svelte 5.41.3 → 5.42.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.
- package/compiler/index.js +1 -1
- package/package.json +1 -1
- package/src/compiler/phases/2-analyze/index.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/Attribute.js +5 -183
- package/src/compiler/phases/2-analyze/visitors/shared/function.js +0 -7
- package/src/compiler/phases/3-transform/client/utils.js +2 -124
- package/src/compiler/phases/3-transform/client/visitors/FunctionDeclaration.js +0 -11
- package/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js +0 -18
- package/src/compiler/phases/3-transform/client/visitors/shared/events.js +1 -29
- package/src/compiler/phases/3-transform/client/visitors/shared/function.js +0 -13
- package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +2 -2
- package/src/compiler/phases/3-transform/utils.js +0 -19
- package/src/compiler/phases/nodes.js +1 -1
- package/src/compiler/utils/ast.js +8 -4
- package/src/compiler/utils/builders.js +5 -8
- package/src/index-client.js +1 -1
- package/src/index-server.js +4 -0
- package/src/internal/client/constants.js +6 -2
- package/src/internal/client/context.js +8 -1
- package/src/internal/client/dev/inspect.js +12 -3
- package/src/internal/client/dev/tracing.js +1 -2
- package/src/internal/client/dom/blocks/boundary.js +29 -3
- package/src/internal/client/dom/blocks/branches.js +18 -3
- package/src/internal/client/dom/blocks/each.js +1 -1
- package/src/internal/client/dom/elements/attributes.js +2 -2
- package/src/internal/client/dom/elements/events.js +2 -7
- package/src/internal/client/error-handling.js +2 -2
- package/src/internal/client/errors.js +48 -0
- package/src/internal/client/proxy.js +5 -5
- package/src/internal/client/reactivity/batch.js +160 -22
- package/src/internal/client/reactivity/deriveds.js +5 -5
- package/src/internal/client/reactivity/effects.js +13 -5
- package/src/internal/client/reactivity/sources.js +19 -19
- package/src/internal/client/runtime.js +2 -2
- package/src/utils.js +1 -1
- package/src/version.js +1 -1
- package/types/index.d.ts +39 -5
- package/types/index.d.ts.map +5 -3
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @import { Fork } from 'svelte' */
|
|
1
2
|
/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */
|
|
2
3
|
import {
|
|
3
4
|
BLOCK_EFFECT,
|
|
@@ -12,25 +13,35 @@ import {
|
|
|
12
13
|
ROOT_EFFECT,
|
|
13
14
|
MAYBE_DIRTY,
|
|
14
15
|
DERIVED,
|
|
15
|
-
BOUNDARY_EFFECT
|
|
16
|
+
BOUNDARY_EFFECT,
|
|
17
|
+
EAGER_EFFECT
|
|
16
18
|
} from '#client/constants';
|
|
17
19
|
import { async_mode_flag } from '../../flags/index.js';
|
|
18
20
|
import { deferred, define_property } from '../../shared/utils.js';
|
|
19
21
|
import {
|
|
20
22
|
active_effect,
|
|
21
23
|
get,
|
|
24
|
+
increment_write_version,
|
|
22
25
|
is_dirty,
|
|
23
26
|
is_updating_effect,
|
|
24
27
|
set_is_updating_effect,
|
|
25
28
|
set_signal_status,
|
|
29
|
+
tick,
|
|
26
30
|
update_effect
|
|
27
31
|
} from '../runtime.js';
|
|
28
32
|
import * as e from '../errors.js';
|
|
29
33
|
import { flush_tasks, queue_micro_task } from '../dom/task.js';
|
|
30
34
|
import { DEV } from 'esm-env';
|
|
31
35
|
import { invoke_error_boundary } from '../error-handling.js';
|
|
32
|
-
import {
|
|
33
|
-
|
|
36
|
+
import {
|
|
37
|
+
flush_eager_effects,
|
|
38
|
+
eager_effects,
|
|
39
|
+
old_values,
|
|
40
|
+
set_eager_effects,
|
|
41
|
+
source,
|
|
42
|
+
update
|
|
43
|
+
} from './sources.js';
|
|
44
|
+
import { eager_effect, unlink_effect } from './effects.js';
|
|
34
45
|
|
|
35
46
|
/**
|
|
36
47
|
* @typedef {{
|
|
@@ -90,14 +101,20 @@ export class Batch {
|
|
|
90
101
|
* They keys of this map are identical to `this.#current`
|
|
91
102
|
* @type {Map<Source, any>}
|
|
92
103
|
*/
|
|
93
|
-
|
|
104
|
+
previous = new Map();
|
|
94
105
|
|
|
95
106
|
/**
|
|
96
107
|
* When the batch is committed (and the DOM is updated), we need to remove old branches
|
|
97
108
|
* and append new ones by calling the functions added inside (if/each/key/etc) blocks
|
|
98
109
|
* @type {Set<() => void>}
|
|
99
110
|
*/
|
|
100
|
-
#
|
|
111
|
+
#commit_callbacks = new Set();
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* If a fork is discarded, we need to destroy any effects that are no longer needed
|
|
115
|
+
* @type {Set<(batch: Batch) => void>}
|
|
116
|
+
*/
|
|
117
|
+
#discard_callbacks = new Set();
|
|
101
118
|
|
|
102
119
|
/**
|
|
103
120
|
* The number of async effects that are currently in flight
|
|
@@ -135,6 +152,8 @@ export class Batch {
|
|
|
135
152
|
*/
|
|
136
153
|
skipped_effects = new Set();
|
|
137
154
|
|
|
155
|
+
is_fork = false;
|
|
156
|
+
|
|
138
157
|
/**
|
|
139
158
|
*
|
|
140
159
|
* @param {Effect[]} root_effects
|
|
@@ -159,15 +178,15 @@ export class Batch {
|
|
|
159
178
|
this.#traverse_effect_tree(root, target);
|
|
160
179
|
}
|
|
161
180
|
|
|
162
|
-
this
|
|
181
|
+
if (!this.is_fork) {
|
|
182
|
+
this.#resolve();
|
|
183
|
+
}
|
|
163
184
|
|
|
164
|
-
if (this.#blocking_pending > 0) {
|
|
185
|
+
if (this.#blocking_pending > 0 || this.is_fork) {
|
|
165
186
|
this.#defer_effects(target.effects);
|
|
166
187
|
this.#defer_effects(target.render_effects);
|
|
167
188
|
this.#defer_effects(target.block_effects);
|
|
168
189
|
} else {
|
|
169
|
-
// TODO append/detach blocks here, not in #commit
|
|
170
|
-
|
|
171
190
|
// If sources are written to, then work needs to happen in a separate batch, else prior sources would be mixed with
|
|
172
191
|
// newly updated sources, which could lead to infinite loops when effects run over and over again.
|
|
173
192
|
previous_batch = this;
|
|
@@ -271,8 +290,8 @@ export class Batch {
|
|
|
271
290
|
* @param {any} value
|
|
272
291
|
*/
|
|
273
292
|
capture(source, value) {
|
|
274
|
-
if (!this
|
|
275
|
-
this
|
|
293
|
+
if (!this.previous.has(source)) {
|
|
294
|
+
this.previous.set(source, value);
|
|
276
295
|
}
|
|
277
296
|
|
|
278
297
|
this.current.set(source, source.v);
|
|
@@ -289,16 +308,17 @@ export class Batch {
|
|
|
289
308
|
}
|
|
290
309
|
|
|
291
310
|
flush() {
|
|
311
|
+
this.activate();
|
|
312
|
+
|
|
292
313
|
if (queued_root_effects.length > 0) {
|
|
293
|
-
this.activate();
|
|
294
314
|
flush_effects();
|
|
295
315
|
|
|
296
316
|
if (current_batch !== null && current_batch !== this) {
|
|
297
317
|
// this can happen if a new batch was created during `flush_effects()`
|
|
298
318
|
return;
|
|
299
319
|
}
|
|
300
|
-
} else {
|
|
301
|
-
this
|
|
320
|
+
} else if (this.#pending === 0) {
|
|
321
|
+
this.process([]); // TODO this feels awkward
|
|
302
322
|
}
|
|
303
323
|
|
|
304
324
|
this.deactivate();
|
|
@@ -314,11 +334,16 @@ export class Batch {
|
|
|
314
334
|
}
|
|
315
335
|
}
|
|
316
336
|
|
|
337
|
+
discard() {
|
|
338
|
+
for (const fn of this.#discard_callbacks) fn(this);
|
|
339
|
+
this.#discard_callbacks.clear();
|
|
340
|
+
}
|
|
341
|
+
|
|
317
342
|
#resolve() {
|
|
318
343
|
if (this.#blocking_pending === 0) {
|
|
319
344
|
// append/remove branches
|
|
320
|
-
for (const fn of this.#
|
|
321
|
-
this.#
|
|
345
|
+
for (const fn of this.#commit_callbacks) fn();
|
|
346
|
+
this.#commit_callbacks.clear();
|
|
322
347
|
}
|
|
323
348
|
|
|
324
349
|
if (this.#pending === 0) {
|
|
@@ -332,7 +357,7 @@ export class Batch {
|
|
|
332
357
|
// committed state, unless the batch in question has a more
|
|
333
358
|
// recent value for a given source
|
|
334
359
|
if (batches.size > 1) {
|
|
335
|
-
this
|
|
360
|
+
this.previous.clear();
|
|
336
361
|
|
|
337
362
|
var previous_batch_values = batch_values;
|
|
338
363
|
var is_earlier = true;
|
|
@@ -428,6 +453,10 @@ export class Batch {
|
|
|
428
453
|
this.#pending -= 1;
|
|
429
454
|
if (blocking) this.#blocking_pending -= 1;
|
|
430
455
|
|
|
456
|
+
this.revive();
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
revive() {
|
|
431
460
|
for (const e of this.#dirty_effects) {
|
|
432
461
|
set_signal_status(e, DIRTY);
|
|
433
462
|
schedule_effect(e);
|
|
@@ -445,8 +474,13 @@ export class Batch {
|
|
|
445
474
|
}
|
|
446
475
|
|
|
447
476
|
/** @param {() => void} fn */
|
|
448
|
-
|
|
449
|
-
this.#
|
|
477
|
+
oncommit(fn) {
|
|
478
|
+
this.#commit_callbacks.add(fn);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/** @param {(batch: Batch) => void} fn */
|
|
482
|
+
ondiscard(fn) {
|
|
483
|
+
this.#discard_callbacks.add(fn);
|
|
450
484
|
}
|
|
451
485
|
|
|
452
486
|
settled() {
|
|
@@ -489,7 +523,7 @@ export class Batch {
|
|
|
489
523
|
for (const batch of batches) {
|
|
490
524
|
if (batch === this) continue;
|
|
491
525
|
|
|
492
|
-
for (const [source, previous] of batch
|
|
526
|
+
for (const [source, previous] of batch.previous) {
|
|
493
527
|
if (!batch_values.has(source)) {
|
|
494
528
|
batch_values.set(source, previous);
|
|
495
529
|
}
|
|
@@ -717,6 +751,28 @@ function mark_effects(value, sources, marked, checked) {
|
|
|
717
751
|
}
|
|
718
752
|
}
|
|
719
753
|
|
|
754
|
+
/**
|
|
755
|
+
* When committing a fork, we need to trigger eager effects so that
|
|
756
|
+
* any `$state.eager(...)` expressions update immediately. This
|
|
757
|
+
* function allows us to discover them
|
|
758
|
+
* @param {Value} value
|
|
759
|
+
* @param {Set<Effect>} effects
|
|
760
|
+
*/
|
|
761
|
+
function mark_eager_effects(value, effects) {
|
|
762
|
+
if (value.reactions === null) return;
|
|
763
|
+
|
|
764
|
+
for (const reaction of value.reactions) {
|
|
765
|
+
const flags = reaction.f;
|
|
766
|
+
|
|
767
|
+
if ((flags & DERIVED) !== 0) {
|
|
768
|
+
mark_eager_effects(/** @type {Derived} */ (reaction), effects);
|
|
769
|
+
} else if ((flags & EAGER_EFFECT) !== 0) {
|
|
770
|
+
set_signal_status(reaction, DIRTY);
|
|
771
|
+
effects.add(/** @type {Effect} */ (reaction));
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
720
776
|
/**
|
|
721
777
|
* @param {Reaction} reaction
|
|
722
778
|
* @param {Source[]} sources
|
|
@@ -798,9 +854,9 @@ export function eager(fn) {
|
|
|
798
854
|
|
|
799
855
|
get(version);
|
|
800
856
|
|
|
801
|
-
|
|
857
|
+
eager_effect(() => {
|
|
802
858
|
if (initial) {
|
|
803
|
-
// the first time this runs, we create an
|
|
859
|
+
// the first time this runs, we create an eager effect
|
|
804
860
|
// that will run eagerly whenever the expression changes
|
|
805
861
|
var previous_batch_values = batch_values;
|
|
806
862
|
|
|
@@ -829,6 +885,88 @@ export function eager(fn) {
|
|
|
829
885
|
return value;
|
|
830
886
|
}
|
|
831
887
|
|
|
888
|
+
/**
|
|
889
|
+
* Creates a 'fork', in which state changes are evaluated but not applied to the DOM.
|
|
890
|
+
* This is useful for speculatively loading data (for example) when you suspect that
|
|
891
|
+
* the user is about to take some action.
|
|
892
|
+
*
|
|
893
|
+
* Frameworks like SvelteKit can use this to preload data when the user touches or
|
|
894
|
+
* hovers over a link, making any subsequent navigation feel instantaneous.
|
|
895
|
+
*
|
|
896
|
+
* The `fn` parameter is a synchronous function that modifies some state. The
|
|
897
|
+
* state changes will be reverted after the fork is initialised, then reapplied
|
|
898
|
+
* if and when the fork is eventually committed.
|
|
899
|
+
*
|
|
900
|
+
* When it becomes clear that a fork will _not_ be committed (e.g. because the
|
|
901
|
+
* user navigated elsewhere), it must be discarded to avoid leaking memory.
|
|
902
|
+
*
|
|
903
|
+
* @param {() => void} fn
|
|
904
|
+
* @returns {Fork}
|
|
905
|
+
* @since 5.42
|
|
906
|
+
*/
|
|
907
|
+
export function fork(fn) {
|
|
908
|
+
if (!async_mode_flag) {
|
|
909
|
+
e.experimental_async_fork();
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
if (current_batch !== null) {
|
|
913
|
+
e.fork_timing();
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
const batch = Batch.ensure();
|
|
917
|
+
batch.is_fork = true;
|
|
918
|
+
|
|
919
|
+
const settled = batch.settled();
|
|
920
|
+
|
|
921
|
+
flushSync(fn);
|
|
922
|
+
|
|
923
|
+
// revert state changes
|
|
924
|
+
for (const [source, value] of batch.previous) {
|
|
925
|
+
source.v = value;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
return {
|
|
929
|
+
commit: async () => {
|
|
930
|
+
if (!batches.has(batch)) {
|
|
931
|
+
e.fork_discarded();
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
batch.is_fork = false;
|
|
935
|
+
|
|
936
|
+
// apply changes
|
|
937
|
+
for (const [source, value] of batch.current) {
|
|
938
|
+
source.v = value;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
// trigger any `$state.eager(...)` expressions with the new state.
|
|
942
|
+
// eager effects don't get scheduled like other effects, so we
|
|
943
|
+
// can't just encounter them during traversal, we need to
|
|
944
|
+
// proactively flush them
|
|
945
|
+
// TODO maybe there's a better implementation?
|
|
946
|
+
flushSync(() => {
|
|
947
|
+
/** @type {Set<Effect>} */
|
|
948
|
+
const eager_effects = new Set();
|
|
949
|
+
|
|
950
|
+
for (const source of batch.current.keys()) {
|
|
951
|
+
mark_eager_effects(source, eager_effects);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
set_eager_effects(eager_effects);
|
|
955
|
+
flush_eager_effects();
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
batch.revive();
|
|
959
|
+
await settled;
|
|
960
|
+
},
|
|
961
|
+
discard: () => {
|
|
962
|
+
if (batches.has(batch)) {
|
|
963
|
+
batches.delete(batch);
|
|
964
|
+
batch.discard();
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
|
|
832
970
|
/**
|
|
833
971
|
* Forcibly remove all current batches, to prevent cross-talk between tests
|
|
834
972
|
*/
|
|
@@ -28,7 +28,7 @@ import { equals, safe_equals } from './equality.js';
|
|
|
28
28
|
import * as e from '../errors.js';
|
|
29
29
|
import * as w from '../warnings.js';
|
|
30
30
|
import { async_effect, destroy_effect, teardown } from './effects.js';
|
|
31
|
-
import {
|
|
31
|
+
import { eager_effects, internal_set, set_eager_effects, source } from './sources.js';
|
|
32
32
|
import { get_stack } from '../dev/tracing.js';
|
|
33
33
|
import { async_mode_flag, tracing_mode_flag } from '../../flags/index.js';
|
|
34
34
|
import { Boundary } from '../dom/blocks/boundary.js';
|
|
@@ -86,7 +86,7 @@ export function derived(fn) {
|
|
|
86
86
|
};
|
|
87
87
|
|
|
88
88
|
if (DEV && tracing_mode_flag) {
|
|
89
|
-
signal.created = get_stack('
|
|
89
|
+
signal.created = get_stack('created at');
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
return signal;
|
|
@@ -318,8 +318,8 @@ export function execute_derived(derived) {
|
|
|
318
318
|
set_active_effect(get_derived_parent_effect(derived));
|
|
319
319
|
|
|
320
320
|
if (DEV) {
|
|
321
|
-
let
|
|
322
|
-
|
|
321
|
+
let prev_eager_effects = eager_effects;
|
|
322
|
+
set_eager_effects(new Set());
|
|
323
323
|
try {
|
|
324
324
|
if (stack.includes(derived)) {
|
|
325
325
|
e.derived_references_self();
|
|
@@ -332,7 +332,7 @@ export function execute_derived(derived) {
|
|
|
332
332
|
value = update_reaction(derived);
|
|
333
333
|
} finally {
|
|
334
334
|
set_active_effect(prev_active_effect);
|
|
335
|
-
|
|
335
|
+
set_eager_effects(prev_eager_effects);
|
|
336
336
|
stack.pop();
|
|
337
337
|
}
|
|
338
338
|
} else {
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
DERIVED,
|
|
28
28
|
UNOWNED,
|
|
29
29
|
CLEAN,
|
|
30
|
-
|
|
30
|
+
EAGER_EFFECT,
|
|
31
31
|
HEAD_EFFECT,
|
|
32
32
|
MAYBE_DIRTY,
|
|
33
33
|
EFFECT_PRESERVED,
|
|
@@ -88,7 +88,7 @@ function create_effect(type, fn, sync, push = true) {
|
|
|
88
88
|
|
|
89
89
|
if (DEV) {
|
|
90
90
|
// Ensure the parent is never an inspect effect
|
|
91
|
-
while (parent !== null && (parent.f &
|
|
91
|
+
while (parent !== null && (parent.f & EAGER_EFFECT) !== 0) {
|
|
92
92
|
parent = parent.parent;
|
|
93
93
|
}
|
|
94
94
|
}
|
|
@@ -149,6 +149,9 @@ function create_effect(type, fn, sync, push = true) {
|
|
|
149
149
|
(e.f & EFFECT_PRESERVED) === 0
|
|
150
150
|
) {
|
|
151
151
|
e = e.first;
|
|
152
|
+
if ((type & BLOCK_EFFECT) !== 0 && (type & EFFECT_TRANSPARENT) !== 0 && e !== null) {
|
|
153
|
+
e.f |= EFFECT_TRANSPARENT;
|
|
154
|
+
}
|
|
152
155
|
}
|
|
153
156
|
|
|
154
157
|
if (e !== null) {
|
|
@@ -242,8 +245,8 @@ export function user_pre_effect(fn) {
|
|
|
242
245
|
}
|
|
243
246
|
|
|
244
247
|
/** @param {() => void | (() => void)} fn */
|
|
245
|
-
export function
|
|
246
|
-
return create_effect(
|
|
248
|
+
export function eager_effect(fn) {
|
|
249
|
+
return create_effect(EAGER_EFFECT, fn, true);
|
|
247
250
|
}
|
|
248
251
|
|
|
249
252
|
/**
|
|
@@ -604,7 +607,12 @@ export function pause_children(effect, transitions, local) {
|
|
|
604
607
|
|
|
605
608
|
while (child !== null) {
|
|
606
609
|
var sibling = child.next;
|
|
607
|
-
var transparent =
|
|
610
|
+
var transparent =
|
|
611
|
+
(child.f & EFFECT_TRANSPARENT) !== 0 ||
|
|
612
|
+
// If this is a branch effect without a block effect parent,
|
|
613
|
+
// it means the parent block effect was pruned. In that case,
|
|
614
|
+
// transparency information was transferred to the branch effect.
|
|
615
|
+
((child.f & BRANCH_EFFECT) !== 0 && (effect.f & BLOCK_EFFECT) !== 0);
|
|
608
616
|
// TODO we don't need to call pause_children recursively with a linked list in place
|
|
609
617
|
// it's slightly more involved though as we have to account for `transparent` changing
|
|
610
618
|
// through the tree.
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
DERIVED,
|
|
23
23
|
DIRTY,
|
|
24
24
|
BRANCH_EFFECT,
|
|
25
|
-
|
|
25
|
+
EAGER_EFFECT,
|
|
26
26
|
UNOWNED,
|
|
27
27
|
MAYBE_DIRTY,
|
|
28
28
|
BLOCK_EFFECT,
|
|
@@ -39,7 +39,7 @@ import { proxy } from '../proxy.js';
|
|
|
39
39
|
import { execute_derived } from './deriveds.js';
|
|
40
40
|
|
|
41
41
|
/** @type {Set<any>} */
|
|
42
|
-
export let
|
|
42
|
+
export let eager_effects = new Set();
|
|
43
43
|
|
|
44
44
|
/** @type {Map<Source, any>} */
|
|
45
45
|
export const old_values = new Map();
|
|
@@ -47,14 +47,14 @@ export const old_values = new Map();
|
|
|
47
47
|
/**
|
|
48
48
|
* @param {Set<any>} v
|
|
49
49
|
*/
|
|
50
|
-
export function
|
|
51
|
-
|
|
50
|
+
export function set_eager_effects(v) {
|
|
51
|
+
eager_effects = v;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
let
|
|
54
|
+
let eager_effects_deferred = false;
|
|
55
55
|
|
|
56
|
-
export function
|
|
57
|
-
|
|
56
|
+
export function set_eager_effects_deferred() {
|
|
57
|
+
eager_effects_deferred = true;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/**
|
|
@@ -76,7 +76,7 @@ export function source(v, stack) {
|
|
|
76
76
|
};
|
|
77
77
|
|
|
78
78
|
if (DEV && tracing_mode_flag) {
|
|
79
|
-
signal.created = stack ?? get_stack('
|
|
79
|
+
signal.created = stack ?? get_stack('created at');
|
|
80
80
|
signal.updated = null;
|
|
81
81
|
signal.set_during_effect = false;
|
|
82
82
|
signal.trace = null;
|
|
@@ -146,9 +146,9 @@ export function set(source, value, should_proxy = false) {
|
|
|
146
146
|
active_reaction !== null &&
|
|
147
147
|
// since we are untracking the function inside `$inspect.with` we need to add this check
|
|
148
148
|
// to ensure we error if state is set inside an inspect effect
|
|
149
|
-
(!untracking || (active_reaction.f &
|
|
149
|
+
(!untracking || (active_reaction.f & EAGER_EFFECT) !== 0) &&
|
|
150
150
|
is_runes() &&
|
|
151
|
-
(active_reaction.f & (DERIVED | BLOCK_EFFECT | ASYNC |
|
|
151
|
+
(active_reaction.f & (DERIVED | BLOCK_EFFECT | ASYNC | EAGER_EFFECT)) !== 0 &&
|
|
152
152
|
!current_sources?.includes(source)
|
|
153
153
|
) {
|
|
154
154
|
e.state_unsafe_mutation();
|
|
@@ -186,7 +186,7 @@ export function internal_set(source, value) {
|
|
|
186
186
|
|
|
187
187
|
if (DEV) {
|
|
188
188
|
if (tracing_mode_flag || active_effect !== null) {
|
|
189
|
-
const error = get_stack('
|
|
189
|
+
const error = get_stack('updated at');
|
|
190
190
|
|
|
191
191
|
if (error !== null) {
|
|
192
192
|
source.updated ??= new Map();
|
|
@@ -235,18 +235,18 @@ export function internal_set(source, value) {
|
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
if (
|
|
239
|
-
|
|
238
|
+
if (!batch.is_fork && eager_effects.size > 0 && !eager_effects_deferred) {
|
|
239
|
+
flush_eager_effects();
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
return value;
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
export function
|
|
247
|
-
|
|
246
|
+
export function flush_eager_effects() {
|
|
247
|
+
eager_effects_deferred = false;
|
|
248
248
|
|
|
249
|
-
const inspects = Array.from(
|
|
249
|
+
const inspects = Array.from(eager_effects);
|
|
250
250
|
|
|
251
251
|
for (const effect of inspects) {
|
|
252
252
|
// Mark clean inspect-effects as maybe dirty and then check their dirtiness
|
|
@@ -260,7 +260,7 @@ export function flush_inspect_effects() {
|
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
|
|
263
|
+
eager_effects.clear();
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
/**
|
|
@@ -320,8 +320,8 @@ function mark_reactions(signal, status) {
|
|
|
320
320
|
if (!runes && reaction === active_effect) continue;
|
|
321
321
|
|
|
322
322
|
// Inspect effects need to run immediately, so that the stack trace makes sense
|
|
323
|
-
if (DEV && (flags &
|
|
324
|
-
|
|
323
|
+
if (DEV && (flags & EAGER_EFFECT) !== 0) {
|
|
324
|
+
eager_effects.add(reaction);
|
|
325
325
|
continue;
|
|
326
326
|
}
|
|
327
327
|
|
|
@@ -609,7 +609,7 @@ export function get(signal) {
|
|
|
609
609
|
if (!tracking && !untracking && !was_read) {
|
|
610
610
|
w.await_reactivity_loss(/** @type {string} */ (signal.label));
|
|
611
611
|
|
|
612
|
-
var trace = get_stack('
|
|
612
|
+
var trace = get_stack('traced at');
|
|
613
613
|
// eslint-disable-next-line no-console
|
|
614
614
|
if (trace) console.warn(trace);
|
|
615
615
|
}
|
|
@@ -628,7 +628,7 @@ export function get(signal) {
|
|
|
628
628
|
if (signal.trace) {
|
|
629
629
|
signal.trace();
|
|
630
630
|
} else {
|
|
631
|
-
trace = get_stack('
|
|
631
|
+
trace = get_stack('traced at');
|
|
632
632
|
|
|
633
633
|
if (trace) {
|
|
634
634
|
var entry = tracing_expressions.entries.get(signal);
|
package/src/utils.js
CHANGED
|
@@ -137,7 +137,7 @@ const DELEGATED_EVENTS = [
|
|
|
137
137
|
* Returns `true` if `event_name` is a delegated event
|
|
138
138
|
* @param {string} event_name
|
|
139
139
|
*/
|
|
140
|
-
export function
|
|
140
|
+
export function can_delegate_event(event_name) {
|
|
141
141
|
return DELEGATED_EVENTS.includes(event_name);
|
|
142
142
|
}
|
|
143
143
|
|
package/src/version.js
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -348,6 +348,22 @@ declare module 'svelte' {
|
|
|
348
348
|
*/
|
|
349
349
|
props: Props;
|
|
350
350
|
});
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Represents work that is happening off-screen, such as data being preloaded
|
|
354
|
+
* in anticipation of the user navigating
|
|
355
|
+
* @since 5.42
|
|
356
|
+
*/
|
|
357
|
+
export interface Fork {
|
|
358
|
+
/**
|
|
359
|
+
* Commit the fork. The promise will resolve once the state change has been applied
|
|
360
|
+
*/
|
|
361
|
+
commit(): Promise<void>;
|
|
362
|
+
/**
|
|
363
|
+
* Discard the fork
|
|
364
|
+
*/
|
|
365
|
+
discard(): void;
|
|
366
|
+
}
|
|
351
367
|
/**
|
|
352
368
|
* Returns an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that aborts when the current [derived](https://svelte.dev/docs/svelte/$derived) or [effect](https://svelte.dev/docs/svelte/$effect) re-runs or is destroyed.
|
|
353
369
|
*
|
|
@@ -434,11 +450,6 @@ declare module 'svelte' {
|
|
|
434
450
|
* @deprecated Use [`$effect`](https://svelte.dev/docs/svelte/$effect) instead
|
|
435
451
|
* */
|
|
436
452
|
export function afterUpdate(fn: () => void): void;
|
|
437
|
-
/**
|
|
438
|
-
* Synchronously flush any pending updates.
|
|
439
|
-
* Returns void if no callback is provided, otherwise returns the result of calling the callback.
|
|
440
|
-
* */
|
|
441
|
-
export function flushSync<T = void>(fn?: (() => T) | undefined): T;
|
|
442
453
|
/**
|
|
443
454
|
* Create a snippet programmatically
|
|
444
455
|
* */
|
|
@@ -448,6 +459,29 @@ declare module 'svelte' {
|
|
|
448
459
|
}): Snippet<Params>;
|
|
449
460
|
/** Anything except a function */
|
|
450
461
|
type NotFunction<T> = T extends Function ? never : T;
|
|
462
|
+
/**
|
|
463
|
+
* Synchronously flush any pending updates.
|
|
464
|
+
* Returns void if no callback is provided, otherwise returns the result of calling the callback.
|
|
465
|
+
* */
|
|
466
|
+
export function flushSync<T = void>(fn?: (() => T) | undefined): T;
|
|
467
|
+
/**
|
|
468
|
+
* Creates a 'fork', in which state changes are evaluated but not applied to the DOM.
|
|
469
|
+
* This is useful for speculatively loading data (for example) when you suspect that
|
|
470
|
+
* the user is about to take some action.
|
|
471
|
+
*
|
|
472
|
+
* Frameworks like SvelteKit can use this to preload data when the user touches or
|
|
473
|
+
* hovers over a link, making any subsequent navigation feel instantaneous.
|
|
474
|
+
*
|
|
475
|
+
* The `fn` parameter is a synchronous function that modifies some state. The
|
|
476
|
+
* state changes will be reverted after the fork is initialised, then reapplied
|
|
477
|
+
* if and when the fork is eventually committed.
|
|
478
|
+
*
|
|
479
|
+
* When it becomes clear that a fork will _not_ be committed (e.g. because the
|
|
480
|
+
* user navigated elsewhere), it must be discarded to avoid leaking memory.
|
|
481
|
+
*
|
|
482
|
+
* @since 5.42
|
|
483
|
+
*/
|
|
484
|
+
export function fork(fn: () => void): Fork;
|
|
451
485
|
/**
|
|
452
486
|
* Returns a `[get, set]` pair of functions for working with context in a type-safe way.
|
|
453
487
|
*
|
package/types/index.d.ts.map
CHANGED
|
@@ -13,15 +13,17 @@
|
|
|
13
13
|
"Snippet",
|
|
14
14
|
"EventDispatcher",
|
|
15
15
|
"MountOptions",
|
|
16
|
+
"Fork",
|
|
16
17
|
"getAbortSignal",
|
|
17
18
|
"onMount",
|
|
18
19
|
"onDestroy",
|
|
19
20
|
"createEventDispatcher",
|
|
20
21
|
"beforeUpdate",
|
|
21
22
|
"afterUpdate",
|
|
22
|
-
"flushSync",
|
|
23
23
|
"createRawSnippet",
|
|
24
24
|
"NotFunction",
|
|
25
|
+
"flushSync",
|
|
26
|
+
"fork",
|
|
25
27
|
"createContext",
|
|
26
28
|
"getContext",
|
|
27
29
|
"setContext",
|
|
@@ -168,9 +170,9 @@
|
|
|
168
170
|
"sources": [
|
|
169
171
|
"../src/index.d.ts",
|
|
170
172
|
"../src/index-client.js",
|
|
171
|
-
"../src/internal/client/reactivity/batch.js",
|
|
172
173
|
"../src/internal/client/dom/blocks/snippet.js",
|
|
173
174
|
"../src/internal/types.d.ts",
|
|
175
|
+
"../src/internal/client/reactivity/batch.js",
|
|
174
176
|
"../src/internal/client/context.js",
|
|
175
177
|
"../src/internal/client/render.js",
|
|
176
178
|
"../src/internal/client/runtime.js",
|
|
@@ -261,6 +263,6 @@
|
|
|
261
263
|
null,
|
|
262
264
|
null
|
|
263
265
|
],
|
|
264
|
-
"mappings": ";;;;;;;kBAUiBA,2BAA2BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkC/BC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAwEhBC,kBAAkBA;;;;;;;;;;;;;;;;;;;;;;;;kBAwBbC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoCbC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;aAwBrBC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAiCfC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA6BdC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;kBAuBRC,OAAOA;;;;;;;;;;;;;;;;kBAgBPC,eAAeA;;;;;;;;;;;;;;;;aAgBpBC,YAAYA
|
|
266
|
+
"mappings": "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",
|
|
265
267
|
"ignoreList": []
|
|
266
268
|
}
|