ripple 0.3.11 → 0.3.13
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 +43 -0
- package/package.json +8 -2
- package/src/compiler/phases/1-parse/index.js +73 -30
- package/src/compiler/phases/2-analyze/index.js +28 -58
- package/src/compiler/phases/3-transform/client/index.js +127 -164
- package/src/compiler/phases/3-transform/segments.js +4 -8
- package/src/compiler/phases/3-transform/server/index.js +210 -360
- package/src/compiler/types/import.d.ts +0 -12
- package/src/compiler/types/index.d.ts +12 -5
- package/src/compiler/types/parse.d.ts +2 -0
- package/src/compiler/utils.js +39 -44
- package/src/helpers.d.ts +2 -0
- package/src/runtime/index-client.js +15 -13
- package/src/runtime/index-server.js +18 -11
- package/src/runtime/internal/client/blocks.js +19 -23
- package/src/runtime/internal/client/constants.js +20 -9
- package/src/runtime/internal/client/index.js +14 -4
- package/src/runtime/internal/client/runtime.js +435 -173
- package/src/runtime/internal/client/try.js +334 -156
- package/src/runtime/internal/client/types.d.ts +26 -0
- package/src/runtime/internal/server/blocks.js +183 -0
- package/src/runtime/internal/server/constants.js +7 -0
- package/src/runtime/internal/server/index.js +780 -148
- package/src/runtime/internal/server/types.d.ts +35 -0
- package/src/server/index.js +1 -1
- package/src/utils/async.js +35 -0
- package/src/utils/builders.js +3 -1
- package/tests/client/__snapshots__/computed-properties.test.rsrx.snap +49 -0
- package/tests/client/__snapshots__/for.test.rsrx.snap +319 -0
- package/tests/client/__snapshots__/html.test.rsrx.snap +40 -0
- package/tests/client/_etc.test.rsrx +7 -0
- package/tests/client/array/{array.static.test.ripple → array.static.test.rsrx} +18 -20
- package/tests/client/async-suspend.test.rsrx +662 -0
- package/tests/client/basic/__snapshots__/basic.attributes.test.rsrx.snap +60 -0
- package/tests/client/basic/__snapshots__/basic.rendering.test.rsrx.snap +59 -0
- package/tests/client/basic/{basic.errors.test.ripple → basic.errors.test.rsrx} +2 -2
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +12 -0
- package/tests/client/compiler/__snapshots__/compiler.typescript.test.rsrx.snap +46 -0
- package/tests/client/compiler/{compiler.try-in-function.test.ripple → compiler.try-in-function.test.rsrx} +8 -6
- package/tests/client/composite/__snapshots__/composite.render.test.rsrx.snap +37 -0
- package/tests/client/{function-overload.test.ripple → function-overload.test.rsrx} +1 -1
- package/tests/client/try.test.rsrx +1702 -0
- package/tests/hydration/build-components.js +5 -3
- package/tests/hydration/compiled/client/head.js +11 -11
- package/tests/hydration/compiled/client/mixed-control-flow.js +55 -70
- package/tests/hydration/compiled/client/nested-control-flow.js +72 -88
- package/tests/hydration/compiled/client/try.js +42 -54
- package/tests/hydration/compiled/server/basic.js +491 -369
- package/tests/hydration/compiled/server/composite.js +153 -128
- package/tests/hydration/compiled/server/events.js +166 -145
- package/tests/hydration/compiled/server/for.js +821 -677
- package/tests/hydration/compiled/server/head.js +200 -165
- package/tests/hydration/compiled/server/hmr.js +62 -54
- package/tests/hydration/compiled/server/html-in-template.js +64 -55
- package/tests/hydration/compiled/server/html.js +1477 -1360
- package/tests/hydration/compiled/server/if-children.js +448 -408
- package/tests/hydration/compiled/server/if.js +204 -171
- package/tests/hydration/compiled/server/mixed-control-flow.js +237 -195
- package/tests/hydration/compiled/server/nested-control-flow.js +533 -467
- package/tests/hydration/compiled/server/portal.js +94 -107
- package/tests/hydration/compiled/server/reactivity.js +87 -64
- package/tests/hydration/compiled/server/return.js +1424 -1174
- package/tests/hydration/compiled/server/switch.js +268 -238
- package/tests/hydration/compiled/server/try.js +98 -87
- package/tests/hydration/components/{mixed-control-flow.ripple → mixed-control-flow.rsrx} +2 -2
- package/tests/hydration/components/{try.ripple → try.rsrx} +4 -2
- package/tests/hydration/mixed-control-flow.test.js +14 -0
- package/tests/hydration/nested-control-flow.test.js +50 -48
- package/tests/hydration/try.test.js +25 -0
- package/tests/server/__snapshots__/compiler.test.ripple.snap +0 -32
- package/tests/server/__snapshots__/compiler.test.rsrx.snap +95 -0
- package/tests/server/{compiler.test.ripple → compiler.test.rsrx} +0 -17
- package/tests/server/{html-nesting-validation.test.ripple → html-nesting-validation.test.rsrx} +3 -3
- package/tests/server/streaming-ssr.test.rsrx +115 -0
- package/tests/server/try.test.rsrx +503 -0
- package/tests/utils/compiler-compat-config.test.js +3 -3
- package/tests/utils/vite-plugin-config.test.js +1 -1
- package/tests/utils/vite-plugin-hmr.test.js +5 -5
- package/tsconfig.json +4 -0
- package/types/index.d.ts +13 -23
- package/types/server.d.ts +43 -16
- package/tests/client/_etc.test.ripple +0 -5
- package/tests/client/async-suspend.test.ripple +0 -94
- package/tests/client/try.test.ripple +0 -196
- package/tests/server/streaming-ssr.test.ripple +0 -68
- package/tests/server/try.test.ripple +0 -82
- /package/tests/client/array/{array.copy-within.test.ripple → array.copy-within.test.rsrx} +0 -0
- /package/tests/client/array/{array.derived.test.ripple → array.derived.test.rsrx} +0 -0
- /package/tests/client/array/{array.iteration.test.ripple → array.iteration.test.rsrx} +0 -0
- /package/tests/client/array/{array.mutations.test.ripple → array.mutations.test.rsrx} +0 -0
- /package/tests/client/array/{array.to-methods.test.ripple → array.to-methods.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.attributes.test.ripple → basic.attributes.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.collections.test.ripple → basic.collections.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.components.test.ripple → basic.components.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.events.test.ripple → basic.events.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.get-set.test.ripple → basic.get-set.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.hmr.test.ripple → basic.hmr.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.reactivity.test.ripple → basic.reactivity.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.rendering.test.ripple → basic.rendering.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.styling.test.ripple → basic.styling.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.utilities.test.ripple → basic.utilities.test.rsrx} +0 -0
- /package/tests/client/{boundaries.test.ripple → boundaries.test.rsrx} +0 -0
- /package/tests/client/compiler/{compiler.assignments.test.ripple → compiler.assignments.test.rsrx} +0 -0
- /package/tests/client/compiler/{compiler.attributes.test.ripple → compiler.attributes.test.rsrx} +0 -0
- /package/tests/client/compiler/{compiler.basic.test.ripple → compiler.basic.test.rsrx} +0 -0
- /package/tests/client/compiler/{compiler.regex.test.ripple → compiler.regex.test.rsrx} +0 -0
- /package/tests/client/compiler/{compiler.tracked-access.test.ripple → compiler.tracked-access.test.rsrx} +0 -0
- /package/tests/client/compiler/{compiler.typescript.test.ripple → compiler.typescript.test.rsrx} +0 -0
- /package/tests/client/composite/{composite.dynamic-components.test.ripple → composite.dynamic-components.test.rsrx} +0 -0
- /package/tests/client/composite/{composite.generics.test.ripple → composite.generics.test.rsrx} +0 -0
- /package/tests/client/composite/{composite.props.test.ripple → composite.props.test.rsrx} +0 -0
- /package/tests/client/composite/{composite.reactivity.test.ripple → composite.reactivity.test.rsrx} +0 -0
- /package/tests/client/composite/{composite.render.test.ripple → composite.render.test.rsrx} +0 -0
- /package/tests/client/{computed-properties.test.ripple → computed-properties.test.rsrx} +0 -0
- /package/tests/client/{context.test.ripple → context.test.rsrx} +0 -0
- /package/tests/client/css/{global-additional-cases.test.ripple → global-additional-cases.test.rsrx} +0 -0
- /package/tests/client/css/{global-advanced-selectors.test.ripple → global-advanced-selectors.test.rsrx} +0 -0
- /package/tests/client/css/{global-at-rules.test.ripple → global-at-rules.test.rsrx} +0 -0
- /package/tests/client/css/{global-basic.test.ripple → global-basic.test.rsrx} +0 -0
- /package/tests/client/css/{global-classes-ids.test.ripple → global-classes-ids.test.rsrx} +0 -0
- /package/tests/client/css/{global-combinators.test.ripple → global-combinators.test.rsrx} +0 -0
- /package/tests/client/css/{global-complex-nesting.test.ripple → global-complex-nesting.test.rsrx} +0 -0
- /package/tests/client/css/{global-edge-cases.test.ripple → global-edge-cases.test.rsrx} +0 -0
- /package/tests/client/css/{global-keyframes.test.ripple → global-keyframes.test.rsrx} +0 -0
- /package/tests/client/css/{global-nested.test.ripple → global-nested.test.rsrx} +0 -0
- /package/tests/client/css/{global-pseudo.test.ripple → global-pseudo.test.rsrx} +0 -0
- /package/tests/client/css/{global-scoping.test.ripple → global-scoping.test.rsrx} +0 -0
- /package/tests/client/css/{style-identifier.test.ripple → style-identifier.test.rsrx} +0 -0
- /package/tests/client/{date.test.ripple → date.test.rsrx} +0 -0
- /package/tests/client/{dynamic-elements.test.ripple → dynamic-elements.test.rsrx} +0 -0
- /package/tests/client/{events.test.ripple → events.test.rsrx} +0 -0
- /package/tests/client/{for.test.ripple → for.test.rsrx} +0 -0
- /package/tests/client/{function-overload-import.ripple → function-overload-import.rsrx} +0 -0
- /package/tests/client/{head.test.ripple → head.test.rsrx} +0 -0
- /package/tests/client/{html.test.ripple → html.test.rsrx} +0 -0
- /package/tests/client/{input-value.test.ripple → input-value.test.rsrx} +0 -0
- /package/tests/client/{lazy-destructuring.test.ripple → lazy-destructuring.test.rsrx} +0 -0
- /package/tests/client/{map.test.ripple → map.test.rsrx} +0 -0
- /package/tests/client/{media-query.test.ripple → media-query.test.rsrx} +0 -0
- /package/tests/client/{object.test.ripple → object.test.rsrx} +0 -0
- /package/tests/client/{portal.test.ripple → portal.test.rsrx} +0 -0
- /package/tests/client/{ref.test.ripple → ref.test.rsrx} +0 -0
- /package/tests/client/{return.test.ripple → return.test.rsrx} +0 -0
- /package/tests/client/{set.test.ripple → set.test.rsrx} +0 -0
- /package/tests/client/{svg.test.ripple → svg.test.rsrx} +0 -0
- /package/tests/client/{switch.test.ripple → switch.test.rsrx} +0 -0
- /package/tests/client/{tsx.test.ripple → tsx.test.rsrx} +0 -0
- /package/tests/client/{typescript-generics.test.ripple → typescript-generics.test.rsrx} +0 -0
- /package/tests/client/url/{url.derived.test.ripple → url.derived.test.rsrx} +0 -0
- /package/tests/client/url/{url.parsing.test.ripple → url.parsing.test.rsrx} +0 -0
- /package/tests/client/url/{url.partial-removal.test.ripple → url.partial-removal.test.rsrx} +0 -0
- /package/tests/client/url/{url.reactivity.test.ripple → url.reactivity.test.rsrx} +0 -0
- /package/tests/client/url/{url.serialization.test.ripple → url.serialization.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.derived.test.ripple → url-search-params.derived.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.initialization.test.ripple → url-search-params.initialization.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.iteration.test.ripple → url-search-params.iteration.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.mutation.test.ripple → url-search-params.mutation.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.retrieval.test.ripple → url-search-params.retrieval.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.serialization.test.ripple → url-search-params.serialization.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.tracked-url.test.ripple → url-search-params.tracked-url.test.rsrx} +0 -0
- /package/tests/hydration/components/{basic.ripple → basic.rsrx} +0 -0
- /package/tests/hydration/components/{composite.ripple → composite.rsrx} +0 -0
- /package/tests/hydration/components/{events.ripple → events.rsrx} +0 -0
- /package/tests/hydration/components/{for.ripple → for.rsrx} +0 -0
- /package/tests/hydration/components/{head.ripple → head.rsrx} +0 -0
- /package/tests/hydration/components/{hmr.ripple → hmr.rsrx} +0 -0
- /package/tests/hydration/components/{html-in-template.ripple → html-in-template.rsrx} +0 -0
- /package/tests/hydration/components/{html.ripple → html.rsrx} +0 -0
- /package/tests/hydration/components/{if-children.ripple → if-children.rsrx} +0 -0
- /package/tests/hydration/components/{if.ripple → if.rsrx} +0 -0
- /package/tests/hydration/components/{nested-control-flow.ripple → nested-control-flow.rsrx} +0 -0
- /package/tests/hydration/components/{portal.ripple → portal.rsrx} +0 -0
- /package/tests/hydration/components/{reactivity.ripple → reactivity.rsrx} +0 -0
- /package/tests/hydration/components/{return.ripple → return.rsrx} +0 -0
- /package/tests/hydration/components/{switch.ripple → switch.rsrx} +0 -0
- /package/tests/server/{await.test.ripple → await.test.rsrx} +0 -0
- /package/tests/server/{basic.attributes.test.ripple → basic.attributes.test.rsrx} +0 -0
- /package/tests/server/{basic.components.test.ripple → basic.components.test.rsrx} +0 -0
- /package/tests/server/{basic.test.ripple → basic.test.rsrx} +0 -0
- /package/tests/server/{composite.props.test.ripple → composite.props.test.rsrx} +0 -0
- /package/tests/server/{composite.test.ripple → composite.test.rsrx} +0 -0
- /package/tests/server/{context.test.ripple → context.test.rsrx} +0 -0
- /package/tests/server/{dynamic-elements.test.ripple → dynamic-elements.test.rsrx} +0 -0
- /package/tests/server/{for.test.ripple → for.test.rsrx} +0 -0
- /package/tests/server/{head.test.ripple → head.test.rsrx} +0 -0
- /package/tests/server/{if.test.ripple → if.test.rsrx} +0 -0
- /package/tests/server/{lazy-destructuring.test.ripple → lazy-destructuring.test.rsrx} +0 -0
- /package/tests/server/{return.test.ripple → return.test.rsrx} +0 -0
- /package/tests/server/{style-identifier.test.ripple → style-identifier.test.rsrx} +0 -0
- /package/tests/server/{switch.test.ripple → switch.test.rsrx} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @import { Block, Component, Dependency, Derived, Tracked } from '#client' */
|
|
1
|
+
/** @import { Block, Component, Dependency, Derived, Tracked, BlockWithTryBoundaryAndCatch, DeferredTrackedEntry } from '#client' */
|
|
2
2
|
/** @import { NAMESPACE_URI } from './constants.js' */
|
|
3
3
|
|
|
4
4
|
import { DEV } from 'esm-env';
|
|
@@ -6,30 +6,42 @@ import {
|
|
|
6
6
|
destroy_block,
|
|
7
7
|
destroy_non_branch_children,
|
|
8
8
|
effect,
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
pause_block,
|
|
10
|
+
pre_effect,
|
|
11
11
|
} from './blocks.js';
|
|
12
12
|
import {
|
|
13
|
-
|
|
13
|
+
ASYNC_DERIVED_READ_THROWN,
|
|
14
14
|
BLOCK_HAS_RUN,
|
|
15
15
|
BRANCH_BLOCK,
|
|
16
16
|
DERIVED,
|
|
17
17
|
COMPUTED_PROPERTY,
|
|
18
18
|
CONTAINS_TEARDOWN,
|
|
19
19
|
CONTAINS_UPDATE,
|
|
20
|
-
DEFERRED,
|
|
21
20
|
DESTROYED,
|
|
22
21
|
EFFECT_BLOCK,
|
|
23
22
|
PAUSED,
|
|
23
|
+
PRE_EFFECT_BLOCK,
|
|
24
24
|
ROOT_BLOCK,
|
|
25
25
|
TRACKED,
|
|
26
|
-
TRY_BLOCK,
|
|
27
26
|
UNINITIALIZED,
|
|
28
27
|
REF_PROP,
|
|
29
28
|
TRACKED_OBJECT,
|
|
30
29
|
DEFAULT_NAMESPACE,
|
|
30
|
+
DERIVED_UPDATED,
|
|
31
|
+
SUSPENSE_PENDING,
|
|
32
|
+
SUSPENSE_REJECTED,
|
|
33
|
+
TRY_BLOCK,
|
|
34
|
+
DIRECT_CHILD_BLOCK,
|
|
31
35
|
} from './constants.js';
|
|
32
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
begin_boundary_request,
|
|
38
|
+
complete_boundary_request,
|
|
39
|
+
get_boundary_with_catch,
|
|
40
|
+
get_pending_boundary,
|
|
41
|
+
register_boundary_deferred,
|
|
42
|
+
register_boundary_paused_block,
|
|
43
|
+
replace_boundary_request,
|
|
44
|
+
} from './try.js';
|
|
33
45
|
import {
|
|
34
46
|
define_property,
|
|
35
47
|
get_descriptor,
|
|
@@ -38,6 +50,7 @@ import {
|
|
|
38
50
|
is_ripple_object,
|
|
39
51
|
object_keys,
|
|
40
52
|
} from './utils.js';
|
|
53
|
+
import { get_async_track_result } from '../../../utils/async.js';
|
|
41
54
|
|
|
42
55
|
const FLUSH_MICROTASK = 0;
|
|
43
56
|
const FLUSH_SYNC = 1;
|
|
@@ -55,7 +68,7 @@ export let active_namespace = DEFAULT_NAMESPACE;
|
|
|
55
68
|
/** @type {boolean} */
|
|
56
69
|
export let is_mutating_allowed = true;
|
|
57
70
|
|
|
58
|
-
/** @type {Map<Tracked, any>} */
|
|
71
|
+
/** @type {Map<Tracked | Derived, any>} */
|
|
59
72
|
var old_values = new Map();
|
|
60
73
|
|
|
61
74
|
// Used for controlling the flush of blocks
|
|
@@ -72,6 +85,8 @@ let queued_root_blocks = [];
|
|
|
72
85
|
let queued_microtasks = [];
|
|
73
86
|
/** @type {number} */
|
|
74
87
|
let flush_count = 0;
|
|
88
|
+
/** @type {(() => void)[]} */
|
|
89
|
+
var queued_post_block_flush = [];
|
|
75
90
|
/** @type {null | Dependency} */
|
|
76
91
|
let active_dependency = null;
|
|
77
92
|
|
|
@@ -141,7 +156,7 @@ export function run_teardown(block) {
|
|
|
141
156
|
|
|
142
157
|
/**
|
|
143
158
|
* @param {Block} block
|
|
144
|
-
* @param {() =>
|
|
159
|
+
* @param {() => any} fn
|
|
145
160
|
*/
|
|
146
161
|
export function with_block(block, fn) {
|
|
147
162
|
var prev_block = active_block;
|
|
@@ -172,6 +187,15 @@ function update_derived(computed) {
|
|
|
172
187
|
}
|
|
173
188
|
}
|
|
174
189
|
|
|
190
|
+
/**
|
|
191
|
+
* @param {Tracked} tracked
|
|
192
|
+
* @param {any} value
|
|
193
|
+
*/
|
|
194
|
+
function update_tracked_value_clock(tracked, value) {
|
|
195
|
+
tracked.__v = value;
|
|
196
|
+
tracked.c = increment_clock();
|
|
197
|
+
}
|
|
198
|
+
|
|
175
199
|
/**
|
|
176
200
|
* @param {Derived} computed
|
|
177
201
|
*/
|
|
@@ -212,6 +236,20 @@ function run_derived(computed) {
|
|
|
212
236
|
computed.d = active_dependency;
|
|
213
237
|
|
|
214
238
|
return value;
|
|
239
|
+
} catch (error) {
|
|
240
|
+
computed.d = active_dependency;
|
|
241
|
+
if (error === ASYNC_DERIVED_READ_THROWN) {
|
|
242
|
+
// Check if any dependency is rejected — if so, propagate rejection
|
|
243
|
+
var dep = active_dependency;
|
|
244
|
+
while (dep !== null) {
|
|
245
|
+
if (dep.t.__v === SUSPENSE_REJECTED) {
|
|
246
|
+
return SUSPENSE_REJECTED;
|
|
247
|
+
}
|
|
248
|
+
dep = dep.n;
|
|
249
|
+
}
|
|
250
|
+
return SUSPENSE_PENDING;
|
|
251
|
+
}
|
|
252
|
+
throw error;
|
|
215
253
|
} finally {
|
|
216
254
|
active_block = previous_block;
|
|
217
255
|
active_reaction = previous_reaction;
|
|
@@ -225,18 +263,13 @@ function run_derived(computed) {
|
|
|
225
263
|
/**
|
|
226
264
|
* @param {unknown} error
|
|
227
265
|
* @param {Block} block
|
|
266
|
+
* @returns {BlockWithTryBoundaryAndCatch}
|
|
228
267
|
*/
|
|
229
268
|
export function handle_error(error, block) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
var state = current.s;
|
|
235
|
-
if ((current.f & TRY_BLOCK) !== 0 && state.c !== null) {
|
|
236
|
-
state.c(error);
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
current = current.p;
|
|
269
|
+
var boundary_with_catch = get_boundary_with_catch(block);
|
|
270
|
+
if (boundary_with_catch !== null) {
|
|
271
|
+
boundary_with_catch.s.c(error);
|
|
272
|
+
return boundary_with_catch;
|
|
240
273
|
}
|
|
241
274
|
|
|
242
275
|
throw error;
|
|
@@ -277,7 +310,53 @@ export function run_block(block) {
|
|
|
277
310
|
|
|
278
311
|
block.d = active_dependency;
|
|
279
312
|
} catch (error) {
|
|
280
|
-
|
|
313
|
+
var is_component_direct = false;
|
|
314
|
+
var is_try_fn_block = false;
|
|
315
|
+
block.d = active_dependency;
|
|
316
|
+
// When a derived read throws ASYNC_DERIVED_READ_THROWN, it means the
|
|
317
|
+
// derived is still SUSPENSE_PENDING. The dependency was already registered,
|
|
318
|
+
// so we swallow the throw and let the parent continue processing. When
|
|
319
|
+
// the derived settles, the block will be dirty and rerun automatically.
|
|
320
|
+
if (error !== ASYNC_DERIVED_READ_THROWN) {
|
|
321
|
+
handle_error(error, block);
|
|
322
|
+
} else if (
|
|
323
|
+
// pending async tracked was read outside allowed blocks
|
|
324
|
+
(is_component_direct = active_component?.b === block) ||
|
|
325
|
+
(is_try_fn_block =
|
|
326
|
+
block.p !== null && (block.p.f & TRY_BLOCK) !== 0 && (block.f & DIRECT_CHILD_BLOCK) !== 0)
|
|
327
|
+
) {
|
|
328
|
+
throw new Error(
|
|
329
|
+
`Reads on pending tracked values directly inside ${is_component_direct ? 'component' : 'try/pending/catch'} body are prohibited. Use trackPending() test or peek() for safe access or create another derived instead.`,
|
|
330
|
+
);
|
|
331
|
+
} else {
|
|
332
|
+
// pending async tracked was read and threw ASYNC_DERIVED_READ_THROWN
|
|
333
|
+
var boundary = get_pending_boundary(block);
|
|
334
|
+
if (boundary !== null) {
|
|
335
|
+
pause_block(block);
|
|
336
|
+
register_boundary_paused_block(boundary, block);
|
|
337
|
+
|
|
338
|
+
// Register deferred boundary completions for async tracked deps.
|
|
339
|
+
// This handles the case where a child boundary reads a tracked value
|
|
340
|
+
// whose resolution is managed by a different (parent) boundary.
|
|
341
|
+
var dep = block.d;
|
|
342
|
+
while (dep !== null) {
|
|
343
|
+
var dep_tracked = /** @type {Tracked} */ (dep.t);
|
|
344
|
+
if (
|
|
345
|
+
(dep_tracked.__v === SUSPENSE_PENDING || dep_tracked.__v === SUSPENSE_REJECTED) &&
|
|
346
|
+
(dep_tracked.f & TRACKED) !== 0
|
|
347
|
+
) {
|
|
348
|
+
var deferred_req = begin_boundary_request(boundary);
|
|
349
|
+
var entry = /** @type {DeferredTrackedEntry} */ ({ b: boundary, r: deferred_req });
|
|
350
|
+
if (dep_tracked.d === null) {
|
|
351
|
+
dep_tracked.d = [entry];
|
|
352
|
+
} else {
|
|
353
|
+
dep_tracked.d.push(entry);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
dep = dep.n;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
281
360
|
} finally {
|
|
282
361
|
active_block = previous_block;
|
|
283
362
|
active_reaction = previous_reaction;
|
|
@@ -289,6 +368,22 @@ export function run_block(block) {
|
|
|
289
368
|
|
|
290
369
|
var empty_get_set = { get: undefined, set: undefined };
|
|
291
370
|
|
|
371
|
+
/**
|
|
372
|
+
* Complete all deferred boundary requests registered on a tracked value.
|
|
373
|
+
* @param {Tracked} t
|
|
374
|
+
* @param {boolean} [show_resolved=true]
|
|
375
|
+
*/
|
|
376
|
+
function complete_deferred_boundaries(t, show_resolved = true) {
|
|
377
|
+
if (t.d !== null) {
|
|
378
|
+
for (var i = 0; i < t.d.length; i++) {
|
|
379
|
+
var entry = t.d[i];
|
|
380
|
+
complete_boundary_request(entry.b, entry.r, show_resolved);
|
|
381
|
+
}
|
|
382
|
+
t.d = null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/** @type {Tracked} */
|
|
292
387
|
class TrackedValue {
|
|
293
388
|
/**
|
|
294
389
|
* @param {any} v
|
|
@@ -299,35 +394,37 @@ class TrackedValue {
|
|
|
299
394
|
this.a = a;
|
|
300
395
|
this.b = block;
|
|
301
396
|
this.c = 0;
|
|
397
|
+
this.d = null;
|
|
302
398
|
this.f = TRACKED;
|
|
303
399
|
this.__v = v;
|
|
304
400
|
}
|
|
305
401
|
get [0]() {
|
|
306
|
-
return get_tracked(
|
|
402
|
+
return get_tracked(this);
|
|
307
403
|
}
|
|
308
404
|
set [0](v) {
|
|
309
|
-
set(
|
|
405
|
+
set(this, v);
|
|
310
406
|
}
|
|
311
407
|
get [1]() {
|
|
312
408
|
return this;
|
|
313
409
|
}
|
|
314
410
|
get value() {
|
|
315
|
-
return get_tracked(
|
|
411
|
+
return get_tracked(this);
|
|
316
412
|
}
|
|
317
413
|
/** @param {any} v */
|
|
318
414
|
set value(v) {
|
|
319
|
-
set(
|
|
415
|
+
set(this, v);
|
|
320
416
|
}
|
|
321
417
|
/** @returns {2} */
|
|
322
418
|
get length() {
|
|
323
419
|
return 2;
|
|
324
420
|
}
|
|
325
421
|
*[Symbol.iterator]() {
|
|
326
|
-
yield get_tracked(
|
|
422
|
+
yield get_tracked(this);
|
|
327
423
|
yield this;
|
|
328
424
|
}
|
|
329
425
|
}
|
|
330
426
|
|
|
427
|
+
/** @type {Derived} */
|
|
331
428
|
class DerivedValue {
|
|
332
429
|
/**
|
|
333
430
|
* @param {Function} fn
|
|
@@ -343,32 +440,32 @@ class DerivedValue {
|
|
|
343
440
|
this.co = active_component;
|
|
344
441
|
/** @type {null | Dependency} */
|
|
345
442
|
this.d = null;
|
|
346
|
-
this.f =
|
|
443
|
+
this.f = DERIVED;
|
|
347
444
|
this.fn = fn;
|
|
348
445
|
this.__v = UNINITIALIZED;
|
|
349
446
|
}
|
|
350
447
|
get [0]() {
|
|
351
|
-
return get_derived(
|
|
448
|
+
return get_derived(this);
|
|
352
449
|
}
|
|
353
450
|
set [0](v) {
|
|
354
|
-
set(
|
|
451
|
+
set(this, v);
|
|
355
452
|
}
|
|
356
453
|
get [1]() {
|
|
357
454
|
return this;
|
|
358
455
|
}
|
|
359
456
|
get value() {
|
|
360
|
-
return get_derived(
|
|
457
|
+
return get_derived(this);
|
|
361
458
|
}
|
|
362
459
|
/** @param {any} v */
|
|
363
460
|
set value(v) {
|
|
364
|
-
set(
|
|
461
|
+
set(this, v);
|
|
365
462
|
}
|
|
366
463
|
/** @returns {2} */
|
|
367
464
|
get length() {
|
|
368
465
|
return 2;
|
|
369
466
|
}
|
|
370
467
|
*[Symbol.iterator]() {
|
|
371
|
-
yield get_derived(
|
|
468
|
+
yield get_derived(this);
|
|
372
469
|
yield this;
|
|
373
470
|
}
|
|
374
471
|
}
|
|
@@ -426,6 +523,225 @@ export function track(v, get, set, b) {
|
|
|
426
523
|
return tracked(v, b, get, set);
|
|
427
524
|
}
|
|
428
525
|
|
|
526
|
+
/**
|
|
527
|
+
* @param {any} fn
|
|
528
|
+
* @param {Block} b
|
|
529
|
+
* @returns {Tracked | void}
|
|
530
|
+
*/
|
|
531
|
+
export function track_async(fn, b) {
|
|
532
|
+
if (is_ripple_object(fn)) {
|
|
533
|
+
return fn;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
var target_block = b || active_block;
|
|
537
|
+
if (target_block === null) {
|
|
538
|
+
throw new TypeError('trackAsync() requires a valid component context');
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
if (typeof fn !== 'function') {
|
|
542
|
+
throw new TypeError(
|
|
543
|
+
'trackAsync() only accepts function arguments that return a promise or an object with a promise property',
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
var t = tracked(SUSPENSE_PENDING, target_block);
|
|
548
|
+
|
|
549
|
+
// Capture the call-site block for boundary lookups. target_block is the
|
|
550
|
+
// component's block (passed by compiler), but the actual try/pending/catch
|
|
551
|
+
// boundary is an ancestor of active_block (the block executing trackAsync).
|
|
552
|
+
var call_site_block = /** @type {Block} */ (active_block);
|
|
553
|
+
|
|
554
|
+
var version = 0;
|
|
555
|
+
/** @type {AbortController | null} */
|
|
556
|
+
var abort_controller = null;
|
|
557
|
+
var request_id = 0;
|
|
558
|
+
/** @type {Block | null} */
|
|
559
|
+
var boundary = null;
|
|
560
|
+
|
|
561
|
+
// Find boundary from the call-site block.
|
|
562
|
+
boundary = get_pending_boundary(active_block);
|
|
563
|
+
if (boundary === null) {
|
|
564
|
+
throw new Error('Missing parent `try { ... } pending { ... }` statement');
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
request_id = begin_boundary_request(boundary);
|
|
568
|
+
|
|
569
|
+
pre_effect(() => {
|
|
570
|
+
var current_version = ++version;
|
|
571
|
+
|
|
572
|
+
// Abort previous in-flight request
|
|
573
|
+
if (abort_controller !== null && abort_controller.signal.aborted === false) {
|
|
574
|
+
abort_controller.abort(DERIVED_UPDATED);
|
|
575
|
+
}
|
|
576
|
+
abort_controller = null;
|
|
577
|
+
|
|
578
|
+
// Manage boundary request: replace if in-flight, or begin new if previous completed
|
|
579
|
+
if (request_id > 0 && boundary !== null) {
|
|
580
|
+
request_id = replace_boundary_request(boundary, request_id);
|
|
581
|
+
} else if (boundary !== null) {
|
|
582
|
+
request_id = begin_boundary_request(boundary);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Set to pending before calling fn() in case it's sync
|
|
586
|
+
if (t.__v !== SUSPENSE_PENDING) {
|
|
587
|
+
update_tracked_value_clock(t, SUSPENSE_PENDING);
|
|
588
|
+
schedule_update(t.b);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Temporarily allow mutations so set() doesn't throw inside the pre-effect
|
|
592
|
+
var previous_is_mutating_allowed = is_mutating_allowed;
|
|
593
|
+
is_mutating_allowed = true;
|
|
594
|
+
|
|
595
|
+
var result;
|
|
596
|
+
try {
|
|
597
|
+
result = fn();
|
|
598
|
+
} catch (e) {
|
|
599
|
+
is_mutating_allowed = previous_is_mutating_allowed;
|
|
600
|
+
if (e === ASYNC_DERIVED_READ_THROWN) {
|
|
601
|
+
// A dependency is still pending or rejected (e.g. chained trackAsync).
|
|
602
|
+
// Check if any dependency is rejected — if so, propagate rejection.
|
|
603
|
+
var dep = active_dependency;
|
|
604
|
+
while (dep !== null) {
|
|
605
|
+
if (dep.t.__v === SUSPENSE_REJECTED) {
|
|
606
|
+
update_tracked_value_clock(t, SUSPENSE_REJECTED);
|
|
607
|
+
schedule_update(t.b);
|
|
608
|
+
complete_deferred_boundaries(t, false);
|
|
609
|
+
if (request_id > 0 && boundary !== null) {
|
|
610
|
+
complete_boundary_request(boundary, request_id, false);
|
|
611
|
+
request_id = 0;
|
|
612
|
+
}
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
dep = dep.n;
|
|
616
|
+
}
|
|
617
|
+
// Dependencies are pending, not rejected — register deferred
|
|
618
|
+
// rejection so that if the boundary goes to catch mode, this
|
|
619
|
+
// tracked value is also set to REJECTED.
|
|
620
|
+
if (request_id > 0 && boundary !== null) {
|
|
621
|
+
register_boundary_deferred(boundary, request_id, () => {
|
|
622
|
+
update_tracked_value_clock(t, SUSPENSE_REJECTED);
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
throw e;
|
|
628
|
+
}
|
|
629
|
+
is_mutating_allowed = previous_is_mutating_allowed;
|
|
630
|
+
|
|
631
|
+
// Check if the result is async
|
|
632
|
+
var previous_tracking = tracking;
|
|
633
|
+
tracking = false;
|
|
634
|
+
var async_result = get_async_track_result(result);
|
|
635
|
+
tracking = previous_tracking;
|
|
636
|
+
|
|
637
|
+
if (async_result === null) {
|
|
638
|
+
// Sync result
|
|
639
|
+
update_tracked_value_clock(t, result);
|
|
640
|
+
schedule_update(t.b);
|
|
641
|
+
if (request_id > 0 && boundary !== null) {
|
|
642
|
+
complete_boundary_request(boundary, request_id);
|
|
643
|
+
request_id = 0;
|
|
644
|
+
}
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// Capture per-invocation so async closures (rejection handler, teardown)
|
|
649
|
+
// have a stable reference. The shared abort_controller is only read
|
|
650
|
+
// synchronously at the top of the pre_effect to abort the previous request.
|
|
651
|
+
var current_abort_controller = async_result.abort_controller;
|
|
652
|
+
abort_controller = current_abort_controller;
|
|
653
|
+
|
|
654
|
+
async_result.promise.then(
|
|
655
|
+
(resolved) => {
|
|
656
|
+
if (current_version !== version) {
|
|
657
|
+
// stale
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
update_tracked_value_clock(t, resolved);
|
|
661
|
+
schedule_update(t.b);
|
|
662
|
+
complete_deferred_boundaries(t);
|
|
663
|
+
if (request_id > 0 && boundary !== null) {
|
|
664
|
+
complete_boundary_request(boundary, request_id);
|
|
665
|
+
request_id = 0;
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
(error) => {
|
|
669
|
+
if (current_version !== version) return; // stale
|
|
670
|
+
|
|
671
|
+
var is_internal_abort =
|
|
672
|
+
error === DERIVED_UPDATED || current_abort_controller?.signal?.reason === DERIVED_UPDATED;
|
|
673
|
+
if (is_internal_abort) {
|
|
674
|
+
// Internal abort (superseded by a new request) — don't set rejected
|
|
675
|
+
if (request_id > 0 && boundary !== null) {
|
|
676
|
+
complete_boundary_request(boundary, request_id, false);
|
|
677
|
+
request_id = 0;
|
|
678
|
+
}
|
|
679
|
+
complete_deferred_boundaries(t, false);
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
update_tracked_value_clock(t, SUSPENSE_REJECTED);
|
|
684
|
+
schedule_update(t.b);
|
|
685
|
+
complete_deferred_boundaries(t, false);
|
|
686
|
+
|
|
687
|
+
// Route error to catch boundary
|
|
688
|
+
var boundary_with_catch = get_boundary_with_catch(call_site_block);
|
|
689
|
+
if (boundary_with_catch !== null) {
|
|
690
|
+
boundary_with_catch.s.c(error);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
if (request_id > 0 && boundary !== null) {
|
|
694
|
+
var should_show_resolved =
|
|
695
|
+
boundary_with_catch === boundary || boundary === null ? false : true;
|
|
696
|
+
complete_boundary_request(boundary, request_id, should_show_resolved);
|
|
697
|
+
request_id = 0;
|
|
698
|
+
}
|
|
699
|
+
},
|
|
700
|
+
);
|
|
701
|
+
|
|
702
|
+
return () => {
|
|
703
|
+
// Teardown: abort in-flight request when block is destroyed
|
|
704
|
+
if (current_abort_controller !== null && current_abort_controller.signal.aborted === false) {
|
|
705
|
+
current_abort_controller.abort(DERIVED_UPDATED);
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
return t;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* @param {(Derived | Tracked) | (() => any)} tracked
|
|
715
|
+
* @returns {boolean}
|
|
716
|
+
*/
|
|
717
|
+
export function is_tracked_pending(tracked) {
|
|
718
|
+
try {
|
|
719
|
+
if (typeof tracked === 'function') {
|
|
720
|
+
tracked();
|
|
721
|
+
} else {
|
|
722
|
+
get(tracked);
|
|
723
|
+
}
|
|
724
|
+
return false;
|
|
725
|
+
} catch (error) {
|
|
726
|
+
if (error === ASYNC_DERIVED_READ_THROWN) {
|
|
727
|
+
return true;
|
|
728
|
+
}
|
|
729
|
+
throw error;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* @param {Tracked | Derived} tracked
|
|
735
|
+
* @return {any}
|
|
736
|
+
*/
|
|
737
|
+
export function peek_tracked(tracked) {
|
|
738
|
+
if (!is_ripple_object(tracked)) {
|
|
739
|
+
return tracked;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
return tracked.__v;
|
|
743
|
+
}
|
|
744
|
+
|
|
429
745
|
/**
|
|
430
746
|
* @param {Tracked | Derived} tracked
|
|
431
747
|
* @returns {Dependency}
|
|
@@ -461,7 +777,15 @@ function is_tracking_dirty(tracking) {
|
|
|
461
777
|
var tracked = tracking.t;
|
|
462
778
|
|
|
463
779
|
if ((tracked.f & DERIVED) !== 0) {
|
|
464
|
-
|
|
780
|
+
try {
|
|
781
|
+
update_derived(/** @type {Derived} **/ (tracked));
|
|
782
|
+
} catch (e) {
|
|
783
|
+
if (e === ASYNC_DERIVED_READ_THROWN) {
|
|
784
|
+
// The derived depends on a pending async value — treat as dirty
|
|
785
|
+
return true;
|
|
786
|
+
}
|
|
787
|
+
throw e;
|
|
788
|
+
}
|
|
465
789
|
}
|
|
466
790
|
|
|
467
791
|
if (tracked.c > tracking.c) {
|
|
@@ -490,77 +814,6 @@ export function is_block_dirty(block) {
|
|
|
490
814
|
return is_tracking_dirty(block.d);
|
|
491
815
|
}
|
|
492
816
|
|
|
493
|
-
/**
|
|
494
|
-
* @param {() => Promise<any>} fn
|
|
495
|
-
* @param {Block} block
|
|
496
|
-
* @returns {Promise<Tracked>}
|
|
497
|
-
*/
|
|
498
|
-
export function async_computed(fn, block) {
|
|
499
|
-
/** @type {Block | Derived | null} */
|
|
500
|
-
let parent = active_reaction;
|
|
501
|
-
var t = tracked(UNINITIALIZED, block);
|
|
502
|
-
/** @type {Promise<any>} */
|
|
503
|
-
var promise;
|
|
504
|
-
/** @type {Map<Tracked, {v: any, c: number}>} */
|
|
505
|
-
var new_values = new Map();
|
|
506
|
-
|
|
507
|
-
render(
|
|
508
|
-
() => {
|
|
509
|
-
var [current, deferred] = capture_deferred(() => (promise = fn()));
|
|
510
|
-
|
|
511
|
-
var restore = capture();
|
|
512
|
-
/** @type {(() => void) | undefined} */
|
|
513
|
-
var unsuspend;
|
|
514
|
-
|
|
515
|
-
if (deferred === null) {
|
|
516
|
-
unsuspend = suspend();
|
|
517
|
-
} else {
|
|
518
|
-
for (var i = 0; i < deferred.length; i++) {
|
|
519
|
-
var tracked = deferred[i];
|
|
520
|
-
new_values.set(tracked, { v: tracked.__v, c: tracked.c });
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
promise.then((v) => {
|
|
525
|
-
if (parent && is_destroyed(/** @type {Block} */ (parent))) {
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
|
-
if (promise === current && t.__v !== v) {
|
|
529
|
-
restore();
|
|
530
|
-
|
|
531
|
-
if (t.__v === UNINITIALIZED) {
|
|
532
|
-
t.__v = v;
|
|
533
|
-
} else {
|
|
534
|
-
set(t, v);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
if (deferred === null) {
|
|
539
|
-
unsuspend?.();
|
|
540
|
-
} else if (promise === current) {
|
|
541
|
-
for (var i = 0; i < deferred.length; i++) {
|
|
542
|
-
var tracked = deferred[i];
|
|
543
|
-
var stored = /** @type {{ v: any, c: number }} */ (new_values.get(tracked));
|
|
544
|
-
var { v, c } = stored;
|
|
545
|
-
tracked.__v = v;
|
|
546
|
-
tracked.c = c;
|
|
547
|
-
schedule_update(tracked.b);
|
|
548
|
-
}
|
|
549
|
-
new_values.clear();
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
|
-
},
|
|
553
|
-
null,
|
|
554
|
-
ASYNC_BLOCK,
|
|
555
|
-
);
|
|
556
|
-
|
|
557
|
-
return new Promise(async (resolve) => {
|
|
558
|
-
var p;
|
|
559
|
-
while (p !== (p = promise)) await p;
|
|
560
|
-
return resolve(t);
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
|
|
564
817
|
/**
|
|
565
818
|
* @template V
|
|
566
819
|
* @param {Function} fn
|
|
@@ -576,29 +829,6 @@ function trigger_track_get(fn, v) {
|
|
|
576
829
|
}
|
|
577
830
|
}
|
|
578
831
|
|
|
579
|
-
/**
|
|
580
|
-
* @param {() => any} fn
|
|
581
|
-
* @returns {[any, Tracked[] | null]}
|
|
582
|
-
*/
|
|
583
|
-
function capture_deferred(fn) {
|
|
584
|
-
var value = fn();
|
|
585
|
-
/** @type {Tracked[] | null} */
|
|
586
|
-
var deferred = null;
|
|
587
|
-
var dependency = active_dependency;
|
|
588
|
-
|
|
589
|
-
while (dependency !== null) {
|
|
590
|
-
var tracked = dependency.t;
|
|
591
|
-
if ((tracked.f & DEFERRED) !== 0) {
|
|
592
|
-
deferred ??= [];
|
|
593
|
-
deferred.push(tracked);
|
|
594
|
-
break;
|
|
595
|
-
}
|
|
596
|
-
dependency = dependency.n;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
return [value, deferred];
|
|
600
|
-
}
|
|
601
|
-
|
|
602
832
|
/**
|
|
603
833
|
* @param {Block} root_block
|
|
604
834
|
*/
|
|
@@ -606,6 +836,8 @@ function flush_updates(root_block) {
|
|
|
606
836
|
/** @type {Block | null} */
|
|
607
837
|
var current = root_block;
|
|
608
838
|
var containing_update = null;
|
|
839
|
+
var pre_effects = [];
|
|
840
|
+
var other_blocks = [];
|
|
609
841
|
var effects = [];
|
|
610
842
|
var containing_update_head = null;
|
|
611
843
|
|
|
@@ -619,16 +851,12 @@ function flush_updates(root_block) {
|
|
|
619
851
|
}
|
|
620
852
|
|
|
621
853
|
if ((flags & PAUSED) === 0 && containing_update !== null) {
|
|
622
|
-
if ((flags &
|
|
854
|
+
if ((flags & PRE_EFFECT_BLOCK) !== 0) {
|
|
855
|
+
pre_effects.push(current);
|
|
856
|
+
} else if ((flags & EFFECT_BLOCK) !== 0) {
|
|
623
857
|
effects.push(current);
|
|
624
858
|
} else {
|
|
625
|
-
|
|
626
|
-
if (is_block_dirty(current)) {
|
|
627
|
-
run_block(current);
|
|
628
|
-
}
|
|
629
|
-
} catch (error) {
|
|
630
|
-
handle_error(error, current);
|
|
631
|
-
}
|
|
859
|
+
other_blocks.push(current);
|
|
632
860
|
}
|
|
633
861
|
/** @type {Block | null} */
|
|
634
862
|
var child = current.first;
|
|
@@ -654,18 +882,47 @@ function flush_updates(root_block) {
|
|
|
654
882
|
}
|
|
655
883
|
}
|
|
656
884
|
|
|
657
|
-
var
|
|
885
|
+
var arr_length = 0;
|
|
886
|
+
|
|
887
|
+
// Phase 1: pre-effects (e.g. update tracked values before render blocks read them)
|
|
888
|
+
arr_length = pre_effects.length;
|
|
889
|
+
for (var i = 0; i < arr_length; i++) {
|
|
890
|
+
var block = pre_effects[i];
|
|
891
|
+
|
|
892
|
+
try {
|
|
893
|
+
if ((block.f & (PAUSED | DESTROYED)) === 0 && is_block_dirty(block)) {
|
|
894
|
+
run_block(block);
|
|
895
|
+
}
|
|
896
|
+
} catch (error) {
|
|
897
|
+
handle_error(error, block);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
// Phase 2: all other blocks except effects
|
|
902
|
+
arr_length = other_blocks.length;
|
|
903
|
+
for (var i = 0; i < arr_length; i++) {
|
|
904
|
+
var block = other_blocks[i];
|
|
905
|
+
|
|
906
|
+
try {
|
|
907
|
+
if ((block.f & (PAUSED | DESTROYED)) === 0 && is_block_dirty(block)) {
|
|
908
|
+
run_block(block);
|
|
909
|
+
}
|
|
910
|
+
} catch (error) {
|
|
911
|
+
handle_error(error, block);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
658
914
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
915
|
+
// Phase 3: effects
|
|
916
|
+
arr_length = effects.length;
|
|
917
|
+
for (var i = 0; i < arr_length; i++) {
|
|
918
|
+
var block = effects[i];
|
|
662
919
|
|
|
663
920
|
try {
|
|
664
|
-
if ((
|
|
665
|
-
run_block(
|
|
921
|
+
if ((block.f & (PAUSED | DESTROYED)) === 0 && is_block_dirty(block)) {
|
|
922
|
+
run_block(block);
|
|
666
923
|
}
|
|
667
924
|
} catch (error) {
|
|
668
|
-
handle_error(error,
|
|
925
|
+
handle_error(error, block);
|
|
669
926
|
}
|
|
670
927
|
}
|
|
671
928
|
}
|
|
@@ -677,6 +934,14 @@ function flush_queued_root_blocks(root_blocks) {
|
|
|
677
934
|
for (let i = 0; i < root_blocks.length; i++) {
|
|
678
935
|
flush_updates(root_blocks[i]);
|
|
679
936
|
}
|
|
937
|
+
|
|
938
|
+
if (queued_post_block_flush.length > 0) {
|
|
939
|
+
var callbacks = queued_post_block_flush;
|
|
940
|
+
queued_post_block_flush = [];
|
|
941
|
+
for (var j = 0; j < callbacks.length; j++) {
|
|
942
|
+
callbacks[j]();
|
|
943
|
+
}
|
|
944
|
+
}
|
|
680
945
|
}
|
|
681
946
|
|
|
682
947
|
/**
|
|
@@ -702,8 +967,9 @@ function flush_microtasks() {
|
|
|
702
967
|
|
|
703
968
|
flush_count++;
|
|
704
969
|
if (flush_count > 1001) {
|
|
705
|
-
|
|
706
|
-
|
|
970
|
+
throw new Error(
|
|
971
|
+
'Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state.',
|
|
972
|
+
);
|
|
707
973
|
}
|
|
708
974
|
var previous_queued_root_blocks = queued_root_blocks;
|
|
709
975
|
queued_root_blocks = [];
|
|
@@ -728,6 +994,16 @@ export function queue_microtask(fn) {
|
|
|
728
994
|
}
|
|
729
995
|
}
|
|
730
996
|
|
|
997
|
+
/**
|
|
998
|
+
* Queue a callback to run after all root blocks are flushed.
|
|
999
|
+
* Used to defer boundary completions so chained async deriveds evaluated during
|
|
1000
|
+
* the flush can start new requests before the boundary transitions out of pending.
|
|
1001
|
+
* @param {() => void} fn
|
|
1002
|
+
*/
|
|
1003
|
+
export function queue_post_block_flush_callback(fn) {
|
|
1004
|
+
queued_post_block_flush.push(fn);
|
|
1005
|
+
}
|
|
1006
|
+
|
|
731
1007
|
/**
|
|
732
1008
|
* @param {Block} block
|
|
733
1009
|
*/
|
|
@@ -751,7 +1027,7 @@ export function schedule_update(block) {
|
|
|
751
1027
|
}
|
|
752
1028
|
|
|
753
1029
|
/**
|
|
754
|
-
* @param {Tracked} tracked
|
|
1030
|
+
* @param {Tracked | Derived} tracked
|
|
755
1031
|
*/
|
|
756
1032
|
function register_dependency(tracked) {
|
|
757
1033
|
var dependency = active_dependency;
|
|
@@ -787,12 +1063,18 @@ export function get_derived(computed) {
|
|
|
787
1063
|
if (tracking) {
|
|
788
1064
|
register_dependency(computed);
|
|
789
1065
|
}
|
|
1066
|
+
var value = computed.__v;
|
|
790
1067
|
var get = computed.a.get;
|
|
791
1068
|
if (get !== undefined) {
|
|
792
|
-
|
|
1069
|
+
value = trigger_track_get(get, value);
|
|
1070
|
+
computed.__v = value;
|
|
793
1071
|
}
|
|
794
1072
|
|
|
795
|
-
|
|
1073
|
+
if (value === SUSPENSE_PENDING || value === SUSPENSE_REJECTED) {
|
|
1074
|
+
throw ASYNC_DERIVED_READ_THROWN;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
return value;
|
|
796
1078
|
}
|
|
797
1079
|
|
|
798
1080
|
/**
|
|
@@ -806,7 +1088,7 @@ export function get(tracked) {
|
|
|
806
1088
|
|
|
807
1089
|
return (tracked.f & DERIVED) !== 0
|
|
808
1090
|
? get_derived(/** @type {Derived} */ (tracked))
|
|
809
|
-
: get_tracked(tracked);
|
|
1091
|
+
: get_tracked(/** @type {Tracked} */ (tracked));
|
|
810
1092
|
}
|
|
811
1093
|
|
|
812
1094
|
/**
|
|
@@ -817,6 +1099,11 @@ export function get_tracked(tracked) {
|
|
|
817
1099
|
if (tracking) {
|
|
818
1100
|
register_dependency(tracked);
|
|
819
1101
|
}
|
|
1102
|
+
|
|
1103
|
+
if (value === SUSPENSE_PENDING || value === SUSPENSE_REJECTED) {
|
|
1104
|
+
throw ASYNC_DERIVED_READ_THROWN;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
820
1107
|
if (teardown && old_values.has(tracked)) {
|
|
821
1108
|
value = old_values.get(tracked);
|
|
822
1109
|
}
|
|
@@ -1203,6 +1490,7 @@ export function safe_scope(err = 'Cannot access outside of a component context')
|
|
|
1203
1490
|
|
|
1204
1491
|
export function create_component_ctx() {
|
|
1205
1492
|
return {
|
|
1493
|
+
b: active_block,
|
|
1206
1494
|
c: null,
|
|
1207
1495
|
e: null,
|
|
1208
1496
|
m: false,
|
|
@@ -1304,29 +1592,3 @@ export function exclude_from_object(obj, exclude_keys) {
|
|
|
1304
1592
|
|
|
1305
1593
|
return new_obj;
|
|
1306
1594
|
}
|
|
1307
|
-
|
|
1308
|
-
/**
|
|
1309
|
-
* @param {any} v
|
|
1310
|
-
* @returns {Promise<() => any>}
|
|
1311
|
-
*/
|
|
1312
|
-
export async function maybe_tracked(v) {
|
|
1313
|
-
var restore = capture();
|
|
1314
|
-
let value;
|
|
1315
|
-
|
|
1316
|
-
if (is_ripple_object(v)) {
|
|
1317
|
-
if ((v.f & DERIVED) !== 0) {
|
|
1318
|
-
value = await async_computed(v.fn, v.b);
|
|
1319
|
-
} else {
|
|
1320
|
-
value = await async_computed(async () => {
|
|
1321
|
-
return await get_tracked(v);
|
|
1322
|
-
}, /** @type {Block} */ (active_block));
|
|
1323
|
-
}
|
|
1324
|
-
} else {
|
|
1325
|
-
value = await v;
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
return () => {
|
|
1329
|
-
restore();
|
|
1330
|
-
return value;
|
|
1331
|
-
};
|
|
1332
|
-
}
|