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.
Files changed (192) hide show
  1. package/CHANGELOG.md +267 -0
  2. package/package.json +10 -4
  3. package/src/runtime/element.js +23 -6
  4. package/src/runtime/index-client.js +81 -41
  5. package/src/runtime/index-server.js +1 -0
  6. package/src/runtime/internal/client/blocks.js +173 -91
  7. package/src/runtime/internal/client/component.js +4 -30
  8. package/src/runtime/internal/client/composite.js +12 -13
  9. package/src/runtime/internal/client/constants.js +9 -0
  10. package/src/runtime/internal/client/context.js +12 -19
  11. package/src/runtime/internal/client/css.js +7 -9
  12. package/src/runtime/internal/client/events.js +178 -90
  13. package/src/runtime/internal/client/expression.js +45 -25
  14. package/src/runtime/internal/client/for.js +409 -129
  15. package/src/runtime/internal/client/head.js +10 -5
  16. package/src/runtime/internal/client/html.js +1 -0
  17. package/src/runtime/internal/client/hydration.js +152 -10
  18. package/src/runtime/internal/client/if.js +239 -50
  19. package/src/runtime/internal/client/index.js +4 -12
  20. package/src/runtime/internal/client/operations.js +40 -61
  21. package/src/runtime/internal/client/portal.js +163 -85
  22. package/src/runtime/internal/client/render.js +39 -39
  23. package/src/runtime/internal/client/rpc.js +3 -3
  24. package/src/runtime/internal/client/runtime.js +592 -433
  25. package/src/runtime/internal/client/selector.js +5 -2
  26. package/src/runtime/internal/client/template.js +133 -158
  27. package/src/runtime/internal/client/transport.js +38 -0
  28. package/src/runtime/internal/client/try.js +465 -426
  29. package/src/runtime/internal/client/types.d.ts +56 -23
  30. package/src/runtime/internal/client/utils.js +1 -3
  31. package/src/runtime/internal/server/dynamic.js +20 -21
  32. package/src/runtime/internal/server/index.js +325 -275
  33. package/src/runtime/internal/server/rpc.js +3 -2
  34. package/src/runtime/internal/server/transport.js +16 -0
  35. package/src/runtime/transport.js +21 -0
  36. package/tests/client/__snapshots__/for.test.tsrx.snap +0 -5
  37. package/tests/client/array/array.copy-within.test.tsrx +12 -12
  38. package/tests/client/array/array.derived.test.tsrx +46 -46
  39. package/tests/client/array/array.iteration.test.tsrx +10 -10
  40. package/tests/client/array/array.mutations.test.tsrx +20 -20
  41. package/tests/client/array/array.static.test.tsrx +11 -11
  42. package/tests/client/array/array.to-methods.test.tsrx +6 -6
  43. package/tests/client/async-suspend.test.tsrx +74 -75
  44. package/tests/client/basic/basic.attributes.test.tsrx +86 -83
  45. package/tests/client/basic/basic.collections.test.tsrx +12 -12
  46. package/tests/client/basic/basic.components.test.tsrx +99 -25
  47. package/tests/client/basic/basic.errors.test.tsrx +18 -18
  48. package/tests/client/basic/basic.events.test.tsrx +42 -42
  49. package/tests/client/basic/basic.get-set.test.tsrx +8 -8
  50. package/tests/client/basic/basic.reactivity.test.tsrx +73 -38
  51. package/tests/client/basic/basic.rendering.test.tsrx +25 -25
  52. package/tests/client/basic/basic.utilities.test.tsrx +3 -3
  53. package/tests/client/boundaries.test.tsrx +8 -8
  54. package/tests/client/boxed-locals.test.tsrx +452 -0
  55. package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +6 -6
  56. package/tests/client/compiler/compiler.assignments.test.tsrx +9 -73
  57. package/tests/client/compiler/compiler.attributes.test.tsrx +23 -23
  58. package/tests/client/compiler/compiler.basic.test.tsrx +15 -60
  59. package/tests/client/compiler/compiler.tracked-access.test.tsrx +18 -43
  60. package/tests/client/compiler/compiler.try-in-function.test.tsrx +2 -2
  61. package/tests/client/composite/__snapshots__/composite.render.test.tsrx.snap +0 -1
  62. package/tests/client/composite/composite.dynamic-components.test.tsrx +77 -6
  63. package/tests/client/composite/composite.props.test.tsrx +149 -12
  64. package/tests/client/composite/composite.reactivity.test.tsrx +51 -52
  65. package/tests/client/composite/composite.render.test.tsrx +26 -9
  66. package/tests/client/css/scoped-styles.test.tsrx +8 -8
  67. package/tests/client/date.test.tsrx +42 -42
  68. package/tests/client/derived-release.test.tsrx +370 -0
  69. package/tests/client/dynamic-elements.test.tsrx +45 -45
  70. package/tests/client/events.test.tsrx +97 -71
  71. package/tests/client/for-selector.test.tsrx +14 -14
  72. package/tests/client/for-single-root-items.test.tsrx +118 -3
  73. package/tests/client/for.test.tsrx +332 -31
  74. package/tests/client/head.test.tsrx +19 -19
  75. package/tests/client/html.test.tsrx +11 -9
  76. package/tests/client/if-block.test.tsrx +80 -0
  77. package/tests/client/map.test.tsrx +16 -16
  78. package/tests/client/media-query.test.tsrx +7 -7
  79. package/tests/client/portal.test.tsrx +224 -26
  80. package/tests/client/primitive-text.test.tsrx +50 -0
  81. package/tests/client/prop-kind-switch.test.tsrx +141 -0
  82. package/tests/client/ref.test.tsrx +17 -17
  83. package/tests/client/return.test.tsrx +26 -3
  84. package/tests/client/root-boundary.test.tsrx +42 -0
  85. package/tests/client/scoped-flush.test.tsrx +8 -8
  86. package/tests/client/set.test.tsrx +6 -6
  87. package/tests/client/svg.test.tsrx +11 -11
  88. package/tests/client/switch.test.tsrx +44 -44
  89. package/tests/client/track-async-hydration.test.tsrx +4 -4
  90. package/tests/client/try.test.tsrx +151 -83
  91. package/tests/client/tsx.test.tsrx +43 -40
  92. package/tests/client/url/url.derived.test.tsrx +6 -6
  93. package/tests/client/url-search-params/url-search-params.derived.test.tsrx +8 -8
  94. package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +10 -10
  95. package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +10 -10
  96. package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +18 -18
  97. package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +2 -2
  98. package/tests/hydration/basic.test.js +74 -1
  99. package/tests/hydration/build-components.js +22 -1
  100. package/tests/hydration/compiled/client/basic.js +1142 -713
  101. package/tests/hydration/compiled/client/composite.js +151 -100
  102. package/tests/hydration/compiled/client/events.js +184 -171
  103. package/tests/hydration/compiled/client/for.js +1472 -1132
  104. package/tests/hydration/compiled/client/fragment-cursor.js +2341 -0
  105. package/tests/hydration/compiled/client/head.js +254 -201
  106. package/tests/hydration/compiled/client/hmr.js +54 -41
  107. package/tests/hydration/compiled/client/html-in-template.js +54 -39
  108. package/tests/hydration/compiled/client/html.js +1633 -1263
  109. package/tests/hydration/compiled/client/if-children.js +420 -270
  110. package/tests/hydration/compiled/client/if-fragment-controlflow.js +363 -317
  111. package/tests/hydration/compiled/client/if.js +229 -219
  112. package/tests/hydration/compiled/client/mixed-control-flow.js +420 -404
  113. package/tests/hydration/compiled/client/nested-control-flow.js +1326 -1277
  114. package/tests/hydration/compiled/client/portal.js +87 -95
  115. package/tests/hydration/compiled/client/reactivity.js +135 -101
  116. package/tests/hydration/compiled/client/return.js +28 -19
  117. package/tests/hydration/compiled/client/streaming.js +390 -306
  118. package/tests/hydration/compiled/client/switch.js +258 -266
  119. package/tests/hydration/compiled/client/track-async-serialization.js +448 -280
  120. package/tests/hydration/compiled/client/try.js +173 -129
  121. package/tests/hydration/compiled/client/typed-text.js +71 -0
  122. package/tests/hydration/compiled/fixtures/money.js +10 -0
  123. package/tests/hydration/compiled/server/basic.js +123 -6
  124. package/tests/hydration/compiled/server/composite.js +16 -30
  125. package/tests/hydration/compiled/server/events.js +66 -18
  126. package/tests/hydration/compiled/server/for.js +117 -41
  127. package/tests/hydration/compiled/server/fragment-cursor.js +1687 -0
  128. package/tests/hydration/compiled/server/head.js +20 -20
  129. package/tests/hydration/compiled/server/hmr.js +2 -2
  130. package/tests/hydration/compiled/server/html.js +70 -238
  131. package/tests/hydration/compiled/server/if-children.js +107 -15
  132. package/tests/hydration/compiled/server/if.js +11 -15
  133. package/tests/hydration/compiled/server/mixed-control-flow.js +8 -8
  134. package/tests/hydration/compiled/server/portal.js +14 -22
  135. package/tests/hydration/compiled/server/reactivity.js +14 -14
  136. package/tests/hydration/compiled/server/streaming.js +19 -19
  137. package/tests/hydration/compiled/server/switch.js +8 -8
  138. package/tests/hydration/compiled/server/track-async-serialization.js +150 -23
  139. package/tests/hydration/compiled/server/try.js +8 -8
  140. package/tests/hydration/compiled/server/typed-text.js +17 -0
  141. package/tests/hydration/components/basic.tsrx +44 -8
  142. package/tests/hydration/components/composite.tsrx +2 -2
  143. package/tests/hydration/components/events.tsrx +25 -25
  144. package/tests/hydration/components/for.tsrx +115 -67
  145. package/tests/hydration/components/fragment-cursor.tsrx +650 -0
  146. package/tests/hydration/components/head.tsrx +16 -16
  147. package/tests/hydration/components/hmr.tsrx +2 -2
  148. package/tests/hydration/components/html.tsrx +7 -7
  149. package/tests/hydration/components/if-children.tsrx +72 -25
  150. package/tests/hydration/components/if.tsrx +18 -18
  151. package/tests/hydration/components/mixed-control-flow.tsrx +11 -11
  152. package/tests/hydration/components/portal.tsrx +3 -3
  153. package/tests/hydration/components/reactivity.tsrx +16 -16
  154. package/tests/hydration/components/streaming.tsrx +20 -20
  155. package/tests/hydration/components/switch.tsrx +20 -20
  156. package/tests/hydration/components/text-types.ts +4 -0
  157. package/tests/hydration/components/track-async-serialization.tsrx +80 -26
  158. package/tests/hydration/components/try.tsrx +8 -8
  159. package/tests/hydration/components/typed-text.tsrx +22 -0
  160. package/tests/hydration/fixtures/money.js +10 -0
  161. package/tests/hydration/for.test.js +36 -0
  162. package/tests/hydration/fragment-cursor.test.js +111 -0
  163. package/tests/hydration/if-children.test.js +24 -0
  164. package/tests/hydration/streaming.test.js +19 -0
  165. package/tests/hydration/track-async-serialization.test.js +87 -2
  166. package/tests/hydration/tsconfig.text-types.json +10 -0
  167. package/tests/hydration/typed-text.test.js +34 -0
  168. package/tests/server/await.test.tsrx +3 -3
  169. package/tests/server/basic.attributes.test.tsrx +42 -42
  170. package/tests/server/basic.components.test.tsrx +64 -8
  171. package/tests/server/basic.test.tsrx +34 -32
  172. package/tests/server/compiler.test.tsrx +1 -70
  173. package/tests/server/composite.props.test.tsrx +6 -6
  174. package/tests/server/dynamic-elements.test.tsrx +31 -8
  175. package/tests/server/for.test.tsrx +94 -0
  176. package/tests/server/head.test.tsrx +11 -11
  177. package/tests/server/scoped-styles.test.tsrx +2 -2
  178. package/tests/server/streaming-ssr.test.tsrx +48 -43
  179. package/tests/server/track-async-serialization.test.tsrx +204 -21
  180. package/tests/server/try.test.tsrx +48 -48
  181. package/tests/types/transport.ts +40 -0
  182. package/tests/utils/vite-plugin-config.test.js +23 -0
  183. package/types/index.d.ts +48 -7
  184. package/types/server.d.ts +3 -0
  185. package/types/transport.d.ts +15 -0
  186. package/src/runtime/internal/client/switch.js +0 -113
  187. package/src/utils/errors.js +0 -13
  188. package/tests/client/lazy-array.test.tsrx +0 -31
  189. package/tests/client/lazy-destructuring.test.tsrx +0 -438
  190. package/tests/client/tracked-index-access.test.tsrx +0 -113
  191. package/tests/server/lazy-destructuring.test.tsrx +0 -595
  192. package/tests/server/tracked-index-access.test.tsrx +0 -76
@@ -2,7 +2,8 @@
2
2
 
3
3
  import { render } from './blocks.js';
4
4
  import { UNINITIALIZED } from './constants.js';
5
- import { get_tracked, selector_tracked, set } from './runtime.js';
5
+ import { get_tracked, revive_selector_key, selector_tracked, set } from './runtime.js';
6
+ import { RELEASED } from './constants.js';
6
7
 
7
8
  /**
8
9
  * @typedef {{ v: any; m: Map<any, Tracked>; b: Block; a: import('./runtime.js').SelectorAccessors }} Selector
@@ -24,7 +25,7 @@ export function selector(get_source) {
24
25
  v: UNINITIALIZED,
25
26
  m,
26
27
  b: /** @type {Block} */ (/** @type {unknown} */ (null)),
27
- a: { get: undefined, set: undefined, m },
28
+ a: { get: undefined, set: undefined, m, n: 0 },
28
29
  };
29
30
 
30
31
  s.b = render(() => {
@@ -69,6 +70,8 @@ export function selector_match(s, key) {
69
70
  if (match === undefined) {
70
71
  match = selector_tracked(key === s.v, s.b, s.a, key);
71
72
  m.set(key, match);
73
+ } else if ((match.f & RELEASED) !== 0) {
74
+ revive_selector_key(match);
72
75
  }
73
76
  return get_tracked(match);
74
77
  }
@@ -1,15 +1,12 @@
1
1
  /** @import { AppendIntoAnchor, Block } from '#client' */
2
2
 
3
3
  import {
4
- COMMENT_NODE,
5
- HYDRATION_END,
6
- HYDRATION_START,
7
4
  TEMPLATE_FRAGMENT,
8
5
  TEMPLATE_USE_IMPORT_NODE,
9
6
  TEMPLATE_SVG_NAMESPACE,
10
7
  TEMPLATE_MATHML_NAMESPACE,
11
8
  } from '../../../constants.js';
12
- import { hydrate_advance, hydrate_node, hydrating, pop } from './hydration.js';
9
+ import { hydrate_append, hydrate_node, hydrating } from './hydration.js';
13
10
  import { create_text, get_first_child, get_next_sibling, is_firefox } from './operations.js';
14
11
  import { active_block, active_namespace } from './runtime.js';
15
12
 
@@ -56,189 +53,167 @@ export function create_fragment_from_html(
56
53
  }
57
54
 
58
55
  /**
59
- * Creates a template node or fragment from content and flags.
60
- * @param {string} content - The template content.
61
- * @param {number} flags - Flags for template type.
62
- * @param {number} [count] - Pre-calculated count of top-level nodes (for fragments). When provided, avoids runtime parsing.
63
- * @returns {() => Node}
56
+ * The hydration path of a {@link template} instance: adopts the server node(s)
57
+ * at the cursor instead of cloning. Kept out of the clone path so a client-only
58
+ * mount never compiles it.
59
+ * @param {boolean} is_fragment
60
+ * @param {number} count
61
+ * @returns {Node}
64
62
  */
65
- export function template(content, flags, count = 1) {
66
- var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0;
67
- var use_import_node = (flags & TEMPLATE_USE_IMPORT_NODE) !== 0;
68
- var use_svg_namespace = (flags & TEMPLATE_SVG_NAMESPACE) !== 0;
69
- var use_mathml_namespace = (flags & TEMPLATE_MATHML_NAMESPACE) !== 0;
70
- /** @type {Node | DocumentFragment | undefined} */
71
- var node;
72
- var node_svg = false;
73
- var node_mathml = false;
74
- var is_comment = content === '<!>';
75
- var has_start = !is_comment && !content.startsWith('<!>');
63
+ function hydrate_template(is_fragment, count) {
64
+ var node = /** @type {Node} */ (hydrate_node);
65
+ var end = is_fragment ? hydrate_fragment_end(node, count) : node;
66
+ // assign_nodes, inline: the per-node hydration path stays free of helpers.
67
+ var block = /** @type {Block} */ (active_block);
68
+ var s = block.s;
69
+ if (s === null) {
70
+ block.s = { start: node, end };
71
+ } else if (s.start === null) {
72
+ s.start = node;
73
+ s.end = end;
74
+ }
75
+ return node;
76
+ }
76
77
 
77
- return () => {
78
- if (hydrating) {
79
- if (is_fragment) {
80
- var start = /** @type {Node} */ (hydrate_node);
81
- var end = start;
78
+ /**
79
+ * The last top-level node of a hydrated fragment template. Walks using the
80
+ * compiler-provided hop count so hydration never parses template HTML.
81
+ * @param {Node} start
82
+ * @param {number} count
83
+ * @returns {Node}
84
+ */
85
+ function hydrate_fragment_end(start, count) {
86
+ var end = start;
82
87
 
83
- // Walk using compiler-provided hop count so hydration never
84
- // parses template HTML into fragments.
85
- for (var i = 1; i < count; i++) {
86
- var next = get_next_sibling(end);
88
+ for (var i = 1; i < count; i++) {
89
+ var next = get_next_sibling(end);
87
90
 
88
- while (next !== null && next.nodeType === Node.COMMENT_NODE) {
89
- next = get_next_sibling(next);
90
- }
91
+ while (next !== null && next.nodeType === Node.COMMENT_NODE) {
92
+ next = get_next_sibling(next);
93
+ }
91
94
 
92
- if (next === null) {
93
- break;
94
- }
95
+ if (next === null) {
96
+ break;
97
+ }
95
98
 
96
- end = next;
97
- }
99
+ end = next;
100
+ }
98
101
 
99
- assign_nodes(start, end);
100
- return start;
101
- } else {
102
- var node_to_use = /** @type {Node} */ (hydrate_node);
103
- assign_nodes(node_to_use, node_to_use);
104
- return node_to_use;
105
- }
106
- }
107
- // If using runtime namespace, check active_namespace
108
- var svg = !is_comment && (use_svg_namespace || active_namespace === 'svg');
109
- var mathml = !is_comment && (use_mathml_namespace || active_namespace === 'mathml');
102
+ return end;
103
+ }
110
104
 
111
- if (node === undefined || node_svg !== svg || node_mathml !== mathml) {
112
- node = create_fragment_from_html(has_start ? content : '<!>' + content, svg, mathml);
113
- node_svg = svg;
114
- node_mathml = mathml;
115
- if (!is_fragment) node = /** @type {Node} */ (get_first_child(node));
116
- }
105
+ /**
106
+ * A template's parsed content and the flags that shaped it, shared by every
107
+ * clone of one `template()` instance.
108
+ * @typedef {{
109
+ * content: string;
110
+ * is_fragment: boolean;
111
+ * use_import_node: boolean;
112
+ * use_svg_namespace: boolean;
113
+ * use_mathml_namespace: boolean;
114
+ * is_comment: boolean;
115
+ * has_start: boolean;
116
+ * node: Node | DocumentFragment | undefined;
117
+ * node_svg: boolean;
118
+ * node_mathml: boolean;
119
+ * }} TemplateState
120
+ */
117
121
 
118
- /** @type {DocumentFragment | Node} */
119
- var clone =
120
- use_import_node || is_firefox
121
- ? document.importNode(/** @type {Node} */ (node), true)
122
- : /** @type {Node} */ (node).cloneNode(true);
122
+ /**
123
+ * The clone path of a {@link template} instance. Kept out of the per-template
124
+ * closure so a hydrating page never compiles it.
125
+ * @param {TemplateState} t
126
+ * @returns {Node}
127
+ */
128
+ function clone_template(t) {
129
+ var is_fragment = t.is_fragment;
130
+ var is_comment = t.is_comment;
131
+ var node = t.node;
132
+ // If using runtime namespace, check active_namespace
133
+ var svg = !is_comment && (t.use_svg_namespace || active_namespace === 'svg');
134
+ var mathml = !is_comment && (t.use_mathml_namespace || active_namespace === 'mathml');
135
+
136
+ if (node === undefined || t.node_svg !== svg || t.node_mathml !== mathml) {
137
+ node = create_fragment_from_html(t.has_start ? t.content : '<!>' + t.content, svg, mathml);
138
+ if (!is_fragment) node = /** @type {Node} */ (get_first_child(node));
139
+ t.node = node;
140
+ t.node_svg = svg;
141
+ t.node_mathml = mathml;
142
+ }
123
143
 
124
- if (is_fragment) {
125
- // we know for sure that children exist
126
- var start = /** @type {Node} */ (get_first_child(/** @type {DocumentFragment} */ (clone)));
127
- var end = /** @type {Node} */ (/** @type {DocumentFragment} */ (clone).lastChild);
144
+ /** @type {DocumentFragment | Node} */
145
+ var clone =
146
+ t.use_import_node || is_firefox
147
+ ? document.importNode(/** @type {Node} */ (node), true)
148
+ : /** @type {Node} */ (node).cloneNode(true);
149
+
150
+ var start = clone;
151
+ var end = clone;
152
+ if (is_fragment) {
153
+ // we know for sure that children exist
154
+ start = /** @type {Node} */ (get_first_child(/** @type {DocumentFragment} */ (clone)));
155
+ end = /** @type {Node} */ (/** @type {DocumentFragment} */ (clone).lastChild);
156
+ }
128
157
 
129
- assign_nodes(start, end);
130
- } else {
131
- assign_nodes(clone, clone);
132
- }
158
+ // assign_nodes, inline: every template clone records its range.
159
+ var block = /** @type {Block} */ (active_block);
160
+ var s = block.s;
161
+ if (s === null) {
162
+ block.s = { start, end };
163
+ } else if (s.start === null) {
164
+ s.start = start;
165
+ s.end = end;
166
+ }
133
167
 
134
- return clone;
168
+ return clone;
169
+ }
170
+
171
+ /**
172
+ * Creates a template node or fragment from content and flags.
173
+ * @param {string} content - The template content.
174
+ * @param {number} flags - Flags for template type.
175
+ * @param {number} [count] - Pre-calculated count of top-level nodes (for fragments). When provided, avoids runtime parsing.
176
+ * @returns {() => Node}
177
+ */
178
+ export function template(content, flags, count = 1) {
179
+ var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0;
180
+ var is_comment = content === '<!>';
181
+ /** @type {TemplateState} */
182
+ var t = {
183
+ content,
184
+ is_fragment,
185
+ use_import_node: (flags & TEMPLATE_USE_IMPORT_NODE) !== 0,
186
+ use_svg_namespace: (flags & TEMPLATE_SVG_NAMESPACE) !== 0,
187
+ use_mathml_namespace: (flags & TEMPLATE_MATHML_NAMESPACE) !== 0,
188
+ is_comment,
189
+ has_start: !is_comment && !content.startsWith('<!>'),
190
+ node: undefined,
191
+ node_svg: false,
192
+ node_mathml: false,
135
193
  };
194
+
195
+ return () => (hydrating ? hydrate_template(is_fragment, count) : clone_template(t));
136
196
  }
137
197
 
138
198
  /**
139
199
  * Appends a DOM node before the anchor node.
140
200
  * @param {ChildNode | AppendIntoAnchor} anchor - The anchor node.
141
201
  * @param {Node} dom - The DOM node to append.
142
- * @param {boolean} [skip_advance] - If true, don't advance hydrate_node (used when next() already positioned it).
143
202
  */
144
- export function append(anchor, dom, skip_advance) {
203
+ export function append(anchor, dom) {
145
204
  if (hydrating) {
146
- // When skip_advance is true, the caller (e.g., a fragment component) has already
147
- // used next() to position hydrate_node correctly. We must NOT reset it.
148
- if (skip_advance) {
149
- return;
150
- }
151
-
152
- // During hydration, if anchor === dom, we're hydrating a child component
153
- // where the "anchor" IS the content. If the cursor is still somewhere
154
- // inside dom (at any depth), reset it to dom's level so sibling traversal
155
- // works. But if the cursor has advanced past dom (e.g., because internal
156
- // control flow blocks like switch/if/for advanced it through their
157
- // hydration markers), preserve the advanced position.
158
- if (anchor === dom) {
159
- if (hydrate_node !== null && hydrate_node !== dom && dom.contains(hydrate_node)) {
160
- pop(dom);
161
- }
162
- return;
163
- }
164
-
165
- // If the hydration cursor has descended into dom's children (e.g. after
166
- // child()/sibling() traversal inside a single-node template), we need
167
- // pop() to reset back to dom's sibling level before advancing.
168
- // But if the cursor is already at dom's sibling level (e.g. because
169
- // nested control flow blocks advanced it past dom via sibling traversal),
170
- // pop() would incorrectly reset backwards — so we skip it.
171
- if (hydrate_node !== null && hydrate_node !== dom && dom.contains(hydrate_node)) {
172
- pop(dom);
173
- } else if (hydrate_node !== dom) {
174
- // Cursor has advanced past dom via sibling traversal (due to nested
175
- // block processing). Update the branch block's end to reflect the
176
- // actual extent, which may be past the statically-assigned end from
177
- // the template's assign_nodes call.
178
- var block = /** @type {Block} */ (active_block);
179
- var s = block.s;
180
- if (s !== null) {
181
- s.end = /** @type {Node} */ (hydrate_node);
182
- }
183
-
184
- if (is_after_hydration_block(dom, hydrate_node)) {
185
- return;
186
- }
187
- }
188
-
189
- // Only advance if there's a next sibling. At the end of a component's
190
- // content, there might not be more siblings, and that's fine.
191
- hydrate_advance();
205
+ hydrate_append(anchor, dom);
192
206
  return;
193
207
  }
194
- if ('parent' in anchor) {
208
+ if (/** @type {AppendIntoAnchor} */ (anchor).into === true) {
195
209
  // Append-into-parent sentinel: an all-component-children element passes a
196
210
  // `{ parent }` object (no `nodeType`) so each component's root appends as
197
211
  // the host's last child instead of inserting before a placeholder comment.
198
212
  // The block still self-marks its range via assign_nodes, so teardown works.
199
- anchor.parent.appendChild(dom);
213
+ /** @type {AppendIntoAnchor} */ (anchor).parent.appendChild(dom);
200
214
  return;
201
215
  }
202
- anchor.before(/** @type {Node} */ (dom));
203
- }
204
-
205
- /**
206
- * @param {Node} start
207
- * @param {Node | null} target
208
- * @returns {boolean}
209
- */
210
- function is_after_hydration_block(start, target) {
211
- if (
212
- target === null ||
213
- start.nodeType !== COMMENT_NODE ||
214
- /** @type {Comment} */ (start).data !== HYDRATION_START
215
- ) {
216
- return false;
217
- }
218
-
219
- var current = get_next_sibling(start);
220
- var depth = 0;
221
-
222
- while (current !== null && current !== target) {
223
- if (current.nodeType === COMMENT_NODE) {
224
- var data = /** @type {Comment} */ (current).data;
225
-
226
- // `[`-prefixed covers plain block starts and streaming slot markers
227
- if (data.startsWith(HYDRATION_START)) {
228
- depth += 1;
229
- } else if (data === HYDRATION_END) {
230
- if (depth === 0) {
231
- return true;
232
- }
233
-
234
- depth -= 1;
235
- }
236
- }
237
-
238
- current = get_next_sibling(current);
239
- }
240
-
241
- return false;
216
+ /** @type {ChildNode} */ (anchor).before(/** @type {Node} */ (dom));
242
217
  }
243
218
 
244
219
  export function text(data = '') {
@@ -0,0 +1,38 @@
1
+ import * as devalue from 'devalue';
2
+ import { create_transport } from '../../transport.js';
3
+
4
+ export { set_transport as setTransport };
5
+
6
+ /** @type {ReturnType<typeof create_transport>} */
7
+ let transport;
8
+
9
+ /**
10
+ * Register the application's transport before hydration, mounting or RPC.
11
+ * @param {import('#public').Transport} [value]
12
+ */
13
+ export function set_transport(value) {
14
+ transport = create_transport(value);
15
+ }
16
+
17
+ /**
18
+ * Encodes RPC arguments for the wire with the registered transport, if any.
19
+ * @param {unknown} value
20
+ * @returns {string}
21
+ */
22
+ export function encode(value) {
23
+ return devalue.stringify(value, transport?.reducers);
24
+ }
25
+
26
+ /**
27
+ * Revives a devalue payload: the string form (RPC results, hydration
28
+ * envelopes from a server without a transport), or the flattened array a
29
+ * server with a transport embeds directly in a hydration envelope.
30
+ * @param {string | unknown[]} payload
31
+ * @returns {any}
32
+ */
33
+ export function revive(payload) {
34
+ var revivers = transport?.revivers;
35
+ return typeof payload === 'string'
36
+ ? devalue.parse(payload, revivers)
37
+ : devalue.unflatten(payload, revivers);
38
+ }