ripple 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +164 -0
- package/package.json +10 -4
- package/src/constants.js +6 -0
- package/src/jsx-runtime.d.ts +2 -1
- package/src/runtime/array.js +15 -9
- package/src/runtime/index-client.js +25 -7
- package/src/runtime/index-server.js +1 -0
- package/src/runtime/internal/client/attributes.js +439 -0
- package/src/runtime/internal/client/blocks.js +20 -20
- package/src/runtime/internal/client/component.js +2 -5
- package/src/runtime/internal/client/composite.js +295 -95
- package/src/runtime/internal/client/constants.js +14 -6
- package/src/runtime/internal/client/context.js +3 -2
- package/src/runtime/internal/client/css.js +11 -26
- package/src/runtime/internal/client/errors.js +188 -0
- package/src/runtime/internal/client/events.js +79 -34
- package/src/runtime/internal/client/expression.js +25 -120
- package/src/runtime/internal/client/for.js +113 -262
- package/src/runtime/internal/client/head.js +4 -3
- package/src/runtime/internal/client/html.js +5 -3
- package/src/runtime/internal/client/hydrate.js +484 -0
- package/src/runtime/internal/client/hydration-enabled.js +7 -0
- package/src/runtime/internal/client/hydration.js +16 -81
- package/src/runtime/internal/client/if.js +69 -10
- package/src/runtime/internal/client/index.js +18 -10
- package/src/runtime/internal/client/operations.js +11 -7
- package/src/runtime/internal/client/portal.js +3 -2
- package/src/runtime/internal/client/render.js +42 -325
- package/src/runtime/internal/client/root-boundary-enabled.js +7 -0
- package/src/runtime/internal/client/runtime.js +157 -371
- package/src/runtime/internal/client/template-ns.js +88 -0
- package/src/runtime/internal/client/template.js +118 -139
- package/src/runtime/internal/client/track-async.js +356 -0
- package/src/runtime/internal/client/try.js +133 -319
- package/src/runtime/internal/client/types.d.ts +48 -24
- package/src/runtime/internal/server/index.js +31 -29
- package/src/runtime/internal/server/prerender.js +27 -0
- package/src/server/index.js +1 -0
- package/src/utils/class-name.js +28 -0
- package/tests/client/basic/basic.errors.test.tsrx +3 -3
- package/tests/client/compiler/__snapshots__/compiler.typescript.test.tsrx.snap +0 -2
- package/tests/client/compiler/compiler.basic.test.tsrx +2 -2
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +3 -3
- package/tests/client/composite/composite.dynamic-components.test.tsrx +40 -0
- package/tests/client/composite/composite.props.test.tsrx +10 -10
- package/tests/client/css/scoped-styles.test.tsrx +3 -1
- package/tests/client/derived-release.test.tsrx +3 -3
- package/tests/client/for-item.test.tsrx +39 -0
- package/tests/client/for-selector.test.tsrx +95 -0
- package/tests/client/svg.test.tsrx +273 -1
- package/tests/hydration/compiled/client/basic.js +88 -87
- package/tests/hydration/compiled/client/composite.js +15 -6
- package/tests/hydration/compiled/client/events.js +40 -48
- package/tests/hydration/compiled/client/for.js +191 -199
- package/tests/hydration/compiled/client/fragment-cursor.js +633 -334
- package/tests/hydration/compiled/client/head.js +22 -22
- package/tests/hydration/compiled/client/hmr.js +14 -5
- package/tests/hydration/compiled/client/html-in-template.js +5 -5
- package/tests/hydration/compiled/client/html.js +195 -177
- package/tests/hydration/compiled/client/if-children.js +136 -63
- package/tests/hydration/compiled/client/if-fragment-controlflow.js +63 -43
- package/tests/hydration/compiled/client/if.js +78 -30
- package/tests/hydration/compiled/client/mixed-control-flow.js +90 -72
- package/tests/hydration/compiled/client/nested-control-flow.js +266 -307
- package/tests/hydration/compiled/client/portal.js +20 -11
- package/tests/hydration/compiled/client/reactivity.js +29 -29
- package/tests/hydration/compiled/client/return.js +2 -2
- package/tests/hydration/compiled/client/streaming.js +33 -35
- package/tests/hydration/compiled/client/switch.js +25 -25
- package/tests/hydration/compiled/client/track-async-serialization.js +41 -41
- package/tests/hydration/compiled/client/try.js +15 -15
- package/tests/hydration/compiled/client/typed-text.js +8 -7
- package/tests/hydration/compiled/server/basic.js +6 -6
- package/tests/hydration/compiled/server/events.js +8 -8
- package/tests/hydration/compiled/server/for.js +22 -22
- package/tests/hydration/compiled/server/fragment-cursor.js +188 -52
- package/tests/hydration/compiled/server/head.js +6 -6
- package/tests/hydration/compiled/server/hmr.js +1 -1
- package/tests/hydration/compiled/server/html.js +1 -1
- package/tests/hydration/compiled/server/if-children.js +9 -9
- package/tests/hydration/compiled/server/if.js +5 -5
- package/tests/hydration/compiled/server/mixed-control-flow.js +4 -4
- package/tests/hydration/compiled/server/portal.js +1 -1
- package/tests/hydration/compiled/server/reactivity.js +9 -9
- package/tests/hydration/compiled/server/streaming.js +9 -9
- package/tests/hydration/compiled/server/switch.js +4 -4
- package/tests/hydration/compiled/server/track-async-serialization.js +16 -16
- package/tests/hydration/compiled/server/try.js +4 -4
- package/tests/hydration/compiled/server/typed-text.js +1 -1
- package/tests/hydration/components/fragment-cursor.tsrx +60 -0
- package/tests/hydration/components/track-async-serialization.tsrx +2 -2
- package/tests/hydration/fragment-cursor.test.js +34 -1
- package/tests/hydration/track-async-serialization.test.js +1 -1
- package/tests/server/basic.components.test.tsrx +3 -3
- package/tests/server/track-async-serialization.test.tsrx +6 -6
- package/tests/utils/tracked-types.test.js +3 -3
- package/types/index.d.ts +8 -8
- package/types/server.d.ts +17 -0
|
@@ -9,43 +9,48 @@ import {
|
|
|
9
9
|
resume_block,
|
|
10
10
|
} from './blocks.js';
|
|
11
11
|
import { BRANCH_BLOCK, DIRECT_CHILD_BLOCK, TRY_BLOCK } from './constants.js';
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
HYDRATION_START,
|
|
15
|
-
HYDRATION_START_PENDING,
|
|
16
|
-
HYDRATION_START_ERRORED,
|
|
17
|
-
STREAM_ERROR_SCRIPT_PREFIX,
|
|
18
|
-
} from '../../../constants.js';
|
|
19
|
-
import {
|
|
20
|
-
hydrate_next,
|
|
21
|
-
hydrate_node,
|
|
22
|
-
hydrating,
|
|
23
|
-
set_hydrate_node,
|
|
24
|
-
set_hydration,
|
|
25
|
-
skip_to_hydration_end,
|
|
26
|
-
} from './hydration.js';
|
|
12
|
+
import { H, hydrate_node, hydrating } from './hydration.js';
|
|
13
|
+
import { HYDRATION } from 'ripple/internal/client/hydration-enabled';
|
|
27
14
|
import { resolve_anchor } from './operations.js';
|
|
28
15
|
import { append } from './template.js';
|
|
29
16
|
import {
|
|
30
17
|
active_block,
|
|
31
18
|
queue_microtask,
|
|
32
19
|
queue_post_block_flush_callback,
|
|
20
|
+
set_catch_router,
|
|
33
21
|
with_block,
|
|
34
22
|
} from './runtime.js';
|
|
35
23
|
|
|
24
|
+
var installed = false;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The runtime's catch routing: the nearest boundary above `block` with a
|
|
28
|
+
* catch branch takes the error, or null leaves it to the caller.
|
|
29
|
+
* @param {unknown} error
|
|
30
|
+
* @param {Block} block
|
|
31
|
+
* @returns {BlockWithTryBoundaryAndCatch | null}
|
|
32
|
+
*/
|
|
33
|
+
function route_error(error, block) {
|
|
34
|
+
var boundary = get_boundary_with_catch(block);
|
|
35
|
+
if (boundary !== null) {
|
|
36
|
+
catch_error(boundary.s, error);
|
|
37
|
+
}
|
|
38
|
+
return boundary;
|
|
39
|
+
}
|
|
40
|
+
|
|
36
41
|
/**
|
|
37
42
|
* A boundary's branches run as direct children of its try block (see
|
|
38
43
|
* `TryState` in types.d.ts for the state they share).
|
|
39
44
|
* @param {() => void} fn
|
|
40
45
|
* @returns {Block}
|
|
41
46
|
*/
|
|
42
|
-
function boundary_branch(fn) {
|
|
47
|
+
export function boundary_branch(fn) {
|
|
43
48
|
return create_block(BRANCH_BLOCK | DIRECT_CHILD_BLOCK, fn);
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
/** @param {TryState} state */
|
|
47
52
|
function clear_paused_blocks(state) {
|
|
48
|
-
state.
|
|
53
|
+
state.z.clear();
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
/**
|
|
@@ -53,12 +58,12 @@ function clear_paused_blocks(state) {
|
|
|
53
58
|
* @returns {boolean}
|
|
54
59
|
*/
|
|
55
60
|
function resume_paused_blocks(state) {
|
|
56
|
-
if (state.
|
|
61
|
+
if (state.z.size === 0) {
|
|
57
62
|
return false;
|
|
58
63
|
}
|
|
59
64
|
|
|
60
|
-
var blocks = state.
|
|
61
|
-
state.
|
|
65
|
+
var blocks = state.z;
|
|
66
|
+
state.z = new Set();
|
|
62
67
|
var resumed = false;
|
|
63
68
|
|
|
64
69
|
for (var block of blocks) {
|
|
@@ -73,134 +78,128 @@ function resume_paused_blocks(state) {
|
|
|
73
78
|
|
|
74
79
|
/** @param {TryState} state */
|
|
75
80
|
function show_resolved_fragment(state) {
|
|
76
|
-
if (state.
|
|
77
|
-
/** @type {ChildNode} */ (state.
|
|
78
|
-
state.
|
|
81
|
+
if (state.o !== null) {
|
|
82
|
+
/** @type {ChildNode} */ (state.a).before(state.o);
|
|
83
|
+
state.o = null;
|
|
79
84
|
}
|
|
80
85
|
|
|
81
|
-
state.
|
|
82
|
-
state.
|
|
86
|
+
state.h = true;
|
|
87
|
+
state.m = 0;
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
/** @param {TryState} state */
|
|
86
|
-
function render_resolved(state) {
|
|
87
|
-
if (
|
|
88
|
-
state.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
) {
|
|
92
|
-
if (state.catch_branch !== null) {
|
|
93
|
-
destroy_block(state.catch_branch);
|
|
94
|
-
state.catch_branch = null;
|
|
91
|
+
export function render_resolved(state) {
|
|
92
|
+
if (state.b !== null && !is_destroyed(state.b) && (state.rb === null || is_destroyed(state.rb))) {
|
|
93
|
+
if (state.cb !== null) {
|
|
94
|
+
destroy_block(state.cb);
|
|
95
|
+
state.cb = null;
|
|
95
96
|
}
|
|
96
|
-
state.
|
|
97
|
-
if (active_block !== state.
|
|
98
|
-
with_block(state.
|
|
99
|
-
state.
|
|
97
|
+
state.m = 0;
|
|
98
|
+
if (active_block !== state.b) {
|
|
99
|
+
with_block(state.b, () => {
|
|
100
|
+
state.rb = boundary_branch(() => state.fn(state.a));
|
|
100
101
|
});
|
|
101
102
|
} else {
|
|
102
|
-
state.
|
|
103
|
+
state.rb = boundary_branch(() => state.fn(state.a));
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
/** @param {TryState} state */
|
|
108
109
|
function destroy_resolved(state) {
|
|
109
|
-
if (state.
|
|
110
|
-
destroy_block(state.
|
|
110
|
+
if (state.rb !== null && !is_destroyed(state.rb)) {
|
|
111
|
+
destroy_block(state.rb);
|
|
111
112
|
}
|
|
112
|
-
state.
|
|
113
|
-
state.
|
|
113
|
+
state.rb = null;
|
|
114
|
+
state.o = null;
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
/** @param {TryState} state */
|
|
117
118
|
function move_resolved_offscreen(state) {
|
|
118
|
-
if (state.
|
|
119
|
-
if (!state.
|
|
119
|
+
if (state.rb !== null) {
|
|
120
|
+
if (!state.o) {
|
|
120
121
|
// if offcreen_fragment exists, it means the resolved_branch is already offscreen,
|
|
121
122
|
// so we can skip moving it again
|
|
122
|
-
state.
|
|
123
|
-
move_block(state.
|
|
123
|
+
state.o = document.createDocumentFragment();
|
|
124
|
+
move_block(state.rb, state.o);
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
/** @param {TryState} state */
|
|
129
130
|
function render_pending(state) {
|
|
130
|
-
if (state.
|
|
131
|
+
if (state.p === null || state.m === 1) {
|
|
131
132
|
return;
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
move_resolved_offscreen(state);
|
|
135
136
|
|
|
136
|
-
state.
|
|
137
|
+
state.m = 1;
|
|
137
138
|
|
|
138
139
|
var create_pending = () => {
|
|
139
|
-
state.
|
|
140
|
-
/** @type {TryPendingFunction} */ (state.
|
|
140
|
+
state.pb = boundary_branch(() => {
|
|
141
|
+
/** @type {TryPendingFunction} */ (state.p)(state.a);
|
|
141
142
|
});
|
|
142
143
|
};
|
|
143
144
|
|
|
144
145
|
// with_block ensures the branch is parented under the TRY_BLOCK when called
|
|
145
146
|
// from async contexts (microtasks) where active_block is null. During synchronous
|
|
146
147
|
// execution (try_block not yet assigned), active_block is already the TRY_BLOCK.
|
|
147
|
-
if (
|
|
148
|
-
state.
|
|
149
|
-
!is_destroyed(state.try_block) &&
|
|
150
|
-
active_block !== state.try_block
|
|
151
|
-
) {
|
|
152
|
-
with_block(state.try_block, create_pending);
|
|
148
|
+
if (state.b !== null && !is_destroyed(state.b) && active_block !== state.b) {
|
|
149
|
+
with_block(state.b, create_pending);
|
|
153
150
|
} else {
|
|
154
151
|
create_pending();
|
|
155
152
|
}
|
|
156
153
|
}
|
|
157
154
|
|
|
158
155
|
/** @param {TryState} state */
|
|
159
|
-
function destroy_pending(state) {
|
|
160
|
-
if (state.
|
|
161
|
-
destroy_block(state.
|
|
156
|
+
export function destroy_pending(state) {
|
|
157
|
+
if (state.pb !== null && !is_destroyed(state.pb)) {
|
|
158
|
+
destroy_block(state.pb);
|
|
162
159
|
}
|
|
163
|
-
state.
|
|
160
|
+
state.pb = null;
|
|
164
161
|
}
|
|
165
162
|
|
|
166
163
|
/**
|
|
164
|
+
* Routes an error into a boundary: its catch branch renders in place of the
|
|
165
|
+
* content, which is kept offscreen for `reset`.
|
|
167
166
|
* @param {TryState} state
|
|
168
167
|
* @param {any} error
|
|
169
168
|
* @returns {void}
|
|
170
169
|
*/
|
|
171
|
-
function
|
|
172
|
-
if (state.
|
|
170
|
+
export function catch_error(state, error) {
|
|
171
|
+
if (state.m === 2) {
|
|
173
172
|
// we don't want to do this again and render catch block again
|
|
174
173
|
return;
|
|
175
174
|
}
|
|
176
|
-
state.
|
|
177
|
-
state.
|
|
175
|
+
state.n = 0;
|
|
176
|
+
state.q.clear();
|
|
178
177
|
clear_paused_blocks(state);
|
|
179
178
|
|
|
180
179
|
// Reject all pending deferred promises so dependent async tracked settle
|
|
181
180
|
// handlers fire and clean up. The settle will see the request already
|
|
182
181
|
// cleared and skip error routing, avoiding double-catch.
|
|
183
|
-
if (state.
|
|
184
|
-
for (var [, reject_fn] of state.
|
|
182
|
+
if (state.d.size > 0) {
|
|
183
|
+
for (var [, reject_fn] of state.d) {
|
|
185
184
|
reject_fn(error);
|
|
186
185
|
}
|
|
187
|
-
state.
|
|
186
|
+
state.d.clear();
|
|
188
187
|
}
|
|
189
188
|
|
|
190
|
-
if (state.
|
|
189
|
+
if (state.m === 1) {
|
|
191
190
|
destroy_pending(state);
|
|
192
|
-
} else if (state.
|
|
191
|
+
} else if (state.m === 0) {
|
|
193
192
|
move_resolved_offscreen(state);
|
|
194
193
|
}
|
|
195
194
|
|
|
196
|
-
state.
|
|
195
|
+
state.m = 2;
|
|
197
196
|
|
|
198
197
|
var create_catch = () => {
|
|
199
|
-
state.
|
|
200
|
-
/** @type {TryCatchFunction} */ (state.
|
|
201
|
-
state.
|
|
198
|
+
state.cb = boundary_branch(() => {
|
|
199
|
+
/** @type {TryCatchFunction} */ (state.c)(
|
|
200
|
+
state.a,
|
|
202
201
|
error,
|
|
203
|
-
(state.
|
|
202
|
+
(state.r ??= () => render_resolved(state)),
|
|
204
203
|
);
|
|
205
204
|
});
|
|
206
205
|
};
|
|
@@ -208,12 +207,8 @@ function handle_error(state, error) {
|
|
|
208
207
|
// with_block ensures the branch is parented under the TRY_BLOCK when called
|
|
209
208
|
// from async contexts where active_block is null. During synchronous
|
|
210
209
|
// execution (try_block not yet assigned), active_block is already the TRY_BLOCK.
|
|
211
|
-
if (
|
|
212
|
-
state.
|
|
213
|
-
!is_destroyed(state.try_block) &&
|
|
214
|
-
active_block !== state.try_block
|
|
215
|
-
) {
|
|
216
|
-
with_block(state.try_block, create_catch);
|
|
210
|
+
if (state.b !== null && !is_destroyed(state.b) && active_block !== state.b) {
|
|
211
|
+
with_block(state.b, create_catch);
|
|
217
212
|
} else {
|
|
218
213
|
create_catch();
|
|
219
214
|
}
|
|
@@ -221,134 +216,14 @@ function handle_error(state, error) {
|
|
|
221
216
|
destroy_resolved(state);
|
|
222
217
|
}
|
|
223
218
|
|
|
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
|
|
256
|
-
}
|
|
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
219
|
/** @param {TryState} state */
|
|
340
220
|
function begin_request(state) {
|
|
341
|
-
var request_id = ++state.
|
|
342
|
-
state.
|
|
221
|
+
var request_id = ++state.v;
|
|
222
|
+
state.q.add(request_id);
|
|
343
223
|
|
|
344
|
-
if (state.
|
|
224
|
+
if (state.n++ === 0 && state.p !== null && !state.h) {
|
|
345
225
|
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
|
-
) {
|
|
226
|
+
if (state.b !== null && !is_destroyed(state.b) && state.n > 0 && !state.h) {
|
|
352
227
|
render_pending(state);
|
|
353
228
|
}
|
|
354
229
|
});
|
|
@@ -363,11 +238,11 @@ function begin_request(state) {
|
|
|
363
238
|
* @returns {number}
|
|
364
239
|
*/
|
|
365
240
|
function replace_request(state, old_request_id) {
|
|
366
|
-
state.
|
|
367
|
-
state.
|
|
241
|
+
state.q.delete(old_request_id);
|
|
242
|
+
state.d.delete(old_request_id);
|
|
368
243
|
// pending_count unchanged — one out, one in
|
|
369
|
-
var request_id = ++state.
|
|
370
|
-
state.
|
|
244
|
+
var request_id = ++state.v;
|
|
245
|
+
state.q.add(request_id);
|
|
371
246
|
return request_id;
|
|
372
247
|
}
|
|
373
248
|
|
|
@@ -378,15 +253,15 @@ function replace_request(state, old_request_id) {
|
|
|
378
253
|
* @returns {boolean}
|
|
379
254
|
*/
|
|
380
255
|
function complete_request(state, request_id, show_resolved_branch = true) {
|
|
381
|
-
if (!state.
|
|
256
|
+
if (!state.q.delete(request_id)) {
|
|
382
257
|
return false;
|
|
383
258
|
}
|
|
384
259
|
|
|
385
|
-
state.
|
|
260
|
+
state.d.delete(request_id);
|
|
386
261
|
|
|
387
|
-
state.
|
|
262
|
+
state.n--;
|
|
388
263
|
|
|
389
|
-
if (state.
|
|
264
|
+
if (state.n === 0) {
|
|
390
265
|
if (!show_resolved_branch) {
|
|
391
266
|
clear_paused_blocks(state);
|
|
392
267
|
return true;
|
|
@@ -399,17 +274,17 @@ function complete_request(state, request_id, show_resolved_branch = true) {
|
|
|
399
274
|
// and find more pending requests (and pause themselves) before we are
|
|
400
275
|
// certain to render the resolved state.
|
|
401
276
|
// Otherwise, we'll have multiple renders.
|
|
402
|
-
if (state.
|
|
277
|
+
if (state.b === null || is_destroyed(state.b) || state.n > 0) {
|
|
403
278
|
return;
|
|
404
279
|
}
|
|
405
280
|
|
|
406
|
-
if (state.
|
|
281
|
+
if (state.m === 1) {
|
|
407
282
|
destroy_pending(state);
|
|
408
283
|
show_resolved_fragment(state);
|
|
409
284
|
}
|
|
410
285
|
|
|
411
|
-
state.
|
|
412
|
-
state.
|
|
286
|
+
state.h = true;
|
|
287
|
+
state.m = 0;
|
|
413
288
|
});
|
|
414
289
|
// this is more just in case here and shouldn't really cause anything to run
|
|
415
290
|
// most likely the scheduling is already there
|
|
@@ -420,64 +295,12 @@ function complete_request(state, request_id, show_resolved_branch = true) {
|
|
|
420
295
|
return true;
|
|
421
296
|
}
|
|
422
297
|
|
|
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
|
-
}
|
|
445
|
-
|
|
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
|
-
}
|
|
463
|
-
|
|
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
|
-
});
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
298
|
/** @param {TryState} state */
|
|
476
299
|
function run_try(state) {
|
|
477
|
-
if (state.
|
|
478
|
-
|
|
300
|
+
if (state.si !== null) {
|
|
301
|
+
/** @type {import('./hydrate.js').HydrationRuntime} */ (H).f(state);
|
|
479
302
|
} else {
|
|
480
|
-
state.
|
|
303
|
+
state.rb = boundary_branch(() => state.fn(state.a));
|
|
481
304
|
}
|
|
482
305
|
}
|
|
483
306
|
|
|
@@ -492,63 +315,54 @@ function run_try(state) {
|
|
|
492
315
|
* @returns {void}
|
|
493
316
|
*/
|
|
494
317
|
export function try_block(node, try_fn, catch_fn, pending_fn = null, root_controlled = false) {
|
|
318
|
+
if (!installed) {
|
|
319
|
+
installed = true;
|
|
320
|
+
set_catch_router(route_error);
|
|
321
|
+
}
|
|
495
322
|
/** @type {Node | undefined} */
|
|
496
323
|
var boundary;
|
|
497
324
|
/** @type {TryState} */
|
|
498
325
|
var state = {
|
|
499
|
-
|
|
500
|
-
try_fn,
|
|
501
|
-
catch_fn,
|
|
502
|
-
pending_fn,
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
326
|
+
a: root_controlled ? resolve_anchor(node) : /** @type {Node} */ (node),
|
|
327
|
+
fn: try_fn,
|
|
328
|
+
c: catch_fn,
|
|
329
|
+
p: pending_fn,
|
|
330
|
+
r: null,
|
|
331
|
+
n: 0,
|
|
332
|
+
v: 0,
|
|
333
|
+
q: new Set(),
|
|
334
|
+
b: null,
|
|
335
|
+
rb: null,
|
|
336
|
+
pb: null,
|
|
337
|
+
cb: null,
|
|
338
|
+
o: null,
|
|
339
|
+
h: false,
|
|
340
|
+
m: 0,
|
|
341
|
+
d: new Map(),
|
|
342
|
+
z: new Set(),
|
|
343
|
+
si: null,
|
|
344
|
+
se: false,
|
|
345
|
+
sf: false,
|
|
346
|
+
so: null,
|
|
347
|
+
sc: null,
|
|
521
348
|
};
|
|
522
349
|
|
|
523
|
-
if (hydrating && (pending_fn !== null || catch_fn !== null)) {
|
|
350
|
+
if (HYDRATION && hydrating && (pending_fn !== null || catch_fn !== null)) {
|
|
524
351
|
if (root_controlled) {
|
|
525
352
|
boundary = /** @type {Node} */ (hydrate_node);
|
|
526
353
|
}
|
|
527
|
-
|
|
528
|
-
var marker = /** @type {Comment} */ (hydrate_node);
|
|
529
|
-
var data = marker.nodeType === COMMENT_NODE ? marker.data : '';
|
|
530
|
-
|
|
531
|
-
// A slot at this anchor belongs to this boundary, including the root.
|
|
532
|
-
if (data.startsWith(HYDRATION_START_PENDING) || data.startsWith(HYDRATION_START_ERRORED)) {
|
|
533
|
-
hydrate_streamed_slot(state, marker, data);
|
|
534
|
-
} else {
|
|
535
|
-
// Settled SSR content must not transition back to pending.
|
|
536
|
-
if (pending_fn !== null) {
|
|
537
|
-
state.has_resolved = true;
|
|
538
|
-
}
|
|
539
|
-
hydrate_next(); // consume <!--[-->
|
|
540
|
-
}
|
|
354
|
+
/** @type {import('./hydrate.js').HydrationRuntime} */ (H).m(state);
|
|
541
355
|
}
|
|
542
356
|
|
|
543
|
-
state.
|
|
357
|
+
state.b = create_block(TRY_BLOCK, run_try, state);
|
|
544
358
|
|
|
545
|
-
if (state.
|
|
546
|
-
|
|
359
|
+
if (state.si !== null) {
|
|
360
|
+
/** @type {import('./hydrate.js').HydrationRuntime} */ (H).s(state);
|
|
547
361
|
}
|
|
548
362
|
|
|
549
|
-
own_anchor(node, state.
|
|
363
|
+
own_anchor(node, state.a);
|
|
550
364
|
|
|
551
|
-
if (hydrating && root_controlled) {
|
|
365
|
+
if (HYDRATION && hydrating && root_controlled) {
|
|
552
366
|
append(/** @type {ChildNode} */ (node), /** @type {Node} */ (boundary));
|
|
553
367
|
}
|
|
554
368
|
}
|
|
@@ -562,7 +376,7 @@ export function get_pending_boundary(block) {
|
|
|
562
376
|
|
|
563
377
|
while (current !== null) {
|
|
564
378
|
var state = /** @type {BlockWithTryBoundary} */ (current).s;
|
|
565
|
-
if ((current.f & TRY_BLOCK) !== 0 && state.
|
|
379
|
+
if ((current.f & TRY_BLOCK) !== 0 && state.p !== null) {
|
|
566
380
|
return /** @type {BlockWithTryBoundary} */ (current);
|
|
567
381
|
}
|
|
568
382
|
current = current.p;
|
|
@@ -581,7 +395,7 @@ export function get_boundary_with_catch(block) {
|
|
|
581
395
|
|
|
582
396
|
while (current !== null) {
|
|
583
397
|
var state = /** @type {BlockWithTryBoundary} */ (current).s;
|
|
584
|
-
if ((current.f & TRY_BLOCK) !== 0 && state.
|
|
398
|
+
if ((current.f & TRY_BLOCK) !== 0 && state.c !== null) {
|
|
585
399
|
return /** @type {BlockWithTryBoundaryAndCatch} */ (current);
|
|
586
400
|
}
|
|
587
401
|
current = current.p;
|
|
@@ -597,7 +411,7 @@ export function get_boundary_with_catch(block) {
|
|
|
597
411
|
* @returns {void}
|
|
598
412
|
*/
|
|
599
413
|
export function handle_boundary_error(boundary, error) {
|
|
600
|
-
|
|
414
|
+
catch_error(boundary.s, error);
|
|
601
415
|
}
|
|
602
416
|
|
|
603
417
|
/**
|
|
@@ -637,7 +451,7 @@ export function complete_boundary_request(boundary, request_id, show_resolved_br
|
|
|
637
451
|
*/
|
|
638
452
|
export function register_boundary_deferred(boundary, request_id, reject_fn) {
|
|
639
453
|
if (boundary !== null && !is_destroyed(boundary)) {
|
|
640
|
-
boundary.s.
|
|
454
|
+
boundary.s.d.set(request_id, reject_fn);
|
|
641
455
|
}
|
|
642
456
|
}
|
|
643
457
|
|
|
@@ -648,6 +462,6 @@ export function register_boundary_deferred(boundary, request_id, reject_fn) {
|
|
|
648
462
|
*/
|
|
649
463
|
export function register_boundary_paused_block(boundary, block) {
|
|
650
464
|
if (boundary !== null && !is_destroyed(boundary)) {
|
|
651
|
-
boundary.s.
|
|
465
|
+
boundary.s.z.add(block);
|
|
652
466
|
}
|
|
653
467
|
}
|