Add chat example and fix Solid generator bugs (F-1 through F-7)#99
Merged
Conversation
- Add examples/chat/: realistic multi-channel chat app demonstrating all Solid patterns - Preserve non-build instance methods when lifting StatelessWidget (F-3) - Fix async* Stream query code generation stripping asterisk (B-1) - Fix SignalBuilder over-wrapping non-Widget expressions (B-2) - Apply value-rewriting consistently to user methods on State<X> (F-4) - Update SPEC.md to reflect current plain-class Effect behavior (F-5) - Add AGENTS.md documentation for lifted widget helper methods (F-6)
- Reorder `.environment()` chains so Provider deps are above consumers - Hoist signal reads out of deferred closures to build statement scope - Generator synthesizes outer `SignalBuilder` when reads lack widget anchor - Replace constructor-body signal writes with field initializers - Add SPEC §7.1 documentation for unanchored-read case
- Extract typing indicator to separate component with dedicated lifecycle - Sync typing state with incoming messages (~1.5s before arrival) - Add auto-scroll to bottom with manual scroll detection and FAB - Use broadcast stream controllers for per-channel typing state - Properly dispose stream resources in backend.dispose()
- Added section explaining when dependencies appear first (.environment chains, bottom-up) vs last (MultiProvider, top-down) - Includes worked examples for both forms - Added troubleshooting entry for ProviderNotFoundException with reference to patterns section
- Collection seeding now uses constructor-body writes (re-entrance bug is fixed in 2.7.4) - Remove obsolete SolidEnvironment workaround from troubleshooting docs - Bump flutter_solidart across all examples and integration_tests
- Add troubleshooting entry explaining why reactive reads inside nested callbacks don't subscribe - Improve code comments clarifying the hoisting pattern - Remove verbose comment from chat_shell
- Add untracked<T>(callback) source stub to solid_annotations - Detect verbatim untracked(...) calls and pass through to flutter_solidart - Hide untracked from solid_annotations imports when both packages present - Update spec with rationale: prevents cycles when writing collections in effects - Use in chat example: wrap collection write to break keepChannelRead effect loop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
examples/chat/) — a multi-channel real-time chat with pure in-process mock backend, exercising all major Solid primitives across@SolidStatescalars/collections,@SolidQueryStreams,@SolidEffect, and@SolidEnvironmenton bothState<X>and plain classes@SolidQuerywithasync*body now preserves the asterisk (annotation_reader._bodyKeywordjoinsbody.star)SignalBuilderwrapping now checks static type via resolved AST; non-Widget expressions are rejected, preventing invalid type assignmentsstateless_rewriter._splitMembersnow preserves non-buildinstance methods through the lift and runs value-rewriter over eachstate_class_rewriternow runs value-rewriter over user methods (matchingplain_class_rewriterbehavior), fixing.valuerewrites inside non-annotated methods@SolidEffectare rejected (generator already supports this)dispose()behavior on liftedStatelessWidgetquery_with_cross_class_collection_deplocks in Stream query / cross-class collection semanticsbuilder.dartnow callsbuildStep.resolver.libraryFor+astNodeFor(..., resolve: true), populatingExpression.staticTypedownstream; rewriters consult static type first, fall back to lexeme-based path on unresolved nodesimport '...' as fw; class X extends fw.StatelessWidget {})Testing
examples/chat/:dart run build_runner buildclean,dart format --set-exit-if-changed .passes,dart analyze --fatal-infospassesdart analyze packages/solid_generator/test/golden/outputs/passesdart test packages/solid_generator/— 252 tests passflutter test packages/integration_tests/— 11 tests passquery_stream_async_star,stateless_lift_with_helpers,stateless_lift_with_user_init_state,state_class_user_method_same_class,state_class_user_method_cross_class,state_class_user_method_set_state_closure,query_with_cross_class_collection_depplacement_visitor_test.dartcovers non-Widget rejection path for SignalBuilder wrapping