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
@@ -1,14 +1,14 @@
1
- /** @import { Block, TryBoundaryState, BlockWithTryBoundary, BlockWithTryBoundaryAndCatch } from '#client' */
1
+ /** @import { AppendIntoAnchor, Block, TryState, TryCatchFunction, TryPendingFunction, BlockWithTryBoundary, BlockWithTryBoundaryAndCatch } from '#client' */
2
2
 
3
3
  import {
4
- boundary_fn_running_block,
5
- create_try_block,
4
+ block as create_block,
6
5
  destroy_block,
7
6
  is_destroyed,
8
7
  move_block,
8
+ own_anchor,
9
9
  resume_block,
10
10
  } from './blocks.js';
11
- import { TRY_BLOCK } from './constants.js';
11
+ import { BRANCH_BLOCK, DIRECT_CHILD_BLOCK, TRY_BLOCK } from './constants.js';
12
12
  import {
13
13
  COMMENT_NODE,
14
14
  HYDRATION_START,
@@ -21,9 +21,10 @@ import {
21
21
  hydrate_node,
22
22
  hydrating,
23
23
  set_hydrate_node,
24
- set_hydrating,
24
+ set_hydration,
25
25
  skip_to_hydration_end,
26
26
  } from './hydration.js';
27
+ import { resolve_anchor } from './operations.js';
27
28
  import { append } from './template.js';
28
29
  import {
29
30
  active_block,
@@ -33,425 +34,493 @@ import {
33
34
  } from './runtime.js';
34
35
 
35
36
  /**
36
- @typedef {(
37
- anchor: Node,
38
- error: any,
39
- reset?: () => void
40
- ) => void} CatchFunction;
41
-
42
- @typedef {(anchor: Node) => void} PendingFunction
37
+ * A boundary's branches run as direct children of its try block (see
38
+ * `TryState` in types.d.ts for the state they share).
39
+ * @param {() => void} fn
40
+ * @returns {Block}
43
41
  */
42
+ function boundary_branch(fn) {
43
+ return create_block(BRANCH_BLOCK | DIRECT_CHILD_BLOCK, fn);
44
+ }
45
+
46
+ /** @param {TryState} state */
47
+ function clear_paused_blocks(state) {
48
+ state.paused_blocks.clear();
49
+ }
44
50
 
45
51
  /**
46
- * @param {Node} node
47
- * @param {(anchor: Node, block?: Block) => void} try_fn
48
- * @param {CatchFunction | null} catch_fn
49
- * @param {PendingFunction | null} [pending_fn=null]
50
- * @returns {void}
52
+ * @param {TryState} state
53
+ * @returns {boolean}
51
54
  */
52
- export function try_block(node, try_fn, catch_fn, pending_fn = null, root_controlled = false) {
53
- var anchor = node;
54
- /** @type {Node | undefined} */
55
- var boundary;
56
- var pending_count = 0;
57
- var request_version = 0;
58
- /** @type {Set<number>} */
59
- var active_requests = new Set();
60
- /** @type {Block | null} */
61
- var try_block = null;
62
- /** @type {Block | null} */
63
- var resolved_branch = null;
64
- /** @type {Block | null} */
65
- var pending_branch = null;
66
- /** @type {Block | null} */
67
- var catch_branch = null;
68
- /** @type {DocumentFragment | null} */
69
- var offscreen_fragment = null;
70
- var has_resolved = false;
71
- /** @type {'resolved' | 'pending' | 'catch'} */
72
- var mode = 'resolved';
73
- /** @type {Map<number, (reason: any) => void>} */
74
- var pending_deferreds = new Map();
75
- /** @type {Set<Block>} */
76
- var paused_blocks = new Set();
77
- /** @type {string | null} */
78
- var streamed_id = null;
79
- var streamed_errored = false;
80
- var streamed_fallback = false;
81
- /** @type {Comment | null} */
82
- var slot_open = null;
83
- /** @type {Comment | null} */
84
- var slot_close = null;
85
-
86
- function clear_paused_blocks() {
87
- paused_blocks.clear();
88
- }
89
-
90
- /**
91
- * @returns {boolean}
92
- */
93
- function resume_paused_blocks() {
94
- if (paused_blocks.size === 0) {
95
- return false;
96
- }
55
+ function resume_paused_blocks(state) {
56
+ if (state.paused_blocks.size === 0) {
57
+ return false;
58
+ }
97
59
 
98
- var blocks = paused_blocks;
99
- paused_blocks = new Set();
100
- var resumed = false;
60
+ var blocks = state.paused_blocks;
61
+ state.paused_blocks = new Set();
62
+ var resumed = false;
101
63
 
102
- for (var block of blocks) {
103
- if (!is_destroyed(block)) {
104
- resume_block(block);
105
- resumed = true;
106
- }
64
+ for (var block of blocks) {
65
+ if (!is_destroyed(block)) {
66
+ resume_block(block);
67
+ resumed = true;
107
68
  }
108
-
109
- return resumed;
110
69
  }
111
70
 
112
- function show_resolved_fragment() {
113
- if (offscreen_fragment !== null) {
114
- /** @type {ChildNode} */ (anchor).before(offscreen_fragment);
115
- offscreen_fragment = null;
116
- }
71
+ return resumed;
72
+ }
117
73
 
118
- has_resolved = true;
119
- mode = 'resolved';
74
+ /** @param {TryState} state */
75
+ function show_resolved_fragment(state) {
76
+ if (state.offscreen_fragment !== null) {
77
+ /** @type {ChildNode} */ (state.anchor).before(state.offscreen_fragment);
78
+ state.offscreen_fragment = null;
120
79
  }
121
80
 
122
- function render_resolved() {
123
- if (
124
- try_block !== null &&
125
- !is_destroyed(try_block) &&
126
- (resolved_branch === null || is_destroyed(resolved_branch))
127
- ) {
128
- if (catch_branch !== null) {
129
- destroy_block(catch_branch);
130
- catch_branch = null;
131
- }
132
- mode = 'resolved';
133
- if (active_block !== try_block) {
134
- with_block(try_block, () => {
135
- resolved_branch = boundary_fn_running_block(() => try_fn(anchor));
136
- });
137
- } else {
138
- resolved_branch = boundary_fn_running_block(() => try_fn(anchor));
139
- }
81
+ state.has_resolved = true;
82
+ state.mode = 'resolved';
83
+ }
84
+
85
+ /** @param {TryState} state */
86
+ function render_resolved(state) {
87
+ if (
88
+ state.try_block !== null &&
89
+ !is_destroyed(state.try_block) &&
90
+ (state.resolved_branch === null || is_destroyed(state.resolved_branch))
91
+ ) {
92
+ if (state.catch_branch !== null) {
93
+ destroy_block(state.catch_branch);
94
+ state.catch_branch = null;
95
+ }
96
+ state.mode = 'resolved';
97
+ if (active_block !== state.try_block) {
98
+ with_block(state.try_block, () => {
99
+ state.resolved_branch = boundary_branch(() => state.try_fn(state.anchor));
100
+ });
101
+ } else {
102
+ state.resolved_branch = boundary_branch(() => state.try_fn(state.anchor));
140
103
  }
141
104
  }
105
+ }
142
106
 
143
- function destroy_resolved() {
144
- if (resolved_branch !== null && !is_destroyed(resolved_branch)) {
145
- destroy_block(resolved_branch);
146
- }
147
- resolved_branch = null;
148
- offscreen_fragment = null;
107
+ /** @param {TryState} state */
108
+ function destroy_resolved(state) {
109
+ if (state.resolved_branch !== null && !is_destroyed(state.resolved_branch)) {
110
+ destroy_block(state.resolved_branch);
149
111
  }
112
+ state.resolved_branch = null;
113
+ state.offscreen_fragment = null;
114
+ }
150
115
 
151
- function move_resolved_offscreen() {
152
- if (resolved_branch !== null) {
153
- if (!offscreen_fragment) {
154
- // if offcreen_fragment exists, it means the resolved_branch is already offscreen,
155
- // so we can skip moving it again
156
- offscreen_fragment = document.createDocumentFragment();
157
- move_block(resolved_branch, offscreen_fragment);
158
- }
116
+ /** @param {TryState} state */
117
+ function move_resolved_offscreen(state) {
118
+ if (state.resolved_branch !== null) {
119
+ if (!state.offscreen_fragment) {
120
+ // if offcreen_fragment exists, it means the resolved_branch is already offscreen,
121
+ // so we can skip moving it again
122
+ state.offscreen_fragment = document.createDocumentFragment();
123
+ move_block(state.resolved_branch, state.offscreen_fragment);
159
124
  }
160
125
  }
126
+ }
161
127
 
162
- function render_pending() {
163
- if (pending_fn === null || mode === 'pending') {
164
- return;
165
- }
128
+ /** @param {TryState} state */
129
+ function render_pending(state) {
130
+ if (state.pending_fn === null || state.mode === 'pending') {
131
+ return;
132
+ }
166
133
 
167
- move_resolved_offscreen();
134
+ move_resolved_offscreen(state);
168
135
 
169
- mode = 'pending';
136
+ state.mode = 'pending';
170
137
 
171
- var create_pending = () => {
172
- pending_branch = boundary_fn_running_block(() => {
173
- /** @type {PendingFunction} */ (pending_fn)(anchor);
174
- });
175
- };
138
+ var create_pending = () => {
139
+ state.pending_branch = boundary_branch(() => {
140
+ /** @type {TryPendingFunction} */ (state.pending_fn)(state.anchor);
141
+ });
142
+ };
176
143
 
177
- // with_block ensures the branch is parented under the TRY_BLOCK when called
178
- // from async contexts (microtasks) where active_block is null. During synchronous
179
- // execution (try_block not yet assigned), active_block is already the TRY_BLOCK.
180
- if (try_block !== null && !is_destroyed(try_block) && active_block !== try_block) {
181
- with_block(try_block, create_pending);
182
- } else {
183
- create_pending();
184
- }
144
+ // with_block ensures the branch is parented under the TRY_BLOCK when called
145
+ // from async contexts (microtasks) where active_block is null. During synchronous
146
+ // execution (try_block not yet assigned), active_block is already the TRY_BLOCK.
147
+ if (
148
+ state.try_block !== null &&
149
+ !is_destroyed(state.try_block) &&
150
+ active_block !== state.try_block
151
+ ) {
152
+ with_block(state.try_block, create_pending);
153
+ } else {
154
+ create_pending();
185
155
  }
156
+ }
186
157
 
187
- function destroy_pending() {
188
- if (pending_branch !== null && !is_destroyed(pending_branch)) {
189
- destroy_block(pending_branch);
190
- }
191
- pending_branch = null;
158
+ /** @param {TryState} state */
159
+ function destroy_pending(state) {
160
+ if (state.pending_branch !== null && !is_destroyed(state.pending_branch)) {
161
+ destroy_block(state.pending_branch);
192
162
  }
163
+ state.pending_branch = null;
164
+ }
193
165
 
194
- /**
195
- * @param {any} error
196
- * @returns {void}
197
- */
198
- function handle_error(error) {
199
- if (mode === 'catch') {
200
- // we don't want to do this again and render catch block again
201
- return;
202
- }
203
- pending_count = 0;
204
- active_requests.clear();
205
- clear_paused_blocks();
206
-
207
- // Reject all pending deferred promises so dependent async tracked settle
208
- // handlers fire and clean up. The settle will see the request already
209
- // cleared and skip error routing, avoiding double-catch.
210
- if (pending_deferreds.size > 0) {
211
- for (var [, reject_fn] of pending_deferreds) {
212
- reject_fn(error);
213
- }
214
- pending_deferreds.clear();
215
- }
166
+ /**
167
+ * @param {TryState} state
168
+ * @param {any} error
169
+ * @returns {void}
170
+ */
171
+ function handle_error(state, error) {
172
+ if (state.mode === 'catch') {
173
+ // we don't want to do this again and render catch block again
174
+ return;
175
+ }
176
+ state.pending_count = 0;
177
+ state.active_requests.clear();
178
+ clear_paused_blocks(state);
179
+
180
+ // Reject all pending deferred promises so dependent async tracked settle
181
+ // handlers fire and clean up. The settle will see the request already
182
+ // cleared and skip error routing, avoiding double-catch.
183
+ if (state.pending_deferreds.size > 0) {
184
+ for (var [, reject_fn] of state.pending_deferreds) {
185
+ reject_fn(error);
186
+ }
187
+ state.pending_deferreds.clear();
188
+ }
216
189
 
217
- if (mode === 'pending') {
218
- destroy_pending();
219
- } else if (mode === 'resolved') {
220
- move_resolved_offscreen();
221
- }
190
+ if (state.mode === 'pending') {
191
+ destroy_pending(state);
192
+ } else if (state.mode === 'resolved') {
193
+ move_resolved_offscreen(state);
194
+ }
222
195
 
223
- mode = 'catch';
196
+ state.mode = 'catch';
224
197
 
225
- var create_catch = () => {
226
- catch_branch = boundary_fn_running_block(() => {
227
- /** @type {CatchFunction} */ (catch_fn)(anchor, error, render_resolved);
228
- });
229
- };
198
+ var create_catch = () => {
199
+ state.catch_branch = boundary_branch(() => {
200
+ /** @type {TryCatchFunction} */ (state.catch_fn)(
201
+ state.anchor,
202
+ error,
203
+ (state.reset ??= () => render_resolved(state)),
204
+ );
205
+ });
206
+ };
230
207
 
231
- // with_block ensures the branch is parented under the TRY_BLOCK when called
232
- // from async contexts where active_block is null. During synchronous
233
- // execution (try_block not yet assigned), active_block is already the TRY_BLOCK.
234
- if (try_block !== null && !is_destroyed(try_block) && active_block !== try_block) {
235
- with_block(try_block, create_catch);
236
- } else {
237
- create_catch();
238
- }
208
+ // with_block ensures the branch is parented under the TRY_BLOCK when called
209
+ // from async contexts where active_block is null. During synchronous
210
+ // execution (try_block not yet assigned), active_block is already the TRY_BLOCK.
211
+ if (
212
+ state.try_block !== null &&
213
+ !is_destroyed(state.try_block) &&
214
+ active_block !== state.try_block
215
+ ) {
216
+ with_block(state.try_block, create_catch);
217
+ } else {
218
+ create_catch();
219
+ }
239
220
 
240
- destroy_resolved();
241
- }
242
-
243
- /**
244
- * Retires the slot wrapper markers once the slot's fate is decided: the
245
- * open comment loses its marker data (it may still serve as the boundary
246
- * anchor, so it must stay in the DOM) and the close comment is dropped —
247
- * keeping `[`/`]` depth balanced for scans over surrounding slots.
248
- * @returns {void}
249
- */
250
- function neutralize_slot_markers() {
251
- /** @type {Comment} */ (slot_open).data = '';
252
- /** @type {ChildNode} */ (slot_close).remove();
253
- }
254
-
255
- /**
256
- * Reads the streamed unit error envelope for this slot and routes the
257
- * error into this boundary, or the nearest catch boundary above it.
258
- * @param {string} id
259
- * @returns {void}
260
- */
261
- function route_streamed_error(id) {
262
- if (try_block === null || is_destroyed(try_block)) {
263
- return;
221
+ destroy_resolved(state);
222
+ }
223
+
224
+ /**
225
+ * Retires the slot wrapper markers once the slot's fate is decided: the
226
+ * open comment loses its marker data (it may still serve as the boundary
227
+ * anchor, so it must stay in the DOM) and the close comment is dropped —
228
+ * keeping `[`/`]` depth balanced for scans over surrounding slots.
229
+ * @param {TryState} state
230
+ * @returns {void}
231
+ */
232
+ function neutralize_slot_markers(state) {
233
+ /** @type {Comment} */ (state.slot_open).data = '';
234
+ /** @type {ChildNode} */ (state.slot_close).remove();
235
+ }
236
+
237
+ /**
238
+ * Reads the streamed unit error envelope for this slot and routes the
239
+ * error into this boundary, or the nearest catch boundary above it.
240
+ * @param {TryState} state
241
+ * @param {string} id
242
+ * @returns {void}
243
+ */
244
+ function route_streamed_error(state, id) {
245
+ if (state.try_block === null || is_destroyed(state.try_block)) {
246
+ return;
247
+ }
248
+ neutralize_slot_markers(state);
249
+ var message = 'An error occurred during server rendering';
250
+ var script = document.getElementById(STREAM_ERROR_SCRIPT_PREFIX + id);
251
+ if (script !== null) {
252
+ try {
253
+ message = JSON.parse(/** @type {string} */ (script.textContent)).message ?? message;
254
+ } catch {
255
+ // keep the generic message
264
256
  }
265
- neutralize_slot_markers();
266
- var message = 'An error occurred during server rendering';
267
- var script = document.getElementById(STREAM_ERROR_SCRIPT_PREFIX + id);
268
- if (script !== null) {
269
- try {
270
- message = JSON.parse(/** @type {string} */ (script.textContent)).message ?? message;
271
- } catch {
272
- // keep the generic message
257
+ script.remove();
258
+ }
259
+ var error = new Error(message);
260
+ if (state.catch_fn !== null) {
261
+ handle_error(state, error);
262
+ return;
263
+ }
264
+ var outer = get_boundary_with_catch(/** @type {Block} */ (state.try_block));
265
+ if (outer === null) {
266
+ throw error;
267
+ }
268
+ handle_error(outer.s, error);
269
+ }
270
+
271
+ /**
272
+ * Empties the streamed slot: destroys the hydrated fallback branch and
273
+ * sweeps whatever remains between the wrapper comments (leftover marker
274
+ * comments included).
275
+ * @param {TryState} state
276
+ * @returns {void}
277
+ */
278
+ function clear_streamed_slot(state) {
279
+ destroy_pending(state);
280
+ var node = /** @type {ChildNode} */ (state.slot_open).nextSibling;
281
+ while (node !== null && node !== state.slot_close) {
282
+ var next = node.nextSibling;
283
+ /** @type {ChildNode} */ (node).remove();
284
+ node = next;
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Called by the inline stream runtime when this slot's chunk arrives after
290
+ * hydration: swaps the fallback for the streamed content and claims the
291
+ * new DOM through a boundary-scoped hydration walk (trackAsync inside the
292
+ * body picks its serialized envelope up from the same chunk).
293
+ * @param {TryState} state
294
+ * @param {HTMLTemplateElement | null} template
295
+ * @param {number | undefined} [errored]
296
+ * @returns {void}
297
+ */
298
+ function activate_streamed_chunk(state, template, errored) {
299
+ if (state.try_block === null || is_destroyed(state.try_block)) {
300
+ return;
301
+ }
302
+ var id = /** @type {string} */ (state.streamed_id);
303
+ state.streamed_id = null;
304
+ if (errored) {
305
+ clear_streamed_slot(state);
306
+ route_streamed_error(state, id);
307
+ return;
308
+ }
309
+ clear_streamed_slot(state);
310
+ if (template !== null) {
311
+ /** @type {ChildNode} */ (state.slot_close).before(template.content);
312
+ }
313
+ var first = /** @type {ChildNode} */ (state.slot_open).nextSibling;
314
+ if (first === null || first === state.slot_close) {
315
+ neutralize_slot_markers(state);
316
+ return;
317
+ }
318
+ // adopt the streamed body's own <!--[--> as the boundary anchor (the
319
+ // node the buffered-SSR hydration path would have used) and drop the
320
+ // slot wrapper comments, so the resulting DOM matches buffered SSR
321
+ // exactly like the pre-hydration swap path does
322
+ if (state.anchor === state.slot_open) {
323
+ state.anchor = first;
324
+ }
325
+ /** @type {ChildNode} */ (state.slot_open).remove();
326
+ /** @type {ChildNode} */ (state.slot_close).remove();
327
+ var previous_hydrating = hydrating;
328
+ var previous_hydrate_node = hydrate_node;
329
+ set_hydration(true, first);
330
+ hydrate_next(); // consume the streamed body's <!--[-->
331
+ try {
332
+ state.has_resolved = true;
333
+ render_resolved(state);
334
+ } finally {
335
+ set_hydration(previous_hydrating, previous_hydrate_node);
336
+ }
337
+ }
338
+
339
+ /** @param {TryState} state */
340
+ function begin_request(state) {
341
+ var request_id = ++state.request_version;
342
+ state.active_requests.add(request_id);
343
+
344
+ if (state.pending_count++ === 0 && state.pending_fn !== null && !state.has_resolved) {
345
+ queue_microtask(() => {
346
+ if (
347
+ state.try_block !== null &&
348
+ !is_destroyed(state.try_block) &&
349
+ state.pending_count > 0 &&
350
+ !state.has_resolved
351
+ ) {
352
+ render_pending(state);
273
353
  }
274
- script.remove();
275
- }
276
- var error = new Error(message);
277
- if (catch_fn !== null) {
278
- handle_error(error);
279
- return;
280
- }
281
- var outer = get_boundary_with_catch(/** @type {Block} */ (try_block));
282
- if (outer === null) {
283
- throw error;
284
- }
285
- outer.s.c(error);
286
- }
287
-
288
- /**
289
- * Empties the streamed slot: destroys the hydrated fallback branch and
290
- * sweeps whatever remains between the wrapper comments (leftover marker
291
- * comments included).
292
- * @returns {void}
293
- */
294
- function clear_streamed_slot() {
295
- destroy_pending();
296
- var node = /** @type {ChildNode} */ (slot_open).nextSibling;
297
- while (node !== null && node !== slot_close) {
298
- var next = node.nextSibling;
299
- /** @type {ChildNode} */ (node).remove();
300
- node = next;
301
- }
354
+ });
302
355
  }
303
356
 
304
- /**
305
- * Called by the inline stream runtime when this slot's chunk arrives after
306
- * hydration: swaps the fallback for the streamed content and claims the
307
- * new DOM through a boundary-scoped hydration walk (trackAsync inside the
308
- * body picks its serialized envelope up from the same chunk).
309
- * @param {HTMLTemplateElement | null} template
310
- * @param {number | undefined} [errored]
311
- * @returns {void}
312
- */
313
- function activate_streamed_chunk(template, errored) {
314
- if (try_block === null || is_destroyed(try_block)) {
315
- return;
316
- }
317
- var id = /** @type {string} */ (streamed_id);
318
- streamed_id = null;
319
- if (errored) {
320
- clear_streamed_slot();
321
- route_streamed_error(id);
322
- return;
323
- }
324
- clear_streamed_slot();
325
- if (template !== null) {
326
- /** @type {ChildNode} */ (slot_close).before(template.content);
327
- }
328
- var first = /** @type {ChildNode} */ (slot_open).nextSibling;
329
- if (first === null || first === slot_close) {
330
- neutralize_slot_markers();
331
- return;
332
- }
333
- // adopt the streamed body's own <!--[--> as the boundary anchor (the
334
- // node the buffered-SSR hydration path would have used) and drop the
335
- // slot wrapper comments, so the resulting DOM matches buffered SSR
336
- // exactly like the pre-hydration swap path does
337
- if (anchor === slot_open) {
338
- anchor = first;
339
- }
340
- /** @type {ChildNode} */ (slot_open).remove();
341
- /** @type {ChildNode} */ (slot_close).remove();
342
- var previous_hydrating = hydrating;
343
- var previous_hydrate_node = hydrate_node;
344
- set_hydrating(true);
345
- set_hydrate_node(first);
346
- hydrate_next(); // consume the streamed body's <!--[-->
347
- try {
348
- has_resolved = true;
349
- render_resolved();
350
- } finally {
351
- set_hydrating(previous_hydrating);
352
- set_hydrate_node(previous_hydrate_node, true);
353
- }
357
+ return request_id;
358
+ }
359
+
360
+ /**
361
+ * @param {TryState} state
362
+ * @param {number} old_request_id
363
+ * @returns {number}
364
+ */
365
+ function replace_request(state, old_request_id) {
366
+ state.active_requests.delete(old_request_id);
367
+ state.pending_deferreds.delete(old_request_id);
368
+ // pending_count unchanged — one out, one in
369
+ var request_id = ++state.request_version;
370
+ state.active_requests.add(request_id);
371
+ return request_id;
372
+ }
373
+
374
+ /**
375
+ * @param {TryState} state
376
+ * @param {number} request_id
377
+ * @param {boolean} [show_resolved_branch=true]
378
+ * @returns {boolean}
379
+ */
380
+ function complete_request(state, request_id, show_resolved_branch = true) {
381
+ if (!state.active_requests.delete(request_id)) {
382
+ return false;
354
383
  }
355
384
 
356
- function begin_request() {
357
- var request_id = ++request_version;
358
- active_requests.add(request_id);
385
+ state.pending_deferreds.delete(request_id);
359
386
 
360
- if (pending_count++ === 0 && pending_fn !== null && !has_resolved) {
361
- queue_microtask(() => {
362
- if (try_block !== null && !is_destroyed(try_block) && pending_count > 0 && !has_resolved) {
363
- render_pending();
364
- }
365
- });
366
- }
387
+ state.pending_count--;
367
388
 
368
- return request_id;
369
- }
370
-
371
- /**
372
- * @param {number} old_request_id
373
- * @returns {number}
374
- */
375
- function replace_request(old_request_id) {
376
- active_requests.delete(old_request_id);
377
- pending_deferreds.delete(old_request_id);
378
- // pending_count unchanged — one out, one in
379
- var request_id = ++request_version;
380
- active_requests.add(request_id);
381
- return request_id;
382
- }
383
-
384
- /**
385
- * @param {number} request_id
386
- * @param {boolean} [show_resolved_branch=true]
387
- * @returns {boolean}
388
- */
389
- function complete_request(request_id, show_resolved_branch = true) {
390
- if (!active_requests.delete(request_id)) {
391
- return false;
389
+ if (state.pending_count === 0) {
390
+ if (!show_resolved_branch) {
391
+ clear_paused_blocks(state);
392
+ return true;
392
393
  }
393
394
 
394
- pending_deferreds.delete(request_id);
395
+ resume_paused_blocks(state);
395
396
 
396
- pending_count--;
397
+ queue_post_block_flush_callback(() => {
398
+ // run this only after the blocks have a chance to run
399
+ // and find more pending requests (and pause themselves) before we are
400
+ // certain to render the resolved state.
401
+ // Otherwise, we'll have multiple renders.
402
+ if (state.try_block === null || is_destroyed(state.try_block) || state.pending_count > 0) {
403
+ return;
404
+ }
397
405
 
398
- if (pending_count === 0) {
399
- if (!show_resolved_branch) {
400
- clear_paused_blocks();
401
- return true;
406
+ if (state.mode === 'pending') {
407
+ destroy_pending(state);
408
+ show_resolved_fragment(state);
402
409
  }
403
410
 
404
- resume_paused_blocks();
411
+ state.has_resolved = true;
412
+ state.mode = 'resolved';
413
+ });
414
+ // this is more just in case here and shouldn't really cause anything to run
415
+ // most likely the scheduling is already there
416
+ // leaving it here in case there are some weird edge cases
417
+ queue_microtask();
418
+ }
405
419
 
406
- queue_post_block_flush_callback(() => {
407
- // run this only after the blocks have a chance to run
408
- // and find more pending requests (and pause themselves) before we are
409
- // certain to render the resolved state.
410
- // Otherwise, we'll have multiple renders.
411
- if (try_block === null || is_destroyed(try_block) || pending_count > 0) {
412
- return;
413
- }
420
+ return true;
421
+ }
414
422
 
415
- if (mode === 'pending') {
416
- destroy_pending();
417
- show_resolved_fragment();
418
- }
423
+ /**
424
+ * @param {TryState} state
425
+ * @param {Comment} marker
426
+ * @param {string} data
427
+ */
428
+ function hydrate_streamed_slot(state, marker, data) {
429
+ // live streamed slot
430
+ state.streamed_id = data.slice(HYDRATION_START_PENDING.length);
431
+ state.streamed_errored = data.startsWith(HYDRATION_START_ERRORED);
432
+ state.slot_open = marker;
433
+ hydrate_next(); // consume the slot wrapper open
434
+ state.slot_close = /** @type {Comment} */ (skip_to_hydration_end());
435
+ var fallback_start = /** @type {Comment} */ (hydrate_node);
436
+ state.streamed_fallback =
437
+ !state.streamed_errored &&
438
+ state.pending_fn !== null &&
439
+ fallback_start.nodeType === COMMENT_NODE &&
440
+ fallback_start.data === HYDRATION_START;
441
+ if (state.streamed_fallback) {
442
+ hydrate_next(); // consume the fallback's <!--[-->
443
+ }
444
+ }
419
445
 
420
- has_resolved = true;
421
- mode = 'resolved';
422
- });
423
- // this is more just in case here and shouldn't really cause anything to run
424
- // most likely the scheduling is already there
425
- // leaving it here in case there are some weird edge cases
426
- queue_microtask();
427
- }
446
+ /** @param {TryState} state */
447
+ function register_streamed_slot(state) {
448
+ // continue the outer hydration walk after the slot
449
+ set_hydrate_node(state.slot_close);
450
+
451
+ var registry = (window.__RIPPLE_B__ ??= {});
452
+ var unit_id = /** @type {string} */ (state.streamed_id);
453
+ if (state.streamed_errored) {
454
+ // the inline runtime already emptied the slot and marked it errored
455
+ // — route the error once the surrounding hydration has finished
456
+ queue_microtask(() => route_streamed_error(state, unit_id));
457
+ } else {
458
+ registry[unit_id] = {
459
+ a: (template, errored) => activate_streamed_chunk(state, template, errored),
460
+ };
461
+ }
462
+ }
428
463
 
429
- return true;
464
+ /** @param {TryState} state */
465
+ function hydrate_streamed_fallback(state) {
466
+ // The body has not arrived yet; hydrate its fallback until activation.
467
+ if (state.streamed_fallback) {
468
+ state.mode = 'pending';
469
+ state.pending_branch = boundary_branch(() => {
470
+ /** @type {TryPendingFunction} */ (state.pending_fn)(state.anchor);
471
+ });
430
472
  }
473
+ }
474
+
475
+ /** @param {TryState} state */
476
+ function run_try(state) {
477
+ if (state.streamed_id !== null) {
478
+ hydrate_streamed_fallback(state);
479
+ } else {
480
+ state.resolved_branch = boundary_branch(() => state.try_fn(state.anchor));
481
+ }
482
+ }
431
483
 
432
- /** @type {TryBoundaryState} */
484
+ /**
485
+ * @param {Node | AppendIntoAnchor} node
486
+ * @param {(anchor: Node, block?: Block) => void} try_fn
487
+ * @param {TryCatchFunction | null} catch_fn
488
+ * @param {TryPendingFunction | null} [pending_fn=null]
489
+ * @param {boolean} [root_controlled=false] When true the block renders before
490
+ * the component's `__anchor`, which may be an append-into sentinel (see
491
+ * `resolve_anchor`).
492
+ * @returns {void}
493
+ */
494
+ export function try_block(node, try_fn, catch_fn, pending_fn = null, root_controlled = false) {
495
+ /** @type {Node | undefined} */
496
+ var boundary;
497
+ /** @type {TryState} */
433
498
  var state = {
434
- p: pending_fn !== null,
435
- b: begin_request,
436
- r: complete_request,
437
- c: catch_fn !== null ? handle_error : null,
438
- /** @param {number} request_id @param {(reason: any) => void} reject_fn */
439
- rd: (request_id, reject_fn) => {
440
- pending_deferreds.set(request_id, reject_fn);
441
- },
442
- /** @param {Block} block */
443
- pb: (block) => {
444
- paused_blocks.add(block);
445
- },
446
- rp: replace_request,
499
+ anchor: root_controlled ? resolve_anchor(node) : /** @type {Node} */ (node),
500
+ try_fn,
501
+ catch_fn,
502
+ pending_fn,
503
+ reset: null,
504
+ pending_count: 0,
505
+ request_version: 0,
506
+ active_requests: new Set(),
507
+ try_block: null,
508
+ resolved_branch: null,
509
+ pending_branch: null,
510
+ catch_branch: null,
511
+ offscreen_fragment: null,
512
+ has_resolved: false,
513
+ mode: 'resolved',
514
+ pending_deferreds: new Map(),
515
+ paused_blocks: new Set(),
516
+ streamed_id: null,
517
+ streamed_errored: false,
518
+ streamed_fallback: false,
519
+ slot_open: null,
520
+ slot_close: null,
447
521
  };
448
522
 
449
523
  if (hydrating && (pending_fn !== null || catch_fn !== null)) {
450
- // Server wraps a settled try body with <!--[-->...<!--]--> markers when
451
- // pending or catch is present, and the boundary hydrates as resolved.
452
- // Streaming SSR instead emits a slot wrapper around the fallback:
453
- // <!--[?N--> while unit N's content is still on its way, or
454
- // <!--[!N--> when the unit errored after its region was already sent.
455
524
  if (root_controlled) {
456
525
  boundary = /** @type {Node} */ (hydrate_node);
457
526
  }
@@ -459,66 +528,26 @@ export function try_block(node, try_fn, catch_fn, pending_fn = null, root_contro
459
528
  var marker = /** @type {Comment} */ (hydrate_node);
460
529
  var data = marker.nodeType === COMMENT_NODE ? marker.data : '';
461
530
 
462
- // a slot marker at the boundary's own anchor always belongs to this
463
- // boundary — the root boundary included: when the root suspends, the
464
- // server emits its slot as the whole body, so the marker doubles as
465
- // the hydration anchor
531
+ // A slot at this anchor belongs to this boundary, including the root.
466
532
  if (data.startsWith(HYDRATION_START_PENDING) || data.startsWith(HYDRATION_START_ERRORED)) {
467
- // live streamed slot
468
- streamed_id = data.slice(HYDRATION_START_PENDING.length);
469
- streamed_errored = data.startsWith(HYDRATION_START_ERRORED);
470
- slot_open = marker;
471
- hydrate_next(); // consume the slot wrapper open
472
- slot_close = /** @type {Comment} */ (skip_to_hydration_end());
473
- var fallback_start = /** @type {Comment} */ (hydrate_node);
474
- streamed_fallback =
475
- !streamed_errored &&
476
- pending_fn !== null &&
477
- fallback_start.nodeType === COMMENT_NODE &&
478
- fallback_start.data === HYDRATION_START;
479
- if (streamed_fallback) {
480
- hydrate_next(); // consume the fallback's <!--[-->
481
- }
533
+ hydrate_streamed_slot(state, marker, data);
482
534
  } else {
483
- // settled content: mark as already resolved so begin_request's
484
- // microtask won't transition to pending
535
+ // Settled SSR content must not transition back to pending.
485
536
  if (pending_fn !== null) {
486
- has_resolved = true;
537
+ state.has_resolved = true;
487
538
  }
488
539
  hydrate_next(); // consume <!--[-->
489
540
  }
490
541
  }
491
542
 
492
- try_block = create_try_block(() => {
493
- if (streamed_id !== null) {
494
- // the streamed body hasn't arrived yet — hydrate the fallback (if
495
- // any) as the pending branch and wait for the chunk to activate us
496
- if (streamed_fallback) {
497
- mode = 'pending';
498
- pending_branch = boundary_fn_running_block(() => {
499
- /** @type {PendingFunction} */ (pending_fn)(anchor);
500
- });
501
- }
502
- return;
503
- }
504
- resolved_branch = boundary_fn_running_block(() => try_fn(anchor));
505
- }, state);
506
-
507
- if (streamed_id !== null) {
508
- // continue the outer hydration walk after the slot
509
- set_hydrate_node(slot_close);
510
-
511
- var registry = (window.__RIPPLE_B__ ??= {});
512
- var unit_id = streamed_id;
513
- if (streamed_errored) {
514
- // the inline runtime already emptied the slot and marked it errored
515
- // — route the error once the surrounding hydration has finished
516
- queue_microtask(() => route_streamed_error(unit_id));
517
- } else {
518
- registry[unit_id] = { a: activate_streamed_chunk };
519
- }
543
+ state.try_block = create_block(TRY_BLOCK, run_try, state);
544
+
545
+ if (state.streamed_id !== null) {
546
+ register_streamed_slot(state);
520
547
  }
521
548
 
549
+ own_anchor(node, state.anchor);
550
+
522
551
  if (hydrating && root_controlled) {
523
552
  append(/** @type {ChildNode} */ (node), /** @type {Node} */ (boundary));
524
553
  }
@@ -533,7 +562,7 @@ export function get_pending_boundary(block) {
533
562
 
534
563
  while (current !== null) {
535
564
  var state = /** @type {BlockWithTryBoundary} */ (current).s;
536
- if ((current.f & TRY_BLOCK) !== 0 && state.p) {
565
+ if ((current.f & TRY_BLOCK) !== 0 && state.pending_fn !== null) {
537
566
  return /** @type {BlockWithTryBoundary} */ (current);
538
567
  }
539
568
  current = current.p;
@@ -552,7 +581,7 @@ export function get_boundary_with_catch(block) {
552
581
 
553
582
  while (current !== null) {
554
583
  var state = /** @type {BlockWithTryBoundary} */ (current).s;
555
- if ((current.f & TRY_BLOCK) !== 0 && state.c !== null) {
584
+ if ((current.f & TRY_BLOCK) !== 0 && state.catch_fn !== null) {
556
585
  return /** @type {BlockWithTryBoundaryAndCatch} */ (current);
557
586
  }
558
587
  current = current.p;
@@ -561,12 +590,22 @@ export function get_boundary_with_catch(block) {
561
590
  return null;
562
591
  }
563
592
 
593
+ /**
594
+ * Routes an error into a boundary's catch branch.
595
+ * @param {BlockWithTryBoundaryAndCatch} boundary
596
+ * @param {any} error
597
+ * @returns {void}
598
+ */
599
+ export function handle_boundary_error(boundary, error) {
600
+ handle_error(boundary.s, error);
601
+ }
602
+
564
603
  /**
565
604
  * @param {BlockWithTryBoundary} boundary
566
605
  * @returns {number}
567
606
  */
568
607
  export function begin_boundary_request(boundary) {
569
- return boundary.s.b();
608
+ return begin_request(boundary.s);
570
609
  }
571
610
 
572
611
  /**
@@ -575,7 +614,7 @@ export function begin_boundary_request(boundary) {
575
614
  * @returns {number}
576
615
  */
577
616
  export function replace_boundary_request(boundary, old_request_id) {
578
- return boundary.s.rp(old_request_id);
617
+ return replace_request(boundary.s, old_request_id);
579
618
  }
580
619
 
581
620
  /**
@@ -586,7 +625,7 @@ export function replace_boundary_request(boundary, old_request_id) {
586
625
  */
587
626
  export function complete_boundary_request(boundary, request_id, show_resolved_branch = true) {
588
627
  return boundary !== null && !is_destroyed(boundary)
589
- ? boundary.s.r(request_id, show_resolved_branch)
628
+ ? complete_request(boundary.s, request_id, show_resolved_branch)
590
629
  : false;
591
630
  }
592
631
 
@@ -597,8 +636,8 @@ export function complete_boundary_request(boundary, request_id, show_resolved_br
597
636
  * @returns {void}
598
637
  */
599
638
  export function register_boundary_deferred(boundary, request_id, reject_fn) {
600
- if (boundary !== null && !is_destroyed(boundary) && boundary.s?.rd) {
601
- boundary.s.rd(request_id, reject_fn);
639
+ if (boundary !== null && !is_destroyed(boundary)) {
640
+ boundary.s.pending_deferreds.set(request_id, reject_fn);
602
641
  }
603
642
  }
604
643
 
@@ -608,7 +647,7 @@ export function register_boundary_deferred(boundary, request_id, reject_fn) {
608
647
  * @returns {void}
609
648
  */
610
649
  export function register_boundary_paused_block(boundary, block) {
611
- if (boundary !== null && !is_destroyed(boundary) && boundary.s?.pb) {
612
- boundary.s.pb(block);
650
+ if (boundary !== null && !is_destroyed(boundary)) {
651
+ boundary.s.paused_blocks.add(block);
613
652
  }
614
653
  }