ripple 0.4.1 → 0.4.3

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 (96) hide show
  1. package/CHANGELOG.md +162 -0
  2. package/package.json +9 -3
  3. package/src/constants.js +4 -0
  4. package/src/jsx-runtime.d.ts +2 -1
  5. package/src/runtime/array.js +15 -9
  6. package/src/runtime/index-client.js +25 -7
  7. package/src/runtime/index-server.js +1 -0
  8. package/src/runtime/internal/client/attributes.js +313 -0
  9. package/src/runtime/internal/client/blocks.js +4 -14
  10. package/src/runtime/internal/client/component.js +2 -5
  11. package/src/runtime/internal/client/composite.js +14 -6
  12. package/src/runtime/internal/client/constants.js +12 -6
  13. package/src/runtime/internal/client/context.js +3 -2
  14. package/src/runtime/internal/client/css.js +11 -26
  15. package/src/runtime/internal/client/errors.js +188 -0
  16. package/src/runtime/internal/client/events.js +79 -34
  17. package/src/runtime/internal/client/expression.js +21 -116
  18. package/src/runtime/internal/client/for.js +272 -222
  19. package/src/runtime/internal/client/head.js +4 -3
  20. package/src/runtime/internal/client/html.js +5 -3
  21. package/src/runtime/internal/client/hydrate.js +484 -0
  22. package/src/runtime/internal/client/hydration-enabled.js +7 -0
  23. package/src/runtime/internal/client/hydration.js +16 -97
  24. package/src/runtime/internal/client/if.js +13 -9
  25. package/src/runtime/internal/client/index.js +16 -8
  26. package/src/runtime/internal/client/operations.js +12 -9
  27. package/src/runtime/internal/client/portal.js +3 -2
  28. package/src/runtime/internal/client/render.js +75 -321
  29. package/src/runtime/internal/client/root-boundary-enabled.js +7 -0
  30. package/src/runtime/internal/client/runtime.js +129 -362
  31. package/src/runtime/internal/client/template-ns.js +47 -0
  32. package/src/runtime/internal/client/template.js +63 -140
  33. package/src/runtime/internal/client/track-async.js +356 -0
  34. package/src/runtime/internal/client/try.js +133 -319
  35. package/src/runtime/internal/client/types.d.ts +48 -24
  36. package/src/runtime/internal/server/index.js +38 -33
  37. package/src/runtime/internal/server/prerender.js +27 -0
  38. package/src/server/index.js +1 -0
  39. package/src/utils/class-name.js +28 -0
  40. package/tests/client/basic/basic.errors.test.tsrx +3 -3
  41. package/tests/client/compiler/__snapshots__/compiler.typescript.test.tsrx.snap +0 -2
  42. package/tests/client/compiler/compiler.basic.test.tsrx +4 -4
  43. package/tests/client/compiler/compiler.tracked-access.test.tsrx +3 -3
  44. package/tests/client/composite/composite.props.test.tsrx +10 -10
  45. package/tests/client/derived-release.test.tsrx +3 -3
  46. package/tests/client/for-item.test.tsrx +443 -0
  47. package/tests/client/for-selector.test.tsrx +95 -0
  48. package/tests/hydration/compiled/client/basic.js +97 -123
  49. package/tests/hydration/compiled/client/composite.js +5 -5
  50. package/tests/hydration/compiled/client/events.js +84 -79
  51. package/tests/hydration/compiled/client/for.js +229 -233
  52. package/tests/hydration/compiled/client/fragment-cursor.js +781 -481
  53. package/tests/hydration/compiled/client/head.js +23 -26
  54. package/tests/hydration/compiled/client/hmr.js +4 -4
  55. package/tests/hydration/compiled/client/html-in-template.js +5 -5
  56. package/tests/hydration/compiled/client/html.js +174 -208
  57. package/tests/hydration/compiled/client/if-children.js +71 -70
  58. package/tests/hydration/compiled/client/if-fragment-controlflow.js +46 -46
  59. package/tests/hydration/compiled/client/if.js +26 -26
  60. package/tests/hydration/compiled/client/mixed-control-flow.js +63 -105
  61. package/tests/hydration/compiled/client/nested-control-flow.js +170 -390
  62. package/tests/hydration/compiled/client/portal.js +10 -10
  63. package/tests/hydration/compiled/client/reactivity.js +36 -50
  64. package/tests/hydration/compiled/client/return.js +2 -2
  65. package/tests/hydration/compiled/client/streaming.js +34 -40
  66. package/tests/hydration/compiled/client/switch.js +25 -25
  67. package/tests/hydration/compiled/client/track-async-serialization.js +41 -41
  68. package/tests/hydration/compiled/client/try.js +15 -15
  69. package/tests/hydration/compiled/client/typed-text.js +8 -19
  70. package/tests/hydration/compiled/server/basic.js +6 -6
  71. package/tests/hydration/compiled/server/events.js +13 -61
  72. package/tests/hydration/compiled/server/for.js +23 -31
  73. package/tests/hydration/compiled/server/fragment-cursor.js +214 -366
  74. package/tests/hydration/compiled/server/head.js +6 -6
  75. package/tests/hydration/compiled/server/hmr.js +1 -1
  76. package/tests/hydration/compiled/server/html.js +1 -1
  77. package/tests/hydration/compiled/server/if-children.js +9 -9
  78. package/tests/hydration/compiled/server/if.js +5 -5
  79. package/tests/hydration/compiled/server/mixed-control-flow.js +4 -4
  80. package/tests/hydration/compiled/server/portal.js +1 -1
  81. package/tests/hydration/compiled/server/reactivity.js +9 -9
  82. package/tests/hydration/compiled/server/streaming.js +9 -9
  83. package/tests/hydration/compiled/server/switch.js +4 -4
  84. package/tests/hydration/compiled/server/track-async-serialization.js +16 -16
  85. package/tests/hydration/compiled/server/try.js +4 -4
  86. package/tests/hydration/compiled/server/typed-text.js +1 -1
  87. package/tests/hydration/components/fragment-cursor.tsrx +60 -0
  88. package/tests/hydration/components/track-async-serialization.tsrx +2 -2
  89. package/tests/hydration/fragment-cursor.test.js +34 -1
  90. package/tests/hydration/track-async-serialization.test.js +1 -1
  91. package/tests/server/basic.components.test.tsrx +3 -3
  92. package/tests/server/basic.test.tsrx +23 -0
  93. package/tests/server/track-async-serialization.test.tsrx +6 -6
  94. package/tests/utils/tracked-types.test.js +3 -3
  95. package/types/index.d.ts +8 -8
  96. package/types/server.d.ts +17 -0
@@ -0,0 +1,188 @@
1
+ import { DEV } from 'esm-env';
2
+
3
+ /**
4
+ * The runtime's errors, one function per error as in Svelte: in development
5
+ * the message is thrown with a link to its reference page; in production only
6
+ * the link is, so the message text never ships. Each page lives at
7
+ * `https://ripple-ts.com/e/<code>`.
8
+ */
9
+
10
+ /**
11
+ * @param {string} code
12
+ * @param {string} message
13
+ * @returns {string}
14
+ */
15
+ function text(code, message) {
16
+ var link = `https://ripple-ts.com/e/${code}`;
17
+ return DEV ? `${message}\n${link}` : link;
18
+ }
19
+
20
+ /** @returns {never} */
21
+ export function effect_orphan() {
22
+ throw new Error(
23
+ DEV
24
+ ? text(
25
+ 'effect_orphan',
26
+ 'effect() must be called within an active context, such as a component or effect',
27
+ )
28
+ : text('effect_orphan', ''),
29
+ );
30
+ }
31
+
32
+ /** @returns {never} */
33
+ export function track_orphan() {
34
+ throw new TypeError(
35
+ DEV
36
+ ? text('track_orphan', 'track() requires a valid component context')
37
+ : text('track_orphan', ''),
38
+ );
39
+ }
40
+
41
+ /** @returns {never} */
42
+ export function track_async_orphan() {
43
+ throw new TypeError(
44
+ DEV
45
+ ? text('track_async_orphan', 'trackAsync() requires a valid component context')
46
+ : text('track_async_orphan', ''),
47
+ );
48
+ }
49
+
50
+ /** @returns {never} */
51
+ export function track_async_argument() {
52
+ throw new TypeError(
53
+ DEV
54
+ ? text(
55
+ 'track_async_argument',
56
+ 'trackAsync() only accepts function arguments that return a promise or an object with a promise property',
57
+ )
58
+ : text('track_async_argument', ''),
59
+ );
60
+ }
61
+
62
+ /** @returns {never} */
63
+ export function track_async_boundary() {
64
+ throw new Error(
65
+ DEV
66
+ ? text('track_async_boundary', 'Missing parent `try { ... } pending { ... }` statement')
67
+ : text('track_async_boundary', ''),
68
+ );
69
+ }
70
+
71
+ /**
72
+ * @param {boolean} in_component the read sits directly in a component body,
73
+ * otherwise in a try/pending/catch body
74
+ * @returns {never}
75
+ */
76
+ export function pending_read_direct(in_component) {
77
+ throw new Error(
78
+ DEV
79
+ ? text(
80
+ 'pending_read_direct',
81
+ `Reads on pending tracked values directly inside ${in_component ? 'component' : 'try/pending/catch'} body are prohibited. Use trackPending() test or peek() for safe access or create another derived instead.`,
82
+ )
83
+ : text('pending_read_direct', ''),
84
+ );
85
+ }
86
+
87
+ /** @returns {never} */
88
+ export function update_depth_exceeded() {
89
+ throw new Error(
90
+ DEV
91
+ ? text(
92
+ 'update_depth_exceeded',
93
+ 'Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state.',
94
+ )
95
+ : text('update_depth_exceeded', ''),
96
+ );
97
+ }
98
+
99
+ /** @returns {never} */
100
+ export function set_in_derived() {
101
+ throw new Error(
102
+ DEV
103
+ ? text(
104
+ 'set_in_derived',
105
+ 'Assignments or updates to tracked values are not allowed during computed "track(() => ...)" evaluation',
106
+ )
107
+ : text('set_in_derived', ''),
108
+ );
109
+ }
110
+
111
+ /**
112
+ * @param {string} [message] a caller's own wording
113
+ * @returns {never}
114
+ */
115
+ export function scope_orphan(message) {
116
+ throw new Error(
117
+ DEV
118
+ ? text('scope_orphan', message ?? 'Cannot access outside of a component context')
119
+ : text('scope_orphan', ''),
120
+ );
121
+ }
122
+
123
+ /**
124
+ * @param {boolean} is_element the value is a TSRX element rather than a
125
+ * component function
126
+ * @returns {never}
127
+ */
128
+ export function component_invalid(is_element) {
129
+ throw new TypeError(
130
+ DEV
131
+ ? text(
132
+ 'component_invalid',
133
+ `Invalid component type: ${is_element ? 'received a TSRXElement value.' : 'expected a component function.'}`,
134
+ )
135
+ : text('component_invalid', ''),
136
+ );
137
+ }
138
+
139
+ /**
140
+ * @param {boolean} is_set `Context#set` rather than `Context#get`
141
+ * @returns {never}
142
+ */
143
+ export function context_orphan(is_set) {
144
+ throw new Error(
145
+ DEV
146
+ ? text(
147
+ 'context_orphan',
148
+ `No active component found, cannot ${is_set ? 'set' : 'get'} context`,
149
+ )
150
+ : text('context_orphan', ''),
151
+ );
152
+ }
153
+
154
+ /**
155
+ * @param {string} kind the block whose end marker is missing
156
+ * @returns {never}
157
+ */
158
+ export function hydration_mismatch(kind) {
159
+ throw new Error(
160
+ DEV
161
+ ? text('hydration_mismatch', `Hydration mismatch: expected end marker for ${kind} block`)
162
+ : text('hydration_mismatch', ''),
163
+ );
164
+ }
165
+
166
+ /** @returns {never} */
167
+ export function hydration_disabled() {
168
+ throw new Error(
169
+ DEV
170
+ ? text(
171
+ 'hydration_disabled',
172
+ 'hydrate() is not available in a client-only build: this build was compiled with `ssr: false`, which leaves the hydration runtime out',
173
+ )
174
+ : text('hydration_disabled', ''),
175
+ );
176
+ }
177
+
178
+ /** @returns {never} */
179
+ export function root_boundary_disabled() {
180
+ throw new Error(
181
+ DEV
182
+ ? text(
183
+ 'root_boundary_disabled',
184
+ 'A root boundary is not available in this build: it was compiled with `rootBoundary: false`, which leaves the boundary runtime out, so `mount()` and `hydrate()` cannot take `rootBoundary` options',
185
+ )
186
+ : text('root_boundary_disabled', ''),
187
+ );
188
+ }
@@ -23,7 +23,9 @@ import { render } from './blocks.js';
23
23
  var all_registered_events = new Set();
24
24
 
25
25
  /**
26
- * @typedef {{ count: number, registered_events: Set<string>, target: Element }} RootTargetRef
26
+ * A root delegation target: its acquire count, the event names it listens
27
+ * for, and the element.
28
+ * @typedef {{ n: number, e: Set<string>, t: Element }} RootTargetRef
27
29
  */
28
30
 
29
31
  /**
@@ -103,8 +105,6 @@ export function on(element, type, handler, options = {}) {
103
105
  };
104
106
  }
105
107
 
106
- var last_propagated_event = null;
107
-
108
108
  /**
109
109
  * @this {EventTarget}
110
110
  * @param {Event} event
@@ -114,19 +114,19 @@ export function handle_event_propagation(event) {
114
114
  var handler_element = this;
115
115
  var owner_document = /** @type {Node} */ (handler_element).ownerDocument;
116
116
  var event_name = event.type;
117
- var path = event.composedPath?.() || [];
118
- var current_target = /** @type {null | Element} */ (path[0] || event.target);
119
-
120
- last_propagated_event = event;
117
+ /** @type {null | Element} */
118
+ var current_target;
121
119
 
122
- // composedPath contains list of nodes the event has propagated through.
123
- // We check __root to skip all nodes below it in case this is a
124
- // parent of the __root node, which indicates that there's nested
125
- // mounted apps. In this case we don't want to trigger events multiple times.
126
- var path_idx = 0;
127
- var handled_at = last_propagated_event === event && event.__root;
120
+ // __root marks the root that already handled this event: this listener
121
+ // then belongs to a parent of a nested mounted app, and the walk resumes
122
+ // from that root so nothing below it handles the event twice. Only then
123
+ // is the composed path needed; a plain event starts at its target (the
124
+ // composed target when it was retargeted out of a shadow tree).
125
+ var handled_at = event.__root;
128
126
 
129
127
  if (handled_at) {
128
+ var path = event.composedPath?.() || [];
129
+ var path_idx = 0;
130
130
  var at_idx = path.indexOf(handled_at);
131
131
  if (at_idx !== -1 && (handler_element === document || handler_element === window)) {
132
132
  // This is the fallback document listener or a window listener, but the event was already handled
@@ -151,9 +151,14 @@ export function handle_event_propagation(event) {
151
151
  if (at_idx <= handler_idx) {
152
152
  path_idx = at_idx;
153
153
  }
154
+ current_target = /** @type {Element} */ (path[path_idx] || event.target);
155
+ } else {
156
+ current_target = /** @type {Element} */ (event.target);
157
+ if (current_target !== null && /** @type {any} */ (current_target).shadowRoot) {
158
+ current_target = /** @type {Element} */ (event.composedPath?.()[0] || current_target);
159
+ }
154
160
  }
155
161
 
156
- current_target = /** @type {Element} */ (path[path_idx] || event.target);
157
162
  // there can only be one delegated event per element, and we either already handled the current target,
158
163
  // or this is the very first target in the chain which has a non-delegated listener, in which case it's safe
159
164
  // to handle a possible delegated event on it later (through the root delegation listener for example).
@@ -181,9 +186,10 @@ export function handle_event_propagation(event) {
181
186
  */
182
187
  var throw_error;
183
188
  /**
184
- * @type {unknown[]}
189
+ * @type {unknown[] | null}
185
190
  */
186
- var other_errors = [];
191
+ var other_errors = null;
192
+ var prop = '__' + event_name;
187
193
 
188
194
  while (current_target !== null) {
189
195
  /** @type {null | Element} */
@@ -194,7 +200,7 @@ export function handle_event_propagation(event) {
194
200
  null;
195
201
 
196
202
  try {
197
- var delegated = /** @type {Record<string, any>} */ (current_target)['__' + event_name];
203
+ var delegated = /** @type {Record<string, any>} */ (current_target)[prop];
198
204
 
199
205
  if (delegated !== undefined && !(/** @type {any} */ (current_target).disabled)) {
200
206
  if (is_array(delegated)) {
@@ -207,7 +213,7 @@ export function handle_event_propagation(event) {
207
213
  }
208
214
  } catch (error) {
209
215
  if (throw_error) {
210
- other_errors.push(error);
216
+ (other_errors ??= []).push(error);
211
217
  } else {
212
218
  throw_error = error;
213
219
  }
@@ -219,16 +225,17 @@ export function handle_event_propagation(event) {
219
225
  }
220
226
 
221
227
  if (throw_error) {
222
- for (let error of other_errors) {
223
- // Throw the rest of the errors, one-by-one on a microtask
224
- queueMicrotask(() => {
225
- throw error;
226
- });
228
+ if (other_errors !== null) {
229
+ for (let error of other_errors) {
230
+ // Throw the rest of the errors, one-by-one on a microtask
231
+ queueMicrotask(() => {
232
+ throw error;
233
+ });
234
+ }
227
235
  }
228
236
  throw throw_error;
229
237
  }
230
238
  } finally {
231
- set_active_block(previous_block);
232
239
  event.__root = handler_element;
233
240
  // @ts-ignore remove proxy on currentTarget
234
241
  delete event.currentTarget;
@@ -412,6 +419,44 @@ export function event(event_name, dom, handler) {
412
419
  event_listener(event_name, dom, handler);
413
420
  }
414
421
 
422
+ /**
423
+ * Compiler-emitted listener for a static `onEvent={fn}` whose name can never
424
+ * be delegated (`onBlur`, `onScroll`, a `Capture` variant): a native listener
425
+ * on the element, with the handler run outside any reactive context as a
426
+ * delegated handler is. Nothing is returned, as for `event()`. The name is the
427
+ * DOM event name the compiler resolved, so no name table is consulted here.
428
+ * @param {string} name
429
+ * @param {EventTarget} dom
430
+ * @param {EventListener} handler
431
+ * @param {boolean} [capture]
432
+ * @returns {void}
433
+ */
434
+ export function listen(name, dom, handler, capture) {
435
+ dom.addEventListener(
436
+ name,
437
+ /**
438
+ * @this {EventTarget}
439
+ * @param {Event} event
440
+ */
441
+ function (event) {
442
+ var previous_block = active_block;
443
+ var previous_reaction = active_reaction;
444
+ var previous_tracking = tracking;
445
+ set_active_block(null);
446
+ set_active_reaction(null);
447
+ set_tracking(false);
448
+ try {
449
+ return handler.call(this, event);
450
+ } finally {
451
+ set_active_block(previous_block);
452
+ set_active_reaction(previous_reaction);
453
+ set_tracking(previous_tracking);
454
+ }
455
+ },
456
+ capture,
457
+ );
458
+ }
459
+
415
460
  /**
416
461
  * Attaches a listener and returns its remover; `event()` is the one-shot
417
462
  * compiled form of this.
@@ -496,8 +541,8 @@ export function delegate(events) {
496
541
  * @param {Iterable<string>} events
497
542
  */
498
543
  function register_root_events(ref, events) {
499
- var registered_events = ref.registered_events;
500
- var target = ref.target;
544
+ var registered_events = ref.e;
545
+ var target = ref.t;
501
546
 
502
547
  for (var event_name of events) {
503
548
  if (registered_events.has(event_name)) continue;
@@ -519,17 +564,17 @@ export function handle_root_events(target) {
519
564
  // Sibling portals mostly share one target, so check the last ref first.
520
565
  /** @type {RootTargetRef | undefined} */
521
566
  var ref =
522
- last_root_ref !== null && last_root_ref.target === target
567
+ last_root_ref !== null && last_root_ref.t === target
523
568
  ? last_root_ref
524
569
  : root_target_refs.get(target);
525
570
 
526
571
  if (ref === undefined) {
527
- ref = { count: 0, registered_events: new Set(), target };
572
+ ref = { n: 0, e: new Set(), t: target };
528
573
  root_target_refs.set(target, ref);
529
574
  register_root_events(ref, all_registered_events);
530
575
  }
531
576
 
532
- ref.count += 1;
577
+ ref.n += 1;
533
578
  last_root_ref = ref;
534
579
  return ref;
535
580
  }
@@ -539,18 +584,18 @@ export function handle_root_events(target) {
539
584
  * @returns {void}
540
585
  */
541
586
  export function release_root_events(ref) {
542
- // The map entry for `ref.target` is always this `ref`: it is only deleted
587
+ // The map entry for `ref.t` is always this `ref`: it is only deleted
543
588
  // when the count hits 0, which requires every acquirer to have released.
544
- ref.count -= 1;
545
- if (ref.count > 0) return;
589
+ ref.n -= 1;
590
+ if (ref.n > 0) return;
546
591
 
547
592
  // Last caller for this target: actually tear down the shared listeners.
548
- var target = ref.target;
593
+ var target = ref.t;
549
594
  root_target_refs.delete(target);
550
595
  if (last_root_ref === ref) {
551
596
  last_root_ref = null;
552
597
  }
553
- for (var event_name of ref.registered_events) {
598
+ for (var event_name of ref.e) {
554
599
  target.removeEventListener(event_name, /** @type {EventListener} */ (handle_event_propagation));
555
600
  }
556
601
  }
@@ -6,9 +6,10 @@ import { BRANCH_BLOCK, IF_BLOCK, UNINITIALIZED } from './constants.js';
6
6
  import { create_text, get_next_sibling } from './operations.js';
7
7
  import { assign_nodes } from './template.js';
8
8
  import { active_block } from './runtime.js';
9
- import { hydrate_node, hydrating, set_hydrate_node } from './hydration.js';
10
- import { COMMENT_NODE, HYDRATION_END, HYDRATION_START, TEXT_NODE } from '../../../constants.js';
9
+ import { H, hydrate_node, hydrating, set_hydrate_node } from './hydration.js';
10
+ import { COMMENT_NODE, HYDRATION_START, TEXT_NODE } from '../../../constants.js';
11
11
  import { is_tsrx_element, TSRX_ELEMENT } from '../../element.js';
12
+ import { HYDRATION } from 'ripple/internal/client/hydration-enabled';
12
13
 
13
14
  /**
14
15
  * Finds the nearest enclosing block that owns a DOM range (a branch or an if
@@ -58,7 +59,7 @@ export function render_value(value, anchor, block) {
58
59
  * @returns {void}
59
60
  */
60
61
  function render_tsrx_collection(value, anchor, block) {
61
- if (hydrating) {
62
+ if (HYDRATION && hydrating) {
62
63
  assign_nodes(/** @type {Node} */ (hydrate_node ?? anchor), anchor);
63
64
  render_tsrx_collection_items(value, anchor, block);
64
65
  return;
@@ -133,61 +134,15 @@ function render_tsrx_element(value, anchor, block) {
133
134
  * @returns {void}
134
135
  */
135
136
  function render_tsrx_collection_text(value, anchor, assign = false) {
136
- if (!hydrating) {
137
- var text = create_text(value);
138
- insert_before(anchor, text);
139
- if (assign) {
140
- assign_nodes(text, text);
141
- }
142
- return;
143
- }
144
-
145
- var node = hydrate_node;
146
-
147
- if (node?.nodeType === COMMENT_NODE && /** @type {Comment} */ (node).data === HYDRATION_START) {
148
- node = get_next_sibling(node);
149
- }
150
-
151
- if (node?.nodeType === TEXT_NODE) {
152
- var current_value = /** @type {Text} */ (node).nodeValue ?? '';
153
-
154
- if (current_value !== value) {
155
- /** @type {Text} */ (node).nodeValue = value;
156
-
157
- if (current_value.startsWith(value)) {
158
- var remaining = current_value.slice(value.length);
159
-
160
- if (remaining !== '') {
161
- var remaining_text = create_text(remaining);
162
- /** @type {ChildNode} */ (node).after(remaining_text);
163
- if (assign) {
164
- assign_nodes(node, node);
165
- }
166
- set_hydrate_node(remaining_text);
167
- return;
168
- }
169
- }
170
- }
171
-
172
- if (assign) {
173
- assign_nodes(node, node);
174
- }
175
- set_hydrate_node(get_next_sibling(node) ?? anchor);
137
+ if (HYDRATION && hydrating) {
138
+ /** @type {import('./hydrate.js').HydrationRuntime} */ (H).x(value, anchor, assign);
176
139
  return;
177
140
  }
178
-
179
- var new_text = create_text(value);
180
-
181
- if (node !== null && node !== anchor) {
182
- /** @type {ChildNode} */ (node).before(new_text);
183
- } else {
184
- anchor.before(new_text);
185
- }
186
-
141
+ var text = create_text(value);
142
+ insert_before(anchor, text);
187
143
  if (assign) {
188
- assign_nodes(new_text, new_text);
144
+ assign_nodes(text, text);
189
145
  }
190
- set_hydrate_node(node ?? anchor);
191
146
  }
192
147
 
193
148
  /**
@@ -250,10 +205,13 @@ function run_expression(s) {
250
205
  var anchor = s.a;
251
206
  var type = typeof next_value;
252
207
  var is_hydration_marker =
253
- hydrating && s.n === COMMENT_NODE && /** @type {Comment} */ (anchor).data === HYDRATION_START;
208
+ HYDRATION &&
209
+ hydrating &&
210
+ s.n === COMMENT_NODE &&
211
+ /** @type {Comment} */ (anchor).data === HYDRATION_START;
254
212
 
255
213
  if (is_hydration_marker) {
256
- s.m ??= ensure_expression_end(anchor);
214
+ s.m ??= /** @type {import('./hydrate.js').HydrationRuntime} */ (H).e(anchor);
257
215
  }
258
216
 
259
217
  var end = s.m;
@@ -282,7 +240,7 @@ function run_expression(s) {
282
240
  restore_parent_start(s);
283
241
  }
284
242
 
285
- if (end !== null && (s.i || !hydrating)) {
243
+ if (end !== null && (s.i || !(HYDRATION && hydrating))) {
286
244
  clear_expression_range(anchor, end);
287
245
  }
288
246
 
@@ -357,7 +315,10 @@ function run_expression(s) {
357
315
  }
358
316
 
359
317
  if (is_hydration_marker) {
360
- var text = (s.t = get_hydrated_text(anchor, /** @type {Comment} */ (end)));
318
+ var text = (s.t = /** @type {import('./hydrate.js').HydrationRuntime} */ (H).h(
319
+ anchor,
320
+ /** @type {Comment} */ (end),
321
+ ));
361
322
 
362
323
  if (next_text === '') {
363
324
  if (text !== null) {
@@ -408,68 +369,12 @@ function restore_parent_start(s) {
408
369
  }
409
370
  }
410
371
 
411
- /**
412
- * @param {Node} anchor
413
- * @returns {Comment}
414
- */
415
- function ensure_expression_end(anchor) {
416
- if (hydrating) {
417
- /** @type {Node | null} */
418
- var current = get_next_sibling(anchor);
419
- var depth = 0;
420
-
421
- while (current !== null) {
422
- if (current.nodeType === COMMENT_NODE) {
423
- var data = /** @type {Comment} */ (current).data;
424
-
425
- if (data === HYDRATION_START) {
426
- depth += 1;
427
- } else if (data === HYDRATION_END) {
428
- if (depth === 0) {
429
- return /** @type {Comment} */ (current);
430
- }
431
-
432
- depth -= 1;
433
- }
434
- }
435
-
436
- current = get_next_sibling(current);
437
- }
438
-
439
- throw new Error('Hydration mismatch: expected end marker for expression block');
440
- }
441
-
442
- var end = document.createComment(HYDRATION_END);
443
- /** @type {ChildNode} */ (anchor).after(end);
444
- return end;
445
- }
446
-
447
- /**
448
- * @param {Node} anchor
449
- * @param {Node} end
450
- * @returns {Text | null}
451
- */
452
- function get_hydrated_text(anchor, end) {
453
- var first = get_next_sibling(anchor);
454
-
455
- if (first === end) {
456
- return null;
457
- }
458
-
459
- if (first?.nodeType === TEXT_NODE && get_next_sibling(first) === end) {
460
- return /** @type {Text} */ (first);
461
- }
462
-
463
- clear_expression_range(anchor, end);
464
- return null;
465
- }
466
-
467
372
  /**
468
373
  * @param {Node} anchor
469
374
  * @param {Node} end
470
375
  * @returns {void}
471
376
  */
472
- function clear_expression_range(anchor, end) {
377
+ export function clear_expression_range(anchor, end) {
473
378
  var current = get_next_sibling(anchor);
474
379
 
475
380
  while (current !== null && current !== end) {
@@ -487,7 +392,7 @@ function clear_expression_range(anchor, end) {
487
392
  * @returns {void}
488
393
  */
489
394
  function settle_hydration(end) {
490
- if (hydrating) {
395
+ if (HYDRATION && hydrating) {
491
396
  set_hydrate_node(end);
492
397
  }
493
398
  }