| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
fix: keep ripple.config.ts out of the client bundle (#1513) * fix: compile nested `module` namespaces instead of a `module server` error (#1505) `module A.B` parses as nested TSModuleDeclarations, and the parser sets `declare` only on the outermost one. The analyzer treated every non-declare `module` declaration as a submodule, so the inner part of `declare module A.B` and a `module` block inside `declare namespace` hit the fatal "`module server` can only be declared at the module level" error, even in loose mode, which discarded the file's Volar output. A submodule is now a `module` declaration outside any `declare` ancestor that is not the inner part of a dotted name. The name check runs before the level check, so the message names what the source wrote. A dotted `module server.api` reports that dotted names are not supported, and the module-level error is collected in loose mode like the others. The client and server transforms share one `is_server_module_declaration` that also requires a top-level declaration with a block body, so the forms the analyzer reports stay namespaces instead of being lowered. References to a `module` binding only count as submodule references when the binding is in the module scope, so `typeof B.x` inside `declare namespace A` no longer reports "Import submodule exports before using them". Fixes #1505 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: keep ripple.config.ts out of the client bundle The generated hydration entry imported the whole config, so anything the config imported (middlewares and their server-only dependencies) was bundled for the browser and could throw before hydration, leaving the page inert. The entry now imports only the modules the config names for the client, and the server sends the matched route's entry and layout in `__ripple_data`. `transport` and `rootBoundary.pending`/`catch` take module references (a root-relative path or an `[exportName, path]` tuple, like a route `entry`). The dev server and the generated production entry load those modules on the server; the dev client entry is regenerated when the config changes. The browser export condition, `config.js`, and the adapter browser stub existed only because the browser imported the config, so they are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> | 17 天前 | |
feat!: remove lazy destructuring (tsrx RFC #106) (#1472) * feat!: remove lazy destructuring (tsrx RFC #106) Follows tsrx PR #110 and closes the Ripple side of #1471. `&[ ... ]` and `&{ ... }` are syntax errors; tracked state is read and written through `.value`, and a Tracked/Derived object is passed to a child as it is. Compiler (@tsrx/ripple): remove the lazy transforms, the [0]/[1] tracked-index errors, and the indexed-read lowering; own `extract_paths` and `DestructuredAssignment`; infer `{ value: T }` for `track()` calls so `count.value` still lowers to typed text; lower server dynamic tags to `_$_.dynamic_element(tag, props)` with the tag and `is`-free props passed separately; guard parameter-provided components with `if (Comp)` on the client, as the server already did. Runtime (ripple): remove `lazy_array_*`, the tuple accessors and iterator on TrackedValue/DerivedValue, `utils/errors.js`, and the `exclude_prop_from_object` import; `Tracked`, `Derived`, and `WritableDerived` are plain `{ value }` shapes. Docs, templates, playground, benchmarks, and all client/server/hydration tests migrated to `.value`; lazy-only tests removed; a syntax-rejection test added. Changesets: @changesets/cli 3.0.3 (peer bumps patch dependents, so a minor on ripple cannot cascade to a major), changesets/action v2 in both workflows (v1 parsed `New tag:` lines the v3 CLI no longer prints), and the policy relaxed to block only `major`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs,test: show a plain Tracked holding a component or function `track(fn)` always creates a derived, so a component or function is held in a plain `Tracked` by creating it empty and assigning `.value`. Client and server tests cover component and function switching that way; the dynamic component guides, playground examples, and llms.txt show the technique in commented code beside the writable-derived form. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: render nothing for a nullish component in render_component An optional component prop, or any component value that is nullish at render time, now renders nothing on both client and server inside `render_component` itself; other non-function values still throw. The compiler guards are gone: the `if (Comp)` the client transform had added for parameter-provided components, and the server transform's pre-existing `if (comp)` around every non-local component call. Adds a compiler test pinning `track<T>()` type-argument inference. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor: lower rest and default patterns with native destructuring The compiler no longer re-implements destructuring by hand, so the `fallback`, `exclude_from_object`, and `array_slice` runtime helpers and the `extract_paths` utility are gone. A keyed `@for` pattern still reads each name off the loop's per-key tracked item on every render, but a name behind a rest element or a default now reads by destructuring the item with the authored pattern (`(({ id, ...rest }) => rest)(item)`), so rest, default, computed-key, and iterable semantics are JavaScript's own; plain property and index chains stay member reads. A destructuring assignment onto boxed `let`s rewrites the boxed targets in place (`({ a: a.v, ...rest.v } = obj)`) instead of expanding the pattern into per-path assignments. Also removes the dead `exclude_key` / `exclude_prop` parameters that ran from `composite` through `render_spread` to `apply_element_spread`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: destructure a keyed @for item once per change A keyed `@for` pattern with a rest element or a default is now destructured once per item change, natively, into a derived object of its names (`fields`) that the body reads through, instead of once per read of each name. Defaults run once and an iterable item is consumed once, as in `const { ... } = item`. The key callback runs outside the item's block, so it reads a plain member chain where the key name has one and destructures the item inline only for a name behind a rest or default. Plain property and index chains still read directly off the item, so the emitted code for identifier and member patterns (every keyed loop in the benchmark apps) is unchanged. `tsrx_for_pattern_fields` is added to `BaseNodeMetaData` by augmenting `@tsrx/core/types` from this package's types. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore: use the released @tsrx packages Replaces the temporary `link:../tsrx/packages/tsrx` override with the versions published from tsrx-org/tsrx#105 (`@tsrx/core` 0.2.0 and the matching tooling and target releases). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf: destructure keyed @for items in the loop runtime, not a derived The keyed loop runtime takes the destructuring function as a trailing `for_keyed` argument (`map_item`) and applies it where it creates and updates the per-key tracked, so the tracked holds the object of pattern names directly. The body reads `_$_.get(pattern).rest` with no extra reactive node; the item state keeps the raw item (`r`) so a reconcile still skips unchanged items. The key callback receives the raw item and reads a member chain, or destructures inline only for a key behind a rest or default. The script-only (template-less) keyed loop reassigns the loop variable to the destructured object at the top of its body. In a 1000-row jsdom micro-benchmark this matches or beats the previous per-read helper calls (rest 1.57 ms vs 1.77 ms per update, default 1.53 vs 1.50 ms); identifier and member-chain patterns are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ripple): tracked.readOnly() read-only view `tracked.readOnly()` returns a `Derived<V>` that follows a `Tracked` or `WritableDerived` and rejects writes, for a child, function, or context that should only read it; it is what `track(() => tracked.value)` builds. A derived without a setter is already read-only and returns itself. The view is a prototype method on both runtime classes, owned by the source's block. The analyzer allows `readOnly` on a known tracked binding and no longer allows `length`, which only existed for the removed tuple shape. Docs, both `llms.txt`, and the README lead with `readOnly()` for read-only passing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ripple): own a readOnly() view by the block that creates it `readOnly()` handed the view to the source's block, so a view made in a component for a value that outlives it (a store, an ancestor) stayed subscribed to the source after the component was destroyed. The view is now owned by the block active when it is created, the same owner a `track(() => tracked.value)` gets, and the server view carries no hash of its own since it is not a serialized value. `mark_subscribers` now marks a derived's own subscribers before deciding whether to prune it, so a derived whose owner is destroyed and whose readers are gone is dropped on the first write to its source instead of the second. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ripple): record the sources behind a hashless derived in trackAsync envelopes A `readOnly()` view has no hydration hash, so a trackAsync that read its source through the view recorded no dependency in its envelope and the client never re-subscribed after hydration: a later write to the source did not refetch. `collect_dep_hashes` now treats a dependency that is a derived without a hash as standing for what it read and records those hashes instead, deduplicated. Tests: the server envelope lists the same dependency whether the value is read directly or through a view; after hydration, a write to a source read through a view reruns the trackAsync. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> | 26 天前 | |
feat!: remove lazy destructuring (tsrx RFC #106) (#1472) * feat!: remove lazy destructuring (tsrx RFC #106) Follows tsrx PR #110 and closes the Ripple side of #1471. `&[ ... ]` and `&{ ... }` are syntax errors; tracked state is read and written through `.value`, and a Tracked/Derived object is passed to a child as it is. Compiler (@tsrx/ripple): remove the lazy transforms, the [0]/[1] tracked-index errors, and the indexed-read lowering; own `extract_paths` and `DestructuredAssignment`; infer `{ value: T }` for `track()` calls so `count.value` still lowers to typed text; lower server dynamic tags to `_$_.dynamic_element(tag, props)` with the tag and `is`-free props passed separately; guard parameter-provided components with `if (Comp)` on the client, as the server already did. Runtime (ripple): remove `lazy_array_*`, the tuple accessors and iterator on TrackedValue/DerivedValue, `utils/errors.js`, and the `exclude_prop_from_object` import; `Tracked`, `Derived`, and `WritableDerived` are plain `{ value }` shapes. Docs, templates, playground, benchmarks, and all client/server/hydration tests migrated to `.value`; lazy-only tests removed; a syntax-rejection test added. Changesets: @changesets/cli 3.0.3 (peer bumps patch dependents, so a minor on ripple cannot cascade to a major), changesets/action v2 in both workflows (v1 parsed `New tag:` lines the v3 CLI no longer prints), and the policy relaxed to block only `major`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs,test: show a plain Tracked holding a component or function `track(fn)` always creates a derived, so a component or function is held in a plain `Tracked` by creating it empty and assigning `.value`. Client and server tests cover component and function switching that way; the dynamic component guides, playground examples, and llms.txt show the technique in commented code beside the writable-derived form. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: render nothing for a nullish component in render_component An optional component prop, or any component value that is nullish at render time, now renders nothing on both client and server inside `render_component` itself; other non-function values still throw. The compiler guards are gone: the `if (Comp)` the client transform had added for parameter-provided components, and the server transform's pre-existing `if (comp)` around every non-local component call. Adds a compiler test pinning `track<T>()` type-argument inference. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor: lower rest and default patterns with native destructuring The compiler no longer re-implements destructuring by hand, so the `fallback`, `exclude_from_object`, and `array_slice` runtime helpers and the `extract_paths` utility are gone. A keyed `@for` pattern still reads each name off the loop's per-key tracked item on every render, but a name behind a rest element or a default now reads by destructuring the item with the authored pattern (`(({ id, ...rest }) => rest)(item)`), so rest, default, computed-key, and iterable semantics are JavaScript's own; plain property and index chains stay member reads. A destructuring assignment onto boxed `let`s rewrites the boxed targets in place (`({ a: a.v, ...rest.v } = obj)`) instead of expanding the pattern into per-path assignments. Also removes the dead `exclude_key` / `exclude_prop` parameters that ran from `composite` through `render_spread` to `apply_element_spread`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: destructure a keyed @for item once per change A keyed `@for` pattern with a rest element or a default is now destructured once per item change, natively, into a derived object of its names (`fields`) that the body reads through, instead of once per read of each name. Defaults run once and an iterable item is consumed once, as in `const { ... } = item`. The key callback runs outside the item's block, so it reads a plain member chain where the key name has one and destructures the item inline only for a name behind a rest or default. Plain property and index chains still read directly off the item, so the emitted code for identifier and member patterns (every keyed loop in the benchmark apps) is unchanged. `tsrx_for_pattern_fields` is added to `BaseNodeMetaData` by augmenting `@tsrx/core/types` from this package's types. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore: use the released @tsrx packages Replaces the temporary `link:../tsrx/packages/tsrx` override with the versions published from tsrx-org/tsrx#105 (`@tsrx/core` 0.2.0 and the matching tooling and target releases). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf: destructure keyed @for items in the loop runtime, not a derived The keyed loop runtime takes the destructuring function as a trailing `for_keyed` argument (`map_item`) and applies it where it creates and updates the per-key tracked, so the tracked holds the object of pattern names directly. The body reads `_$_.get(pattern).rest` with no extra reactive node; the item state keeps the raw item (`r`) so a reconcile still skips unchanged items. The key callback receives the raw item and reads a member chain, or destructures inline only for a key behind a rest or default. The script-only (template-less) keyed loop reassigns the loop variable to the destructured object at the top of its body. In a 1000-row jsdom micro-benchmark this matches or beats the previous per-read helper calls (rest 1.57 ms vs 1.77 ms per update, default 1.53 vs 1.50 ms); identifier and member-chain patterns are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ripple): tracked.readOnly() read-only view `tracked.readOnly()` returns a `Derived<V>` that follows a `Tracked` or `WritableDerived` and rejects writes, for a child, function, or context that should only read it; it is what `track(() => tracked.value)` builds. A derived without a setter is already read-only and returns itself. The view is a prototype method on both runtime classes, owned by the source's block. The analyzer allows `readOnly` on a known tracked binding and no longer allows `length`, which only existed for the removed tuple shape. Docs, both `llms.txt`, and the README lead with `readOnly()` for read-only passing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ripple): own a readOnly() view by the block that creates it `readOnly()` handed the view to the source's block, so a view made in a component for a value that outlives it (a store, an ancestor) stayed subscribed to the source after the component was destroyed. The view is now owned by the block active when it is created, the same owner a `track(() => tracked.value)` gets, and the server view carries no hash of its own since it is not a serialized value. `mark_subscribers` now marks a derived's own subscribers before deciding whether to prune it, so a derived whose owner is destroyed and whose readers are gone is dropped on the first write to its source instead of the second. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ripple): record the sources behind a hashless derived in trackAsync envelopes A `readOnly()` view has no hydration hash, so a trackAsync that read its source through the view recorded no dependency in its envelope and the client never re-subscribed after hydration: a later write to the source did not refetch. `collect_dep_hashes` now treats a dependency that is a derived without a hash as standing for what it read and records those hashes instead, deduplicated. Tests: the server envelope lists the same dependency whether the value is read directly or through a view; after hydration, a write to a source read through a view reruns the trackAsync. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> | 26 天前 | |
feat!: remove lazy destructuring (tsrx RFC #106) (#1472) * feat!: remove lazy destructuring (tsrx RFC #106) Follows tsrx PR #110 and closes the Ripple side of #1471. `&[ ... ]` and `&{ ... }` are syntax errors; tracked state is read and written through `.value`, and a Tracked/Derived object is passed to a child as it is. Compiler (@tsrx/ripple): remove the lazy transforms, the [0]/[1] tracked-index errors, and the indexed-read lowering; own `extract_paths` and `DestructuredAssignment`; infer `{ value: T }` for `track()` calls so `count.value` still lowers to typed text; lower server dynamic tags to `_$_.dynamic_element(tag, props)` with the tag and `is`-free props passed separately; guard parameter-provided components with `if (Comp)` on the client, as the server already did. Runtime (ripple): remove `lazy_array_*`, the tuple accessors and iterator on TrackedValue/DerivedValue, `utils/errors.js`, and the `exclude_prop_from_object` import; `Tracked`, `Derived`, and `WritableDerived` are plain `{ value }` shapes. Docs, templates, playground, benchmarks, and all client/server/hydration tests migrated to `.value`; lazy-only tests removed; a syntax-rejection test added. Changesets: @changesets/cli 3.0.3 (peer bumps patch dependents, so a minor on ripple cannot cascade to a major), changesets/action v2 in both workflows (v1 parsed `New tag:` lines the v3 CLI no longer prints), and the policy relaxed to block only `major`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs,test: show a plain Tracked holding a component or function `track(fn)` always creates a derived, so a component or function is held in a plain `Tracked` by creating it empty and assigning `.value`. Client and server tests cover component and function switching that way; the dynamic component guides, playground examples, and llms.txt show the technique in commented code beside the writable-derived form. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: render nothing for a nullish component in render_component An optional component prop, or any component value that is nullish at render time, now renders nothing on both client and server inside `render_component` itself; other non-function values still throw. The compiler guards are gone: the `if (Comp)` the client transform had added for parameter-provided components, and the server transform's pre-existing `if (comp)` around every non-local component call. Adds a compiler test pinning `track<T>()` type-argument inference. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor: lower rest and default patterns with native destructuring The compiler no longer re-implements destructuring by hand, so the `fallback`, `exclude_from_object`, and `array_slice` runtime helpers and the `extract_paths` utility are gone. A keyed `@for` pattern still reads each name off the loop's per-key tracked item on every render, but a name behind a rest element or a default now reads by destructuring the item with the authored pattern (`(({ id, ...rest }) => rest)(item)`), so rest, default, computed-key, and iterable semantics are JavaScript's own; plain property and index chains stay member reads. A destructuring assignment onto boxed `let`s rewrites the boxed targets in place (`({ a: a.v, ...rest.v } = obj)`) instead of expanding the pattern into per-path assignments. Also removes the dead `exclude_key` / `exclude_prop` parameters that ran from `composite` through `render_spread` to `apply_element_spread`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: destructure a keyed @for item once per change A keyed `@for` pattern with a rest element or a default is now destructured once per item change, natively, into a derived object of its names (`fields`) that the body reads through, instead of once per read of each name. Defaults run once and an iterable item is consumed once, as in `const { ... } = item`. The key callback runs outside the item's block, so it reads a plain member chain where the key name has one and destructures the item inline only for a name behind a rest or default. Plain property and index chains still read directly off the item, so the emitted code for identifier and member patterns (every keyed loop in the benchmark apps) is unchanged. `tsrx_for_pattern_fields` is added to `BaseNodeMetaData` by augmenting `@tsrx/core/types` from this package's types. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore: use the released @tsrx packages Replaces the temporary `link:../tsrx/packages/tsrx` override with the versions published from tsrx-org/tsrx#105 (`@tsrx/core` 0.2.0 and the matching tooling and target releases). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf: destructure keyed @for items in the loop runtime, not a derived The keyed loop runtime takes the destructuring function as a trailing `for_keyed` argument (`map_item`) and applies it where it creates and updates the per-key tracked, so the tracked holds the object of pattern names directly. The body reads `_$_.get(pattern).rest` with no extra reactive node; the item state keeps the raw item (`r`) so a reconcile still skips unchanged items. The key callback receives the raw item and reads a member chain, or destructures inline only for a key behind a rest or default. The script-only (template-less) keyed loop reassigns the loop variable to the destructured object at the top of its body. In a 1000-row jsdom micro-benchmark this matches or beats the previous per-read helper calls (rest 1.57 ms vs 1.77 ms per update, default 1.53 vs 1.50 ms); identifier and member-chain patterns are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ripple): tracked.readOnly() read-only view `tracked.readOnly()` returns a `Derived<V>` that follows a `Tracked` or `WritableDerived` and rejects writes, for a child, function, or context that should only read it; it is what `track(() => tracked.value)` builds. A derived without a setter is already read-only and returns itself. The view is a prototype method on both runtime classes, owned by the source's block. The analyzer allows `readOnly` on a known tracked binding and no longer allows `length`, which only existed for the removed tuple shape. Docs, both `llms.txt`, and the README lead with `readOnly()` for read-only passing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ripple): own a readOnly() view by the block that creates it `readOnly()` handed the view to the source's block, so a view made in a component for a value that outlives it (a store, an ancestor) stayed subscribed to the source after the component was destroyed. The view is now owned by the block active when it is created, the same owner a `track(() => tracked.value)` gets, and the server view carries no hash of its own since it is not a serialized value. `mark_subscribers` now marks a derived's own subscribers before deciding whether to prune it, so a derived whose owner is destroyed and whose readers are gone is dropped on the first write to its source instead of the second. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ripple): record the sources behind a hashless derived in trackAsync envelopes A `readOnly()` view has no hydration hash, so a trackAsync that read its source through the view recorded no dependency in its envelope and the client never re-subscribed after hydration: a later write to the source did not refetch. `collect_dep_hashes` now treats a dependency that is a derived without a hash as standing for what it read and records those hashes instead, deduplicated. Tests: the server envelope lists the same dependency whether the value is read directly or through a view; after hydration, a write to a source read through a view reruns the trackAsync. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> | 26 天前 | |
feat!: remove lazy destructuring (tsrx RFC #106) (#1472) * feat!: remove lazy destructuring (tsrx RFC #106) Follows tsrx PR #110 and closes the Ripple side of #1471. `&[ ... ]` and `&{ ... }` are syntax errors; tracked state is read and written through `.value`, and a Tracked/Derived object is passed to a child as it is. Compiler (@tsrx/ripple): remove the lazy transforms, the [0]/[1] tracked-index errors, and the indexed-read lowering; own `extract_paths` and `DestructuredAssignment`; infer `{ value: T }` for `track()` calls so `count.value` still lowers to typed text; lower server dynamic tags to `_$_.dynamic_element(tag, props)` with the tag and `is`-free props passed separately; guard parameter-provided components with `if (Comp)` on the client, as the server already did. Runtime (ripple): remove `lazy_array_*`, the tuple accessors and iterator on TrackedValue/DerivedValue, `utils/errors.js`, and the `exclude_prop_from_object` import; `Tracked`, `Derived`, and `WritableDerived` are plain `{ value }` shapes. Docs, templates, playground, benchmarks, and all client/server/hydration tests migrated to `.value`; lazy-only tests removed; a syntax-rejection test added. Changesets: @changesets/cli 3.0.3 (peer bumps patch dependents, so a minor on ripple cannot cascade to a major), changesets/action v2 in both workflows (v1 parsed `New tag:` lines the v3 CLI no longer prints), and the policy relaxed to block only `major`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs,test: show a plain Tracked holding a component or function `track(fn)` always creates a derived, so a component or function is held in a plain `Tracked` by creating it empty and assigning `.value`. Client and server tests cover component and function switching that way; the dynamic component guides, playground examples, and llms.txt show the technique in commented code beside the writable-derived form. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: render nothing for a nullish component in render_component An optional component prop, or any component value that is nullish at render time, now renders nothing on both client and server inside `render_component` itself; other non-function values still throw. The compiler guards are gone: the `if (Comp)` the client transform had added for parameter-provided components, and the server transform's pre-existing `if (comp)` around every non-local component call. Adds a compiler test pinning `track<T>()` type-argument inference. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor: lower rest and default patterns with native destructuring The compiler no longer re-implements destructuring by hand, so the `fallback`, `exclude_from_object`, and `array_slice` runtime helpers and the `extract_paths` utility are gone. A keyed `@for` pattern still reads each name off the loop's per-key tracked item on every render, but a name behind a rest element or a default now reads by destructuring the item with the authored pattern (`(({ id, ...rest }) => rest)(item)`), so rest, default, computed-key, and iterable semantics are JavaScript's own; plain property and index chains stay member reads. A destructuring assignment onto boxed `let`s rewrites the boxed targets in place (`({ a: a.v, ...rest.v } = obj)`) instead of expanding the pattern into per-path assignments. Also removes the dead `exclude_key` / `exclude_prop` parameters that ran from `composite` through `render_spread` to `apply_element_spread`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix: destructure a keyed @for item once per change A keyed `@for` pattern with a rest element or a default is now destructured once per item change, natively, into a derived object of its names (`fields`) that the body reads through, instead of once per read of each name. Defaults run once and an iterable item is consumed once, as in `const { ... } = item`. The key callback runs outside the item's block, so it reads a plain member chain where the key name has one and destructures the item inline only for a name behind a rest or default. Plain property and index chains still read directly off the item, so the emitted code for identifier and member patterns (every keyed loop in the benchmark apps) is unchanged. `tsrx_for_pattern_fields` is added to `BaseNodeMetaData` by augmenting `@tsrx/core/types` from this package's types. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore: use the released @tsrx packages Replaces the temporary `link:../tsrx/packages/tsrx` override with the versions published from tsrx-org/tsrx#105 (`@tsrx/core` 0.2.0 and the matching tooling and target releases). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf: destructure keyed @for items in the loop runtime, not a derived The keyed loop runtime takes the destructuring function as a trailing `for_keyed` argument (`map_item`) and applies it where it creates and updates the per-key tracked, so the tracked holds the object of pattern names directly. The body reads `_$_.get(pattern).rest` with no extra reactive node; the item state keeps the raw item (`r`) so a reconcile still skips unchanged items. The key callback receives the raw item and reads a member chain, or destructures inline only for a key behind a rest or default. The script-only (template-less) keyed loop reassigns the loop variable to the destructured object at the top of its body. In a 1000-row jsdom micro-benchmark this matches or beats the previous per-read helper calls (rest 1.57 ms vs 1.77 ms per update, default 1.53 vs 1.50 ms); identifier and member-chain patterns are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ripple): tracked.readOnly() read-only view `tracked.readOnly()` returns a `Derived<V>` that follows a `Tracked` or `WritableDerived` and rejects writes, for a child, function, or context that should only read it; it is what `track(() => tracked.value)` builds. A derived without a setter is already read-only and returns itself. The view is a prototype method on both runtime classes, owned by the source's block. The analyzer allows `readOnly` on a known tracked binding and no longer allows `length`, which only existed for the removed tuple shape. Docs, both `llms.txt`, and the README lead with `readOnly()` for read-only passing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ripple): own a readOnly() view by the block that creates it `readOnly()` handed the view to the source's block, so a view made in a component for a value that outlives it (a store, an ancestor) stayed subscribed to the source after the component was destroyed. The view is now owned by the block active when it is created, the same owner a `track(() => tracked.value)` gets, and the server view carries no hash of its own since it is not a serialized value. `mark_subscribers` now marks a derived's own subscribers before deciding whether to prune it, so a derived whose owner is destroyed and whose readers are gone is dropped on the first write to its source instead of the second. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ripple): record the sources behind a hashless derived in trackAsync envelopes A `readOnly()` view has no hydration hash, so a trackAsync that read its source through the view recorded no dependency in its envelope and the client never re-subscribed after hydration: a later write to the source did not refetch. `collect_dep_hashes` now treats a dependency that is a derived without a hash as standing for what it read and records those hashes instead, deduplicated. Tests: the server envelope lists the same dependency whether the value is read directly or through a view; after hydration, a write to a source read through a view reruns the trackAsync. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> | 26 天前 | |
docs: fix typos and broken links (#1345) * docs: fix typos, outdated links, and format references in documentation * chore: align package.json metadata, keywords, repository directories, and create-ripple docs * fix(tsrx): replace compiler placeholder error and modernize React playground documentation * style: format good-first-pr-candidates.md with prettier * fix(tsrx): resolve typecheck failure in client transform error handler * style: format client transform index.js with prettier --------- Co-authored-by: kriday <kriday@localhost> | 2 个月前 | |
feat(ripple): infer primitive text with optional TypeScript proofs (#1461) * feat(ripple): infer primitive text with optional TypeScript proofs * peer from pnpm-workspace * fix(ripple): normalize parenthesized text proof ranges * fix(ripple): allow newer TypeScript versions in peer catalog * ts peer to >=5.9.3 * revert to var | 1 个月前 | |
New TSRX design (#1199) * parser changes * tuning * grammar * more changes for treesitter etc * fix * fix tests * more tests * fixes * more tweaks * more fixes * more fixes * fixes * fixing the site * more fixes * improvements * more improvements * more fixes * fixes * fixes * one more * blog * more test fixes * grrammar * more tests * more fixes + clean up blog post * more tests * cleanup solid * fixes * more fixes * more fixes * more fixes * more fixes * fixes * more fixes * jsx control flow language * fix grammar * fix closing tag parsing * more fixes * fix TS issue in parser * fix blog * fix other parser tests * fix new-website * some more * more fixes * regex parsing * add more parser tests * validation fix * add a failing test for now * ooops * lol, actual failing test with nested funcs * allow tsrx at any level * tsrx in expressions, convert more solid tests * fix solid try/pending/catch with brackets, add 2 more failing for future fix * convert solid interleaved test to string check * fix @if...else if chains: read token after else as header, not raw text The token after `else` was tokenized in template-output mode, so an `else if` chain swallowed `if (...)` as JSXText instead of recognizing the `if` keyword. Read it keyword-aware in #parseTemplateIfStatement so the chain recurses correctly. No transformer changes needed — they already recurse the nested IfStatement. * fix escaped backtick with markup should strings * fix parsing fence transition * type * fixes * more parser fixes * more fixes * style parse fix * more fixes * parser fix * more fixes * more * fix website example * better fix * another * fixes * add more parser tests * fix prettier cases * fix react tests * more fixes * fix * fixes * new design * update website * more website * more tweaks * rules * llms * old website * fixes * fix textmate - new design * fix blog * update spec * more fixes * updates * adjustment * readme * llms * improvements * spec * better site * website * website * fixes * parser, parser tests, pretter converted + recovered and converted * update some tests * more fixes * more fixes * more fixes * more fixes * more parser tests, allow code only @ control flows * allow @{} siblings * composite * css tests * more fixes * parse @{} always but error on one child violation * make single child errors more visible, whole node vs start * one more * fix more tests * more fixes * more fixes * token error * code only @{} blocks * fix hydration * tsrx website * more fixes * old website * new website * tree sitter stuff * more fixes * Fix plain if/continue/break/return/throw in template directive bodies being highlighted as JSX text Add tsrx-template-setup-statement rule to tsrx-template-children that matches plain JavaScript setup statements (if, continue, break, return, throw) inside directive bodies and parses them as embedded JavaScript via component-statements. The new rule is placed before jsx-text in the pattern list so it takes priority, preventing these valid setup statements from being incorrectly styled as JSX text. * mcp server fixes * eslint + tsrx website * fix(tree-sitter): prevent jsx_text from swallowing control flow keywords Fix two bugs in the Tree-sitter grammar: 1. Switch cases swallowed as text: The jsx_text scanner consumed 'case' and 'default' keywords as text content, preventing subsequent switch arms from being parsed as separate jsx_switch_case nodes. 2. @if else branch parses separately: The jsx_text scanner consumed 'else', 'pending', 'catch', and 'finally' keywords as text, preventing them from being matched as continuation clauses of @if and @try expressions. Scanner fix: Add boundary keyword detection in scan_jsx_text that stops text tokenization when encountering these keywords (only when preceded by whitespace and followed by expected syntax patterns). Grammar fix: Change jsx_if_expression and jsx_try_expression from prec(1) to prec.right(1) to prefer shifting continuation keywords over reducing the expression early. * update solid tests * preact tests * vue tests * more fixes * textmate * fixes * react tests * fixes * more fixes * more fixes * parser fix * more fixes * solid * mfixes * fix solid dynamic el * fixe * fixes * more fixes * fixes * fix code block * more fixes * Fix braceless if losing JSX highlighting in component contexts Add component-if-statement rule that mirrors if-statement but uses #component-statements (which includes #jsx) instead of #statements for the body. Include it in component-statements before control-statement so it takes priority in component/template contexts. * react fixes * formatting and fixes * fixes * grammar * grammar * better parser support, more tests * lint * fix white space handling in jsx text children * better fix * parse as statement after jsx and if fails, friendly message * parse location * better diagnostic mapping when no exact token exists * fix llms.txt * update tsgo, fixes * update docs * more cleanup + removal of break in @swtich * more @switch changes * no return in @break * more constraints around @for, @if, @try etc * fix parser * allow semi not to crash transformers * add @for empty logic * docs * more fixes * update acorn * changes to syntax * remove ignored packages from changeset * update @catch and @format * format * fixes * fix ripple style intellisense * fix code snippets * tweaks --------- Co-authored-by: Leonidas <329182+leonidaz@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: cursor[bot] <206951365+cursor[bot]@users.noreply.github.com> | 4 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 17 天前 | ||
| 26 天前 | ||
| 26 天前 | ||
| 26 天前 | ||
| 26 天前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 4 个月前 |