| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
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> | 8 天前 | |
chore: remove ripple-new (#1308) chore: remove ripple-new (migrated to vyre) ripple-new and its compiler/metaframework now live in the standalone vyre repo, so remove them from this monorepo. Removed: - packages/{ripple-new, tsrx-ripple-new, vite-plugin-new} - playground/{ripple-new, ripple-new-ssr, ripple-new-meta} - website-tsrx-new (a ripple-new-metaframework stress-test copy) - benchmarks/js-framework (ripple-new-only) and the ripple-new target dirs from the news / recursive-context / signal-favoring comparison benches - the ripple-new + tsrx-ripple-new vitest projects and typecheck tsconfigs Cleaned the surviving benches (run.mjs / gen.mjs / READMEs) to drop the ripple-new target and its comparison comments; pruned the dead pnpm-workspace globs and the debug-mode.js references. Also bumps the @typescript/native-preview pin 20260619.1 -> 20260616.1 (the pinned nightly was unpublished from the registry, blocking lockfile regeneration; unrelated to ripple-new but required to reinstall). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 2 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 8 天前 | ||
| 2 个月前 |