ripple 0.3.128 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +267 -0
- package/package.json +10 -4
- package/src/runtime/element.js +23 -6
- package/src/runtime/index-client.js +81 -41
- package/src/runtime/index-server.js +1 -0
- package/src/runtime/internal/client/blocks.js +173 -91
- package/src/runtime/internal/client/component.js +4 -30
- package/src/runtime/internal/client/composite.js +12 -13
- package/src/runtime/internal/client/constants.js +9 -0
- package/src/runtime/internal/client/context.js +12 -19
- package/src/runtime/internal/client/css.js +7 -9
- package/src/runtime/internal/client/events.js +178 -90
- package/src/runtime/internal/client/expression.js +45 -25
- package/src/runtime/internal/client/for.js +409 -129
- package/src/runtime/internal/client/head.js +10 -5
- package/src/runtime/internal/client/html.js +1 -0
- package/src/runtime/internal/client/hydration.js +152 -10
- package/src/runtime/internal/client/if.js +239 -50
- package/src/runtime/internal/client/index.js +4 -12
- package/src/runtime/internal/client/operations.js +40 -61
- package/src/runtime/internal/client/portal.js +163 -85
- package/src/runtime/internal/client/render.js +39 -39
- package/src/runtime/internal/client/rpc.js +3 -3
- package/src/runtime/internal/client/runtime.js +592 -433
- package/src/runtime/internal/client/selector.js +5 -2
- package/src/runtime/internal/client/template.js +133 -158
- package/src/runtime/internal/client/transport.js +38 -0
- package/src/runtime/internal/client/try.js +465 -426
- package/src/runtime/internal/client/types.d.ts +56 -23
- package/src/runtime/internal/client/utils.js +1 -3
- package/src/runtime/internal/server/dynamic.js +20 -21
- package/src/runtime/internal/server/index.js +325 -275
- package/src/runtime/internal/server/rpc.js +3 -2
- package/src/runtime/internal/server/transport.js +16 -0
- package/src/runtime/transport.js +21 -0
- package/tests/client/__snapshots__/for.test.tsrx.snap +0 -5
- package/tests/client/array/array.copy-within.test.tsrx +12 -12
- package/tests/client/array/array.derived.test.tsrx +46 -46
- package/tests/client/array/array.iteration.test.tsrx +10 -10
- package/tests/client/array/array.mutations.test.tsrx +20 -20
- package/tests/client/array/array.static.test.tsrx +11 -11
- package/tests/client/array/array.to-methods.test.tsrx +6 -6
- package/tests/client/async-suspend.test.tsrx +74 -75
- package/tests/client/basic/basic.attributes.test.tsrx +86 -83
- package/tests/client/basic/basic.collections.test.tsrx +12 -12
- package/tests/client/basic/basic.components.test.tsrx +99 -25
- package/tests/client/basic/basic.errors.test.tsrx +18 -18
- package/tests/client/basic/basic.events.test.tsrx +42 -42
- package/tests/client/basic/basic.get-set.test.tsrx +8 -8
- package/tests/client/basic/basic.reactivity.test.tsrx +73 -38
- package/tests/client/basic/basic.rendering.test.tsrx +25 -25
- package/tests/client/basic/basic.utilities.test.tsrx +3 -3
- package/tests/client/boundaries.test.tsrx +8 -8
- package/tests/client/boxed-locals.test.tsrx +452 -0
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +6 -6
- package/tests/client/compiler/compiler.assignments.test.tsrx +9 -73
- package/tests/client/compiler/compiler.attributes.test.tsrx +23 -23
- package/tests/client/compiler/compiler.basic.test.tsrx +15 -60
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +18 -43
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +2 -2
- package/tests/client/composite/__snapshots__/composite.render.test.tsrx.snap +0 -1
- package/tests/client/composite/composite.dynamic-components.test.tsrx +77 -6
- package/tests/client/composite/composite.props.test.tsrx +149 -12
- package/tests/client/composite/composite.reactivity.test.tsrx +51 -52
- package/tests/client/composite/composite.render.test.tsrx +26 -9
- package/tests/client/css/scoped-styles.test.tsrx +8 -8
- package/tests/client/date.test.tsrx +42 -42
- package/tests/client/derived-release.test.tsrx +370 -0
- package/tests/client/dynamic-elements.test.tsrx +45 -45
- package/tests/client/events.test.tsrx +97 -71
- package/tests/client/for-selector.test.tsrx +14 -14
- package/tests/client/for-single-root-items.test.tsrx +118 -3
- package/tests/client/for.test.tsrx +332 -31
- package/tests/client/head.test.tsrx +19 -19
- package/tests/client/html.test.tsrx +11 -9
- package/tests/client/if-block.test.tsrx +80 -0
- package/tests/client/map.test.tsrx +16 -16
- package/tests/client/media-query.test.tsrx +7 -7
- package/tests/client/portal.test.tsrx +224 -26
- package/tests/client/primitive-text.test.tsrx +50 -0
- package/tests/client/prop-kind-switch.test.tsrx +141 -0
- package/tests/client/ref.test.tsrx +17 -17
- package/tests/client/return.test.tsrx +26 -3
- package/tests/client/root-boundary.test.tsrx +42 -0
- package/tests/client/scoped-flush.test.tsrx +8 -8
- package/tests/client/set.test.tsrx +6 -6
- package/tests/client/svg.test.tsrx +11 -11
- package/tests/client/switch.test.tsrx +44 -44
- package/tests/client/track-async-hydration.test.tsrx +4 -4
- package/tests/client/try.test.tsrx +151 -83
- package/tests/client/tsx.test.tsrx +43 -40
- package/tests/client/url/url.derived.test.tsrx +6 -6
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +8 -8
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +10 -10
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +10 -10
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +18 -18
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +2 -2
- package/tests/hydration/basic.test.js +74 -1
- package/tests/hydration/build-components.js +22 -1
- package/tests/hydration/compiled/client/basic.js +1142 -713
- package/tests/hydration/compiled/client/composite.js +151 -100
- package/tests/hydration/compiled/client/events.js +184 -171
- package/tests/hydration/compiled/client/for.js +1472 -1132
- package/tests/hydration/compiled/client/fragment-cursor.js +2341 -0
- package/tests/hydration/compiled/client/head.js +254 -201
- package/tests/hydration/compiled/client/hmr.js +54 -41
- package/tests/hydration/compiled/client/html-in-template.js +54 -39
- package/tests/hydration/compiled/client/html.js +1633 -1263
- package/tests/hydration/compiled/client/if-children.js +420 -270
- package/tests/hydration/compiled/client/if-fragment-controlflow.js +363 -317
- package/tests/hydration/compiled/client/if.js +229 -219
- package/tests/hydration/compiled/client/mixed-control-flow.js +420 -404
- package/tests/hydration/compiled/client/nested-control-flow.js +1326 -1277
- package/tests/hydration/compiled/client/portal.js +87 -95
- package/tests/hydration/compiled/client/reactivity.js +135 -101
- package/tests/hydration/compiled/client/return.js +28 -19
- package/tests/hydration/compiled/client/streaming.js +390 -306
- package/tests/hydration/compiled/client/switch.js +258 -266
- package/tests/hydration/compiled/client/track-async-serialization.js +448 -280
- package/tests/hydration/compiled/client/try.js +173 -129
- package/tests/hydration/compiled/client/typed-text.js +71 -0
- package/tests/hydration/compiled/fixtures/money.js +10 -0
- package/tests/hydration/compiled/server/basic.js +123 -6
- package/tests/hydration/compiled/server/composite.js +16 -30
- package/tests/hydration/compiled/server/events.js +66 -18
- package/tests/hydration/compiled/server/for.js +117 -41
- package/tests/hydration/compiled/server/fragment-cursor.js +1687 -0
- package/tests/hydration/compiled/server/head.js +20 -20
- package/tests/hydration/compiled/server/hmr.js +2 -2
- package/tests/hydration/compiled/server/html.js +70 -238
- package/tests/hydration/compiled/server/if-children.js +107 -15
- package/tests/hydration/compiled/server/if.js +11 -15
- package/tests/hydration/compiled/server/mixed-control-flow.js +8 -8
- package/tests/hydration/compiled/server/portal.js +14 -22
- package/tests/hydration/compiled/server/reactivity.js +14 -14
- package/tests/hydration/compiled/server/streaming.js +19 -19
- package/tests/hydration/compiled/server/switch.js +8 -8
- package/tests/hydration/compiled/server/track-async-serialization.js +150 -23
- package/tests/hydration/compiled/server/try.js +8 -8
- package/tests/hydration/compiled/server/typed-text.js +17 -0
- package/tests/hydration/components/basic.tsrx +44 -8
- package/tests/hydration/components/composite.tsrx +2 -2
- package/tests/hydration/components/events.tsrx +25 -25
- package/tests/hydration/components/for.tsrx +115 -67
- package/tests/hydration/components/fragment-cursor.tsrx +650 -0
- package/tests/hydration/components/head.tsrx +16 -16
- package/tests/hydration/components/hmr.tsrx +2 -2
- package/tests/hydration/components/html.tsrx +7 -7
- package/tests/hydration/components/if-children.tsrx +72 -25
- package/tests/hydration/components/if.tsrx +18 -18
- package/tests/hydration/components/mixed-control-flow.tsrx +11 -11
- package/tests/hydration/components/portal.tsrx +3 -3
- package/tests/hydration/components/reactivity.tsrx +16 -16
- package/tests/hydration/components/streaming.tsrx +20 -20
- package/tests/hydration/components/switch.tsrx +20 -20
- package/tests/hydration/components/text-types.ts +4 -0
- package/tests/hydration/components/track-async-serialization.tsrx +80 -26
- package/tests/hydration/components/try.tsrx +8 -8
- package/tests/hydration/components/typed-text.tsrx +22 -0
- package/tests/hydration/fixtures/money.js +10 -0
- package/tests/hydration/for.test.js +36 -0
- package/tests/hydration/fragment-cursor.test.js +111 -0
- package/tests/hydration/if-children.test.js +24 -0
- package/tests/hydration/streaming.test.js +19 -0
- package/tests/hydration/track-async-serialization.test.js +87 -2
- package/tests/hydration/tsconfig.text-types.json +10 -0
- package/tests/hydration/typed-text.test.js +34 -0
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +42 -42
- package/tests/server/basic.components.test.tsrx +64 -8
- package/tests/server/basic.test.tsrx +34 -32
- package/tests/server/compiler.test.tsrx +1 -70
- package/tests/server/composite.props.test.tsrx +6 -6
- package/tests/server/dynamic-elements.test.tsrx +31 -8
- package/tests/server/for.test.tsrx +94 -0
- package/tests/server/head.test.tsrx +11 -11
- package/tests/server/scoped-styles.test.tsrx +2 -2
- package/tests/server/streaming-ssr.test.tsrx +48 -43
- package/tests/server/track-async-serialization.test.tsrx +204 -21
- package/tests/server/try.test.tsrx +48 -48
- package/tests/types/transport.ts +40 -0
- package/tests/utils/vite-plugin-config.test.js +23 -0
- package/types/index.d.ts +48 -7
- package/types/server.d.ts +3 -0
- package/types/transport.d.ts +15 -0
- package/src/runtime/internal/client/switch.js +0 -113
- package/src/utils/errors.js +0 -13
- package/tests/client/lazy-array.test.tsrx +0 -31
- package/tests/client/lazy-destructuring.test.tsrx +0 -438
- package/tests/client/tracked-index-access.test.tsrx +0 -113
- package/tests/server/lazy-destructuring.test.tsrx +0 -595
- package/tests/server/tracked-index-access.test.tsrx +0 -76
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,272 @@
|
|
|
1
1
|
# ripple
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1472](https://github.com/Ripple-TS/ripple/pull/1472)
|
|
8
|
+
[`5d3e60d`](https://github.com/Ripple-TS/ripple/commit/5d3e60d86129ac20d23c86a923914ee44efea9d1)
|
|
9
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Lazy destructuring is removed
|
|
10
|
+
from the language (tsrx RFC
|
|
11
|
+
[#106](https://github.com/Ripple-TS/ripple/issues/106)). `&[ ... ]` and
|
|
12
|
+
`&{ ... }` are syntax errors now; a tracked value is read and written through
|
|
13
|
+
`.value`, and a `Tracked`, `Derived`, or `WritableDerived` object is passed to a
|
|
14
|
+
child as it is (`<Child {count} />`, or `count={track(() => count.value)}` for a
|
|
15
|
+
read-only view).
|
|
16
|
+
|
|
17
|
+
| Before | After |
|
|
18
|
+
| ---------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
19
|
+
| `let &[count] = track(0); count++; {count}` | `const count = track(0); count.value++; {count.value}` |
|
|
20
|
+
| `let &[count, countT] = track(0); <Child count={countT} />` | `const count = track(0); <Child {count} />` |
|
|
21
|
+
| `let &[double] = track(() => count * 2)` | `const double = track(() => count.value * 2)` |
|
|
22
|
+
| `function Card({ count: &[count] }: { count: Tracked<number> })` | `function Card({ count }: { count: Tracked<number> })` and `count.value` |
|
|
23
|
+
|
|
24
|
+
`Tracked<V>`, `Derived<V>`, and `WritableDerived<V>` are plain `{ value: V }`
|
|
25
|
+
shapes; the `[V, Tracked<V>]` tuple member, the runtime `[0]`/`[1]` accessors,
|
|
26
|
+
and the `lazy_array_*` helpers are gone, and `count[0]` reports the ordinary
|
|
27
|
+
"use `.value`" error. Rest and default patterns lower to native destructuring: a
|
|
28
|
+
keyed `@for` pattern with a rest element or a default is destructured once per
|
|
29
|
+
item change, and a destructuring assignment onto boxed `let`s writes the boxes
|
|
30
|
+
in place; the `fallback`, `exclude_from_object`, and `array_slice` runtime
|
|
31
|
+
helpers are gone. On the server a dynamic tag `<{tag} />` is lowered to
|
|
32
|
+
`_$_.dynamic_element(tag, props)`, with the tag and the element's own props
|
|
33
|
+
passed separately, so the props never carry an `is` entry.
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- [#1458](https://github.com/Ripple-TS/ripple/pull/1458)
|
|
38
|
+
[`bbc1445`](https://github.com/Ripple-TS/ripple/commit/bbc14455485e054c145ebc78f08a771d41ea16f1)
|
|
39
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Lighter list, `@if`, and
|
|
40
|
+
mount output on the client. A controlled `@for` (the sole content of its
|
|
41
|
+
element) appends its items into the parent instead of inserting before an empty
|
|
42
|
+
text anchor, and an `@if` at the root of such an item creates an anchor only
|
|
43
|
+
once it needs a position of its own (a branch swap, or a branch that renders
|
|
44
|
+
nothing), so a keyed list of `@if` items keeps no anchor nodes in the DOM;
|
|
45
|
+
`mount()` likewise renders into the target without an anchor node. An `@if`
|
|
46
|
+
block now renders its branch directly and owns the branch's DOM range, and a
|
|
47
|
+
list keeps its inputs in block state, so every `@if` and `@for` allocates one
|
|
48
|
+
block less and no closures. Text and class updates compare against the last
|
|
49
|
+
value in the render block's state instead of a cache on the DOM node; the
|
|
50
|
+
compiler emits that compared form for single updates as well.
|
|
51
|
+
|
|
52
|
+
A selector key whose subscribers all left stays in the selector's map for reuse
|
|
53
|
+
when the key comes back, and is swept once more than 1024 released keys pile up.
|
|
54
|
+
|
|
55
|
+
- [#1469](https://github.com/Ripple-TS/ripple/pull/1469)
|
|
56
|
+
[`b3a38ce`](https://github.com/Ripple-TS/ripple/commit/b3a38ce0aae66a9dcac0b663c30161eed0d7547a)
|
|
57
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Add custom serialization for
|
|
58
|
+
trackAsync hydration and RPC arguments/results using `transport` handlers in
|
|
59
|
+
ripple.config.ts. Register matching encoders and decoders automatically in
|
|
60
|
+
development and production, and expose `setTransport` for custom integrations.
|
|
61
|
+
Apps without a transport retain the plain JSON hydration fast path. Provide a
|
|
62
|
+
browser entry for config helpers so importing defineConfig does not load the
|
|
63
|
+
Vite plugin's Node.js dependencies during hydration. A configured hydration
|
|
64
|
+
payload embeds devalue's flattened form directly, so the client revives it
|
|
65
|
+
without a second string encoding.
|
|
66
|
+
|
|
67
|
+
- [#1460](https://github.com/Ripple-TS/ripple/pull/1460)
|
|
68
|
+
[`2ef5da5`](https://github.com/Ripple-TS/ripple/commit/2ef5da52b26fc13e11537dd28df0e2b376ca0f52)
|
|
69
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Cheaper element refs,
|
|
70
|
+
effects, and component templates on the client. A `ref` is one effect block
|
|
71
|
+
keyed on its state instead of a render block that re-evaluates the thunk and
|
|
72
|
+
creates a branch and an effect for it, since the ref value is read untracked and
|
|
73
|
+
fixed for the life of the enclosing block. Effects deferred until a component
|
|
74
|
+
has rendered are recorded as flat entries, and an effect's first run skips the
|
|
75
|
+
child and teardown sweep. A tracked value written during a flush keeps its
|
|
76
|
+
previous value for teardowns on itself instead of in a map, and `flushSync`
|
|
77
|
+
releases those values when it finishes (they were only released by the microtask
|
|
78
|
+
flush before).
|
|
79
|
+
|
|
80
|
+
The compiler types the bindings of a destructured pattern
|
|
81
|
+
(`{ item }: { item: Item }` as component props, or `const { item } = props` from
|
|
82
|
+
a typed initializer), so their property reads lower to direct text and attribute
|
|
83
|
+
writes. A component whose body has setup statements beside a single root element
|
|
84
|
+
clones that element instead of a fragment.
|
|
85
|
+
|
|
86
|
+
- [#1470](https://github.com/Ripple-TS/ripple/pull/1470)
|
|
87
|
+
[`0321791`](https://github.com/Ripple-TS/ripple/commit/03217912651e0a49edb8060a92602fd0e0abe193)
|
|
88
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Component props are plain
|
|
89
|
+
objects, evaluated once. A call site such as `<Child a={x} b="y" />` compiles to
|
|
90
|
+
the object literal `{ a: x, b: 'y' }` and passes it to the component as is: no
|
|
91
|
+
getters, no props class, no Proxy for spreads, no `Props` helpers, and no
|
|
92
|
+
`Object.keys`/spread lowering, so props behave like any other object in `.tsrx`
|
|
93
|
+
and `.ts` code alike. A prop expression is evaluated when the component is
|
|
94
|
+
called, so a child that must follow a change now receives a live value
|
|
95
|
+
explicitly: a tracked object (`count={count}`) or a derived
|
|
96
|
+
(`title={track(() => label + count.value)}`), read through `.value`.
|
|
97
|
+
`count={count.value}` passes the current number. `track(fn)` is typed
|
|
98
|
+
`Derived<V>` with a read-only `value`; `track(fn, get, set)` or
|
|
99
|
+
`track(fn, undefined, true)` is a `WritableDerived<V>`, and a write to a
|
|
100
|
+
read-only derived warns in development. A dynamic element
|
|
101
|
+
(`<{tag} class={x} />`) still updates its attributes reactively. `Props.keys`,
|
|
102
|
+
`Props.values`, `Props.entries`, `Props.has`, `Props.spread`, `Props.rest`,
|
|
103
|
+
`Props.ownSymbolKeys` and `Props.ownAllKeys` are removed, as they are plain
|
|
104
|
+
`Object` operations now.
|
|
105
|
+
|
|
106
|
+
- [#1457](https://github.com/Ripple-TS/ripple/pull/1457)
|
|
107
|
+
[`020d269`](https://github.com/Ripple-TS/ripple/commit/020d2699f8e1333367ac9f7abe9247bab55e272d)
|
|
108
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Fix hydration when a fragment
|
|
109
|
+
root or a slot is followed by siblings. The compiler's closing `next(n)` for a
|
|
110
|
+
fragment root now counts from wherever the cursor was last positioned, so a
|
|
111
|
+
trailing element navigated to for an event or attribute, tracked text, a
|
|
112
|
+
control-flow block, a component, or a `{expression}` no longer makes the cursor
|
|
113
|
+
overshoot or fall short of the fragment's last node; a trailing element that was
|
|
114
|
+
descended into is popped back to. Control-flow bodies nested inside an element
|
|
115
|
+
now emit that `next(n)` too. At runtime, a `{expression}` leaves the cursor on
|
|
116
|
+
its own end marker like every other block, and a multi-node branch or `@for`
|
|
117
|
+
item steps to its block's end marker after appending, so the next sibling, item,
|
|
118
|
+
or component adopts the right node.
|
|
119
|
+
|
|
120
|
+
- [#1462](https://github.com/Ripple-TS/ripple/pull/1462)
|
|
121
|
+
[`453bf4b`](https://github.com/Ripple-TS/ripple/commit/453bf4ba8b1b31963df26696545e446ab4b1658e)
|
|
122
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Faster keyed lists and
|
|
123
|
+
lighter component output on the client. A `@for` keyed by the item itself
|
|
124
|
+
(`key item`) keys by identity with no key callback, so a re-run compares the
|
|
125
|
+
item arrays directly and skips the per-item value update; a same-length keyed
|
|
126
|
+
re-run rewrites the list's block array in place instead of allocating a new one,
|
|
127
|
+
with the unchanged prefix and suffix skipped by plain compares. Static child
|
|
128
|
+
components that follow their template siblings append into the parent element
|
|
129
|
+
instead of inserting before a `<!>` placeholder, so a component with trailing
|
|
130
|
+
child components clones fewer nodes and leaves no comment anchors in the DOM.
|
|
131
|
+
The compiler also infers a primitive text type through a call whose callee is
|
|
132
|
+
declared to return one (a binding typed as a function type, an `as` assertion, a
|
|
133
|
+
function with a declared return type, or a method or function-typed property of
|
|
134
|
+
an annotated object), so such text lowers to `set_text` instead of a generic
|
|
135
|
+
expression block.
|
|
136
|
+
|
|
137
|
+
- [#1463](https://github.com/Ripple-TS/ripple/pull/1463)
|
|
138
|
+
[`411809f`](https://github.com/Ripple-TS/ripple/commit/411809fb38f25b259a1078a901839318e4207871)
|
|
139
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Faster cold hydration and
|
|
140
|
+
server rendering. `hydrate()` accepts `rootBoundary: false` like `mount()`,
|
|
141
|
+
stepping over the server's root marker itself instead of rendering under a `try`
|
|
142
|
+
block (a streamed shell whose root suspended still hydrates under the default
|
|
143
|
+
boundary, which alone can adopt and activate its slot). The client runtime
|
|
144
|
+
compiles less on a cold page: the hydration cursor steps live in one module and
|
|
145
|
+
assign the cursor directly, a list's first render never compiles the diff, a
|
|
146
|
+
template's clone path stays out of its hydrating closure, `run_block` keeps
|
|
147
|
+
re-run and teardown handling in separate functions, and the compiler adopts an
|
|
148
|
+
element's lone text child in place (`hydrate_text`) with no `pop()`. A `@for`
|
|
149
|
+
whose `index` nothing reads allocates no tracked index per item. Removing the
|
|
150
|
+
server's inline styles now starts from an animation frame rather than inside
|
|
151
|
+
`mount()`/`hydrate()`.
|
|
152
|
+
|
|
153
|
+
On the server, `render()` joins its buffer tree with a plain walk instead of
|
|
154
|
+
`flat(Infinity).join('')`, `escape()` returns strings without `&`, `<` or `"`
|
|
155
|
+
after a single regex test, and an `Output` allocates its stream, css and
|
|
156
|
+
async-operation collections only for the root or on first use.
|
|
157
|
+
|
|
158
|
+
- [#1453](https://github.com/Ripple-TS/ripple/pull/1453)
|
|
159
|
+
[`82bc9ee`](https://github.com/Ripple-TS/ripple/commit/82bc9ee585c6b273bf69890bc2f230aba922bf19)
|
|
160
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Speed up portals and root
|
|
161
|
+
event delegation. `<Portal>` now lowers to a dedicated `portal()` runtime call,
|
|
162
|
+
portal content appends straight into its target without a placeholder node,
|
|
163
|
+
delegated root listeners are shared per target instead of per portal, event
|
|
164
|
+
registration no longer scans every root target, and `@if` blocks and compiled
|
|
165
|
+
`event()` calls allocate fewer closures. `mount()` accepts `rootBoundary: false`
|
|
166
|
+
to render without the default root try/pending boundary. Cold code paths
|
|
167
|
+
(keyed-list diff, block error handling, effect-phase flushing, hydration
|
|
168
|
+
branches) live in their own functions so a first mount compiles less. A
|
|
169
|
+
component whose root is `@if`, `@for`, `@switch`, or `@try` now re-renders at
|
|
170
|
+
its own position when it is portal content or one of an element's all-component
|
|
171
|
+
children, instead of at the end of the parent; `mount()`/`hydrate()` disposers
|
|
172
|
+
are safe to call more than once.
|
|
173
|
+
|
|
174
|
+
- [#1470](https://github.com/Ripple-TS/ripple/pull/1470)
|
|
175
|
+
[`0321791`](https://github.com/Ripple-TS/ripple/commit/03217912651e0a49edb8060a92602fd0e0abe193)
|
|
176
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Cheaper component
|
|
177
|
+
instantiation and `@if` chains on the client. An `@else if`, and a branch whose
|
|
178
|
+
only statement is another `@if`, fold into the enclosing `@if` block on both the
|
|
179
|
+
client and the server, so a chain costs one block and one hydration boundary. An
|
|
180
|
+
`@if` whose condition reads no tracked state renders its branch directly under
|
|
181
|
+
the enclosing block with no block of its own (a block without dependencies is
|
|
182
|
+
never scheduled, so nothing is lost); a dynamic condition keeps its block and
|
|
183
|
+
adopts the dependencies recorded while it was evaluated. A module-level
|
|
184
|
+
component also carries a direct render entry so `render_component` skips the
|
|
185
|
+
element it would otherwise return. An `@if` condition and its branches compile
|
|
186
|
+
to module-level functions when they capture at most one local (passed through
|
|
187
|
+
the if runtime), a condition returns the branch function to render instead of
|
|
188
|
+
calling a selection callback, and a render block's function is module-level with
|
|
189
|
+
its captured locals carried on the block state, so a component instantiation
|
|
190
|
+
creates no closures for its ifs or its reactive text and attribute updates.
|
|
191
|
+
`Context.get()` walks a chain of the context entries that were set rather than
|
|
192
|
+
every ancestor component. A module-level component's render body is a
|
|
193
|
+
module-level function that receives the props from the element instead of a
|
|
194
|
+
closure created per instantiation, `Context.get()`/`set()` calls on a
|
|
195
|
+
`new Context()` binding skip the `with_scope` wrapper, and `mount()` only
|
|
196
|
+
schedules the SSR style removal when the page has server-rendered inline styles.
|
|
197
|
+
A `@switch` now lowers onto the same runtime as `@if`: its selector returns the
|
|
198
|
+
case to render, so a `@switch` over a value that reads no tracked state renders
|
|
199
|
+
its case with no block, its cases are module-level functions when they capture
|
|
200
|
+
at most one local, and the separate switch runtime is gone. The probe that
|
|
201
|
+
decides whether an `@if` needs a block now renders a static branch itself, one
|
|
202
|
+
runtime call instead of four. A module-level component with a destructuring
|
|
203
|
+
parameter gets the direct render entry as well, and an `@if` or `@switch` is
|
|
204
|
+
hoisted whatever number of locals it captures: several travel as one object
|
|
205
|
+
literal destructured in the hoisted signatures. A binding that hoisted template
|
|
206
|
+
code writes (a `ref={name}` setter, a handler that assigns it) or that is
|
|
207
|
+
reassigned after template code reads it is compiled to a `{ v }` box, so the
|
|
208
|
+
hoisted functions share the variable with the component exactly as a closure
|
|
209
|
+
would: a plain `let`, a name inside a destructuring pattern of any shape, a
|
|
210
|
+
function or catch parameter (reboxed first thing in the body), and a `let`
|
|
211
|
+
written through a destructuring or `for...of` assignment target.
|
|
212
|
+
|
|
213
|
+
- [#1473](https://github.com/Ripple-TS/ripple/pull/1473)
|
|
214
|
+
[`eb638ea`](https://github.com/Ripple-TS/ripple/commit/eb638ea4a3c73b7ecb98ccedfffc576661dc67b3)
|
|
215
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - A derived created during a
|
|
216
|
+
block's run (a `track(() => ...)` or `tracked.readOnly()` in an `@if` branch, a
|
|
217
|
+
keyed `@for` item, a render expression, or component setup) is now unsubscribed
|
|
218
|
+
from its sources when that block reruns or is destroyed, unless a reader that is
|
|
219
|
+
still alive holds it. Before, such deriveds stayed subscribed until the block
|
|
220
|
+
that owned them was destroyed, so a branch that toggled repeatedly accumulated
|
|
221
|
+
one stale derived per toggle, each walked on every write to the source. The
|
|
222
|
+
bookkeeping lives in a side table keyed by the creating block, so blocks that
|
|
223
|
+
create no deriveds pay nothing.
|
|
224
|
+
|
|
225
|
+
- [#1466](https://github.com/Ripple-TS/ripple/pull/1466)
|
|
226
|
+
[`2631804`](https://github.com/Ripple-TS/ripple/commit/2631804cd28980b213643ac4ef5e5bcb814eae57)
|
|
227
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - Faster streaming SSR. A
|
|
228
|
+
resolved `trackAsync` value made of plain data (strings, finite numbers,
|
|
229
|
+
booleans, `null`, arrays and plain objects, each reachable once) now travels in
|
|
230
|
+
its hydration script as raw JSON that `JSON.parse` of the envelope yields
|
|
231
|
+
directly, instead of a devalue-encoded string; values JSON cannot represent
|
|
232
|
+
(`undefined`, `NaN`, `-0`, bigints, Dates, Maps, Sets, shared references,
|
|
233
|
+
cycles) keep the devalue encoding, and the client reads either form. Boundaries
|
|
234
|
+
that settle in the same task (data arriving together, a batch of promises
|
|
235
|
+
resolved by one timer or I/O callback) stream as one chunk, flushed once the
|
|
236
|
+
task's microtasks have drained; closing the stream flushes whatever is still
|
|
237
|
+
queued first. `devalue` is updated to 5.9.2, with the stringify performance
|
|
238
|
+
patch proposed upstream in sveltejs/devalue#190 applied through pnpm's
|
|
239
|
+
`patchedDependencies` until it is released.
|
|
240
|
+
|
|
241
|
+
- [#1472](https://github.com/Ripple-TS/ripple/pull/1472)
|
|
242
|
+
[`5d3e60d`](https://github.com/Ripple-TS/ripple/commit/5d3e60d86129ac20d23c86a923914ee44efea9d1)
|
|
243
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - `tracked.readOnly()` returns
|
|
244
|
+
a read-only view of a `Tracked` or `WritableDerived`: a `Derived<V>` that
|
|
245
|
+
follows the value and rejects writes, for a child, function, or context that
|
|
246
|
+
should only read it. It is equivalent to `track(() => tracked.value)`. On a
|
|
247
|
+
derived that is already read-only, `readOnly()` returns the derived itself.
|
|
248
|
+
|
|
249
|
+
- [#1465](https://github.com/Ripple-TS/ripple/pull/1465)
|
|
250
|
+
[`8ace206`](https://github.com/Ripple-TS/ripple/commit/8ace206bfed2cd80b758e6e72f94084d2ffe1455)
|
|
251
|
+
Thanks [@leonidaz](https://github.com/leonidaz)! - `@try` blocks and the root
|
|
252
|
+
boundary keep their state in one explicit `TryState` object, and the pending,
|
|
253
|
+
catch, request and streaming helpers are module functions that take it. A
|
|
254
|
+
boundary allocates its state and one branch closure instead of a closure per
|
|
255
|
+
helper.
|
|
256
|
+
- Updated dependencies
|
|
257
|
+
[[`bbc1445`](https://github.com/Ripple-TS/ripple/commit/bbc14455485e054c145ebc78f08a771d41ea16f1),
|
|
258
|
+
[`0321791`](https://github.com/Ripple-TS/ripple/commit/03217912651e0a49edb8060a92602fd0e0abe193),
|
|
259
|
+
[`2ef5da5`](https://github.com/Ripple-TS/ripple/commit/2ef5da52b26fc13e11537dd28df0e2b376ca0f52),
|
|
260
|
+
[`0321791`](https://github.com/Ripple-TS/ripple/commit/03217912651e0a49edb8060a92602fd0e0abe193),
|
|
261
|
+
[`020d269`](https://github.com/Ripple-TS/ripple/commit/020d2699f8e1333367ac9f7abe9247bab55e272d),
|
|
262
|
+
[`453bf4b`](https://github.com/Ripple-TS/ripple/commit/453bf4ba8b1b31963df26696545e446ab4b1658e),
|
|
263
|
+
[`411809f`](https://github.com/Ripple-TS/ripple/commit/411809fb38f25b259a1078a901839318e4207871),
|
|
264
|
+
[`82bc9ee`](https://github.com/Ripple-TS/ripple/commit/82bc9ee585c6b273bf69890bc2f230aba922bf19),
|
|
265
|
+
[`69d50d9`](https://github.com/Ripple-TS/ripple/commit/69d50d9849d8484a88d39b2908bb682d27ec7bc9),
|
|
266
|
+
[`0321791`](https://github.com/Ripple-TS/ripple/commit/03217912651e0a49edb8060a92602fd0e0abe193),
|
|
267
|
+
[`5d3e60d`](https://github.com/Ripple-TS/ripple/commit/5d3e60d86129ac20d23c86a923914ee44efea9d1)]:
|
|
268
|
+
- @tsrx/ripple@0.2.0
|
|
269
|
+
|
|
3
270
|
## 0.3.128
|
|
4
271
|
|
|
5
272
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Ripple is an elegant TypeScript UI framework",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.4.0",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"module": "src/runtime/index-client.js",
|
|
9
9
|
"main": "src/runtime/index-client.js",
|
|
@@ -29,6 +29,12 @@
|
|
|
29
29
|
"default": "./src/runtime/index-server.js"
|
|
30
30
|
},
|
|
31
31
|
"./package.json": "./package.json",
|
|
32
|
+
"./transport": {
|
|
33
|
+
"types": "./types/transport.d.ts",
|
|
34
|
+
"worker": "./src/runtime/internal/server/transport.js",
|
|
35
|
+
"browser": "./src/runtime/internal/client/transport.js",
|
|
36
|
+
"default": "./src/runtime/internal/server/transport.js"
|
|
37
|
+
},
|
|
32
38
|
"./server": {
|
|
33
39
|
"types": "./types/server.d.ts",
|
|
34
40
|
"default": "./src/server/index.js"
|
|
@@ -71,10 +77,10 @@
|
|
|
71
77
|
},
|
|
72
78
|
"dependencies": {
|
|
73
79
|
"clsx": "^2.1.1",
|
|
74
|
-
"devalue": "^5.
|
|
80
|
+
"devalue": "^5.9.2",
|
|
75
81
|
"esm-env": "^1.2.2",
|
|
76
|
-
"@tsrx/core": "^0.
|
|
77
|
-
"@tsrx/ripple": "0.
|
|
82
|
+
"@tsrx/core": "^0.2.0",
|
|
83
|
+
"@tsrx/ripple": "0.2.0"
|
|
78
84
|
},
|
|
79
85
|
"devDependencies": {
|
|
80
86
|
"@types/estree": "^1.0.8",
|
package/src/runtime/element.js
CHANGED
|
@@ -1,21 +1,38 @@
|
|
|
1
|
-
const TSRX_ELEMENT = Symbol.for('ripple.element');
|
|
1
|
+
export const TSRX_ELEMENT = Symbol.for('ripple.element');
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @typedef {{
|
|
5
5
|
* render: Function;
|
|
6
|
+
* p: any;
|
|
6
7
|
* [TSRX_ELEMENT]: true;
|
|
7
8
|
* }} TSRXElement
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
/**
|
|
12
|
+
* Elements share one constructor so every instance has the same shape and the
|
|
13
|
+
* marker lives on the prototype instead of being defined per allocation.
|
|
11
14
|
* @param {Function} render
|
|
15
|
+
* @param {any} p
|
|
16
|
+
* @this {TSRXElement}
|
|
17
|
+
*/
|
|
18
|
+
function TSRXElementImpl(render, p) {
|
|
19
|
+
this.render = render;
|
|
20
|
+
this.p = p;
|
|
21
|
+
}
|
|
22
|
+
/** @type {any} */ (TSRXElementImpl.prototype)[TSRX_ELEMENT] = true;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {Function} render `(anchor, block, p) => …`
|
|
26
|
+
* @param {any} [p] a value handed back to `render` as its third argument: a
|
|
27
|
+
* module-level component render function receives the component's props
|
|
28
|
+
* this way instead of closing over them, so instantiating the component
|
|
29
|
+
* allocates no closure
|
|
12
30
|
* @returns {TSRXElement}
|
|
13
31
|
*/
|
|
14
|
-
export function tsrx_element(render) {
|
|
15
|
-
return {
|
|
16
|
-
render,
|
|
17
|
-
|
|
18
|
-
};
|
|
32
|
+
export function tsrx_element(render, p = null) {
|
|
33
|
+
return /** @type {TSRXElement} */ (
|
|
34
|
+
/** @type {unknown} */ (new /** @type {any} */ (TSRXElementImpl)(render, p))
|
|
35
|
+
);
|
|
19
36
|
}
|
|
20
37
|
|
|
21
38
|
/**
|
|
@@ -1,28 +1,24 @@
|
|
|
1
|
-
/** @import { RootBoundaryOptions } from '#client' */
|
|
1
|
+
/** @import { AppendIntoAnchor, RootBoundaryOptions } from '#client' */
|
|
2
2
|
|
|
3
3
|
import { destroy_block, root } from './internal/client/blocks.js';
|
|
4
|
-
import { handle_root_events } from './internal/client/events.js';
|
|
5
|
-
import {
|
|
6
|
-
get_first_child,
|
|
7
|
-
get_next_sibling,
|
|
8
|
-
init_operations,
|
|
9
|
-
} from './internal/client/operations.js';
|
|
4
|
+
import { handle_root_events, release_root_events } from './internal/client/events.js';
|
|
5
|
+
import { init_operations } from './internal/client/operations.js';
|
|
10
6
|
import { render_component } from './internal/client/component.js';
|
|
11
|
-
import { create_anchor } from './internal/client/utils.js';
|
|
12
7
|
import { try_block } from './internal/client/try.js';
|
|
13
|
-
import {
|
|
8
|
+
import { remove_styles } from './internal/client/css.js';
|
|
14
9
|
import { normalize_children } from './element.js';
|
|
15
10
|
import {
|
|
16
|
-
|
|
11
|
+
hydrate_next,
|
|
17
12
|
hydrate_node,
|
|
18
13
|
hydrating,
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
set_hydration,
|
|
15
|
+
track_hash_reference,
|
|
21
16
|
} from './internal/client/hydration.js';
|
|
22
17
|
import { COMMENT_NODE, HYDRATION_START } from '../constants.js';
|
|
23
18
|
|
|
24
19
|
// Re-export JSX runtime functions for jsxImportSource: "ripple"
|
|
25
20
|
export { jsx, jsxs, Fragment } from '../jsx-runtime.js';
|
|
21
|
+
export { set_transport as setTransport } from './internal/client/transport.js';
|
|
26
22
|
export {
|
|
27
23
|
UNINITIALIZED,
|
|
28
24
|
TRACKED_UPDATED,
|
|
@@ -31,7 +27,7 @@ export {
|
|
|
31
27
|
} from './internal/client/constants.js';
|
|
32
28
|
|
|
33
29
|
/**
|
|
34
|
-
* @param {Node} anchor
|
|
30
|
+
* @param {Node | AppendIntoAnchor} anchor
|
|
35
31
|
* @param {(anchor: Node) => void} render_content
|
|
36
32
|
* @param {RootBoundaryOptions | undefined} boundary
|
|
37
33
|
* @returns {void}
|
|
@@ -55,6 +51,7 @@ function render_root_boundary(anchor, render_content, boundary) {
|
|
|
55
51
|
render_component(Pending, pending_anchor, {});
|
|
56
52
|
}
|
|
57
53
|
},
|
|
54
|
+
true,
|
|
58
55
|
);
|
|
59
56
|
}
|
|
60
57
|
|
|
@@ -63,71 +60,104 @@ function render_root_boundary(anchor, render_content, boundary) {
|
|
|
63
60
|
* get, so `mount`/`hydrate` accept a component function as the `children`
|
|
64
61
|
* prop.
|
|
65
62
|
*
|
|
66
|
-
* @param {Record<string, any>
|
|
63
|
+
* @param {Record<string, any>} props
|
|
67
64
|
* @returns {Record<string, any>}
|
|
68
65
|
*/
|
|
69
66
|
function normalize_props(props) {
|
|
70
|
-
|
|
71
|
-
return { ...props, children: normalize_children(props.children) };
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return props || {};
|
|
67
|
+
return { ...props, children: normalize_children(props.children) };
|
|
75
68
|
}
|
|
76
69
|
|
|
77
70
|
/**
|
|
71
|
+
* `rootBoundary` configures the default `try`/`pending`/`catch` boundary the
|
|
72
|
+
* app is rendered under; `false` renders without one. Without a root
|
|
73
|
+
* boundary, `trackAsync()` must sit inside a user `@try` block, and errors
|
|
74
|
+
* that escape one propagate out of the flush.
|
|
78
75
|
* @param {Function} component
|
|
79
|
-
* @param {{ props?: Record<string, any>, target: HTMLElement, rootBoundary?: RootBoundaryOptions }} options
|
|
76
|
+
* @param {{ props?: Record<string, any>, target: HTMLElement, rootBoundary?: RootBoundaryOptions | false }} options
|
|
80
77
|
* @returns {() => void}
|
|
81
78
|
*/
|
|
82
79
|
export function mount(component, options) {
|
|
83
80
|
init_operations();
|
|
84
|
-
|
|
81
|
+
// Only a page with server-rendered inline styles has anything to remove.
|
|
82
|
+
// Requesting a frame otherwise makes the browser attach layout to the
|
|
83
|
+
// mounted tree before the app's next update, which slows a teardown that
|
|
84
|
+
// would have preceded the first paint.
|
|
85
|
+
if (document.querySelector('style[data-ripple-ssr]') !== null) {
|
|
86
|
+
requestAnimationFrame(remove_styles);
|
|
87
|
+
}
|
|
85
88
|
|
|
86
|
-
|
|
89
|
+
let props = options.props ?? {};
|
|
90
|
+
if (props.children != null) {
|
|
91
|
+
props = normalize_props(props);
|
|
92
|
+
}
|
|
87
93
|
const target = options.target;
|
|
88
|
-
const anchor = create_anchor();
|
|
89
94
|
|
|
90
95
|
// Clear target content in case of SSR
|
|
91
96
|
if (target.firstChild) {
|
|
92
97
|
target.textContent = '';
|
|
93
98
|
}
|
|
94
99
|
|
|
95
|
-
target
|
|
100
|
+
// The app appends into the emptied target; a root that keeps inserting
|
|
101
|
+
// relative to its anchor materializes one (see `resolve_anchor`).
|
|
102
|
+
/** @type {AppendIntoAnchor} */
|
|
103
|
+
const anchor = { parent: target, into: true };
|
|
96
104
|
|
|
97
|
-
|
|
105
|
+
/** @type {import('./internal/client/events.js').RootTargetRef | null} */
|
|
106
|
+
let events_ref = handle_root_events(target);
|
|
107
|
+
|
|
108
|
+
const root_boundary = options.rootBoundary;
|
|
98
109
|
|
|
99
110
|
const _root = root(() => {
|
|
111
|
+
if (root_boundary === false) {
|
|
112
|
+
render_component(component, anchor, props);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
100
115
|
render_root_boundary(
|
|
101
116
|
anchor,
|
|
102
117
|
(component_anchor) => {
|
|
103
118
|
render_component(component, component_anchor, props);
|
|
104
119
|
},
|
|
105
|
-
|
|
120
|
+
root_boundary,
|
|
106
121
|
);
|
|
107
122
|
});
|
|
108
123
|
|
|
109
124
|
return () => {
|
|
110
|
-
|
|
125
|
+
// The disposer may be called again (a remount, HMR, a stale reference);
|
|
126
|
+
// only the first call owns the target's delegated-listener ref.
|
|
127
|
+
if (events_ref === null) return;
|
|
128
|
+
release_root_events(events_ref);
|
|
129
|
+
events_ref = null;
|
|
111
130
|
destroy_block(_root);
|
|
112
131
|
};
|
|
113
132
|
}
|
|
114
133
|
|
|
115
134
|
/**
|
|
135
|
+
* `rootBoundary` works as in {@link mount}: the app hydrates under a default
|
|
136
|
+
* `try` boundary, or with `false` directly under the root block. Server output
|
|
137
|
+
* always carries the root boundary markers; without a boundary, `hydrate()`
|
|
138
|
+
* steps over a plain `<!--[-->` itself. A streamed shell whose root suspended
|
|
139
|
+
* starts with a `<!--[?N-->` / `<!--[!N-->` slot instead, and only a boundary
|
|
140
|
+
* can adopt its fallback and activate the chunk, so that shell hydrates under
|
|
141
|
+
* the default boundary regardless.
|
|
116
142
|
* @param {Function} component
|
|
117
|
-
* @param {{ props?: Record<string, any>, target: HTMLElement, rootBoundary?: RootBoundaryOptions }} options
|
|
143
|
+
* @param {{ props?: Record<string, any>, target: HTMLElement, rootBoundary?: RootBoundaryOptions | false }} options
|
|
118
144
|
* @returns {() => void}
|
|
119
145
|
*/
|
|
120
146
|
export function hydrate(component, options) {
|
|
121
147
|
init_operations();
|
|
122
|
-
|
|
148
|
+
requestAnimationFrame(remove_styles);
|
|
123
149
|
|
|
124
|
-
|
|
150
|
+
let props = options.props ?? {};
|
|
151
|
+
if (props.children != null) {
|
|
152
|
+
props = normalize_props(props);
|
|
153
|
+
}
|
|
125
154
|
const target = options.target;
|
|
126
155
|
const was_hydrating = hydrating;
|
|
127
156
|
const previous_hydrate_node = hydrate_node;
|
|
128
|
-
let anchor =
|
|
157
|
+
let anchor = target.firstChild;
|
|
129
158
|
|
|
130
|
-
|
|
159
|
+
/** @type {import('./internal/client/events.js').RootTargetRef | null} */
|
|
160
|
+
let events_ref = handle_root_events(target);
|
|
131
161
|
let _root;
|
|
132
162
|
|
|
133
163
|
try {
|
|
@@ -139,33 +169,43 @@ export function hydrate(component, options) {
|
|
|
139
169
|
// marker instead of a plain `<!--[-->`
|
|
140
170
|
!(/** @type {Comment} */ (anchor).data.startsWith(HYDRATION_START)))
|
|
141
171
|
) {
|
|
142
|
-
anchor =
|
|
172
|
+
anchor = anchor.nextSibling;
|
|
143
173
|
}
|
|
144
174
|
|
|
145
|
-
|
|
146
|
-
|
|
175
|
+
set_hydration(true, /** @type {Comment} */ (anchor));
|
|
176
|
+
|
|
177
|
+
const root_boundary = options.rootBoundary;
|
|
178
|
+
const marker = /** @type {Comment} */ (anchor);
|
|
147
179
|
|
|
148
180
|
_root = root(() => {
|
|
181
|
+
if (root_boundary === false && marker.data === HYDRATION_START) {
|
|
182
|
+
// The root boundary's own hydration walk: consume the `<!--[-->`
|
|
183
|
+
// marker and render against it, as `try_block` does for the root.
|
|
184
|
+
hydrate_next();
|
|
185
|
+
render_component(component, marker, props);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
149
188
|
render_root_boundary(
|
|
150
|
-
|
|
189
|
+
marker,
|
|
151
190
|
(component_anchor) => {
|
|
152
191
|
render_component(component, component_anchor, props);
|
|
153
192
|
},
|
|
154
|
-
|
|
193
|
+
root_boundary === false ? undefined : root_boundary,
|
|
155
194
|
);
|
|
156
195
|
});
|
|
157
196
|
} catch (e) {
|
|
158
197
|
throw e;
|
|
159
198
|
} finally {
|
|
160
|
-
|
|
161
|
-
set_hydrate_node(previous_hydrate_node, true);
|
|
199
|
+
set_hydration(was_hydrating, previous_hydrate_node);
|
|
162
200
|
if (!was_hydrating) {
|
|
163
|
-
|
|
201
|
+
track_hash_reference.clear();
|
|
164
202
|
}
|
|
165
203
|
}
|
|
166
204
|
|
|
167
205
|
return () => {
|
|
168
|
-
|
|
206
|
+
if (events_ref === null) return;
|
|
207
|
+
release_root_events(events_ref);
|
|
208
|
+
events_ref = null;
|
|
169
209
|
destroy_block(_root);
|
|
170
210
|
};
|
|
171
211
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { output_push, noop, tsrx_element } from './internal/server/index.js';
|
|
2
2
|
|
|
3
3
|
export { Fragment } from '../jsx-runtime.js';
|
|
4
|
+
export { set_transport as setTransport } from './internal/server/transport.js';
|
|
4
5
|
export { Context } from './internal/server/context.js';
|
|
5
6
|
export {
|
|
6
7
|
untrack,
|