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
|
@@ -13,10 +13,14 @@ export const INERT = 1 << 13;
|
|
|
13
13
|
export const DESTROYED = 1 << 14;
|
|
14
14
|
|
|
15
15
|
// Flags exclusive to effects
|
|
16
|
+
/** Set once an effect that should run synchronously has run */
|
|
16
17
|
export const EFFECT_RAN = 1 << 15;
|
|
17
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* 'Transparent' effects do not create a transition boundary.
|
|
20
|
+
* This is on a block effect 99% of the time but may also be on a branch effect if its parent block effect was pruned
|
|
21
|
+
*/
|
|
18
22
|
export const EFFECT_TRANSPARENT = 1 << 16;
|
|
19
|
-
export const
|
|
23
|
+
export const EAGER_EFFECT = 1 << 17;
|
|
20
24
|
export const HEAD_EFFECT = 1 << 18;
|
|
21
25
|
export const EFFECT_PRESERVED = 1 << 19;
|
|
22
26
|
export const USER_EFFECT = 1 << 20;
|
|
@@ -128,7 +128,11 @@ export function setContext(key, context) {
|
|
|
128
128
|
|
|
129
129
|
if (async_mode_flag) {
|
|
130
130
|
var flags = /** @type {Effect} */ (active_effect).f;
|
|
131
|
-
var valid =
|
|
131
|
+
var valid =
|
|
132
|
+
!active_reaction &&
|
|
133
|
+
(flags & BRANCH_EFFECT) !== 0 &&
|
|
134
|
+
// pop() runs synchronously, so this indicates we're setting context after an await
|
|
135
|
+
!(/** @type {ComponentContext} */ (component_context).i);
|
|
132
136
|
|
|
133
137
|
if (!valid) {
|
|
134
138
|
e.set_context_after_init();
|
|
@@ -173,6 +177,7 @@ export function getAllContexts() {
|
|
|
173
177
|
export function push(props, runes = false, fn) {
|
|
174
178
|
component_context = {
|
|
175
179
|
p: component_context,
|
|
180
|
+
i: false,
|
|
176
181
|
c: null,
|
|
177
182
|
e: null,
|
|
178
183
|
s: props,
|
|
@@ -208,6 +213,8 @@ export function pop(component) {
|
|
|
208
213
|
context.x = component;
|
|
209
214
|
}
|
|
210
215
|
|
|
216
|
+
context.i = true;
|
|
217
|
+
|
|
211
218
|
component_context = context.p;
|
|
212
219
|
|
|
213
220
|
if (DEV) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UNINITIALIZED } from '../../../constants.js';
|
|
2
2
|
import { snapshot } from '../../shared/clone.js';
|
|
3
|
-
import {
|
|
3
|
+
import { eager_effect, render_effect, validate_effect } from '../reactivity/effects.js';
|
|
4
4
|
import { untrack } from '../runtime.js';
|
|
5
5
|
import { get_stack } from './tracing.js';
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@ export function inspect(get_value, inspector, show_stack = false) {
|
|
|
19
19
|
// stack traces. As a consequence, reading the value might result
|
|
20
20
|
// in an error (an `$inspect(object.property)` will run before the
|
|
21
21
|
// `{#if object}...{/if}` that contains it)
|
|
22
|
-
|
|
22
|
+
eager_effect(() => {
|
|
23
23
|
try {
|
|
24
24
|
var value = get_value();
|
|
25
25
|
} catch (e) {
|
|
@@ -33,8 +33,17 @@ export function inspect(get_value, inspector, show_stack = false) {
|
|
|
33
33
|
inspector(...snap);
|
|
34
34
|
|
|
35
35
|
if (!initial) {
|
|
36
|
+
const stack = get_stack('$inspect(...)');
|
|
36
37
|
// eslint-disable-next-line no-console
|
|
37
|
-
|
|
38
|
+
|
|
39
|
+
if (stack) {
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.groupCollapsed('stack trace');
|
|
42
|
+
// eslint-disable-next-line no-console
|
|
43
|
+
console.log(stack);
|
|
44
|
+
// eslint-disable-next-line no-console
|
|
45
|
+
console.groupEnd();
|
|
46
|
+
}
|
|
38
47
|
}
|
|
39
48
|
} else {
|
|
40
49
|
inspector(initial ? 'init' : 'update', ...snap);
|
|
@@ -179,8 +179,7 @@ export function get_stack(label) {
|
|
|
179
179
|
});
|
|
180
180
|
|
|
181
181
|
define_property(error, 'name', {
|
|
182
|
-
|
|
183
|
-
value: `${label}Error`
|
|
182
|
+
value: label
|
|
184
183
|
});
|
|
185
184
|
|
|
186
185
|
return /** @type {Error & { stack: string }} */ (error);
|
|
@@ -30,7 +30,6 @@ import {
|
|
|
30
30
|
skip_nodes,
|
|
31
31
|
set_hydrate_node
|
|
32
32
|
} from '../hydration.js';
|
|
33
|
-
import { get_next_sibling } from '../operations.js';
|
|
34
33
|
import { queue_micro_task } from '../task.js';
|
|
35
34
|
import * as e from '../../errors.js';
|
|
36
35
|
import * as w from '../../warnings.js';
|
|
@@ -39,6 +38,7 @@ import { Batch, effect_pending_updates } from '../../reactivity/batch.js';
|
|
|
39
38
|
import { internal_set, source } from '../../reactivity/sources.js';
|
|
40
39
|
import { tag } from '../../dev/tracing.js';
|
|
41
40
|
import { createSubscriber } from '../../../../reactivity/create-subscriber.js';
|
|
41
|
+
import { create_text } from '../operations.js';
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* @typedef {{
|
|
@@ -93,6 +93,9 @@ export class Boundary {
|
|
|
93
93
|
/** @type {DocumentFragment | null} */
|
|
94
94
|
#offscreen_fragment = null;
|
|
95
95
|
|
|
96
|
+
/** @type {TemplateNode | null} */
|
|
97
|
+
#pending_anchor = null;
|
|
98
|
+
|
|
96
99
|
#local_pending_count = 0;
|
|
97
100
|
#pending_count = 0;
|
|
98
101
|
|
|
@@ -156,8 +159,10 @@ export class Boundary {
|
|
|
156
159
|
this.#hydrate_resolved_content();
|
|
157
160
|
}
|
|
158
161
|
} else {
|
|
162
|
+
var anchor = this.#get_anchor();
|
|
163
|
+
|
|
159
164
|
try {
|
|
160
|
-
this.#main_effect = branch(() => children(
|
|
165
|
+
this.#main_effect = branch(() => children(anchor));
|
|
161
166
|
} catch (error) {
|
|
162
167
|
this.error(error);
|
|
163
168
|
}
|
|
@@ -168,6 +173,10 @@ export class Boundary {
|
|
|
168
173
|
this.#pending = false;
|
|
169
174
|
}
|
|
170
175
|
}
|
|
176
|
+
|
|
177
|
+
return () => {
|
|
178
|
+
this.#pending_anchor?.remove();
|
|
179
|
+
};
|
|
171
180
|
}, flags);
|
|
172
181
|
|
|
173
182
|
if (hydrating) {
|
|
@@ -195,9 +204,11 @@ export class Boundary {
|
|
|
195
204
|
this.#pending_effect = branch(() => pending(this.#anchor));
|
|
196
205
|
|
|
197
206
|
Batch.enqueue(() => {
|
|
207
|
+
var anchor = this.#get_anchor();
|
|
208
|
+
|
|
198
209
|
this.#main_effect = this.#run(() => {
|
|
199
210
|
Batch.ensure();
|
|
200
|
-
return branch(() => this.#children(
|
|
211
|
+
return branch(() => this.#children(anchor));
|
|
201
212
|
});
|
|
202
213
|
|
|
203
214
|
if (this.#pending_count > 0) {
|
|
@@ -212,6 +223,19 @@ export class Boundary {
|
|
|
212
223
|
});
|
|
213
224
|
}
|
|
214
225
|
|
|
226
|
+
#get_anchor() {
|
|
227
|
+
var anchor = this.#anchor;
|
|
228
|
+
|
|
229
|
+
if (this.#pending) {
|
|
230
|
+
this.#pending_anchor = create_text();
|
|
231
|
+
this.#anchor.before(this.#pending_anchor);
|
|
232
|
+
|
|
233
|
+
anchor = this.#pending_anchor;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return anchor;
|
|
237
|
+
}
|
|
238
|
+
|
|
215
239
|
/**
|
|
216
240
|
* Returns `true` if the effect exists inside a boundary whose pending snippet is shown
|
|
217
241
|
* @returns {boolean}
|
|
@@ -253,6 +277,7 @@ export class Boundary {
|
|
|
253
277
|
|
|
254
278
|
if (this.#main_effect !== null) {
|
|
255
279
|
this.#offscreen_fragment = document.createDocumentFragment();
|
|
280
|
+
this.#offscreen_fragment.append(/** @type {TemplateNode} */ (this.#pending_anchor));
|
|
256
281
|
move_effect(this.#main_effect, this.#offscreen_fragment);
|
|
257
282
|
}
|
|
258
283
|
|
|
@@ -402,6 +427,7 @@ export class Boundary {
|
|
|
402
427
|
if (failed) {
|
|
403
428
|
queue_micro_task(() => {
|
|
404
429
|
this.#failed_effect = this.#run(() => {
|
|
430
|
+
Batch.ensure();
|
|
405
431
|
this.#is_creating_fallback = true;
|
|
406
432
|
|
|
407
433
|
try {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/** @import { Effect, TemplateNode } from '#client' */
|
|
2
|
-
import { is_runes } from '../../context.js';
|
|
3
2
|
import { Batch, current_batch } from '../../reactivity/batch.js';
|
|
4
3
|
import {
|
|
5
4
|
branch,
|
|
@@ -8,7 +7,6 @@ import {
|
|
|
8
7
|
pause_effect,
|
|
9
8
|
resume_effect
|
|
10
9
|
} from '../../reactivity/effects.js';
|
|
11
|
-
import { set_should_intro, should_intro } from '../../render.js';
|
|
12
10
|
import { hydrate_node, hydrating } from '../hydration.js';
|
|
13
11
|
import { create_text, should_defer_append } from '../operations.js';
|
|
14
12
|
|
|
@@ -126,6 +124,22 @@ export class BranchManager {
|
|
|
126
124
|
}
|
|
127
125
|
};
|
|
128
126
|
|
|
127
|
+
/**
|
|
128
|
+
* @param {Batch} batch
|
|
129
|
+
*/
|
|
130
|
+
#discard = (batch) => {
|
|
131
|
+
this.#batches.delete(batch);
|
|
132
|
+
|
|
133
|
+
const keys = Array.from(this.#batches.values());
|
|
134
|
+
|
|
135
|
+
for (const [k, branch] of this.#offscreen) {
|
|
136
|
+
if (!keys.includes(k)) {
|
|
137
|
+
destroy_effect(branch.effect);
|
|
138
|
+
this.#offscreen.delete(k);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
129
143
|
/**
|
|
130
144
|
*
|
|
131
145
|
* @param {any} key
|
|
@@ -173,7 +187,8 @@ export class BranchManager {
|
|
|
173
187
|
}
|
|
174
188
|
}
|
|
175
189
|
|
|
176
|
-
batch.
|
|
190
|
+
batch.oncommit(this.#commit);
|
|
191
|
+
batch.ondiscard(this.#discard);
|
|
177
192
|
} else {
|
|
178
193
|
if (hydrating) {
|
|
179
194
|
this.anchor = hydrate_node;
|
|
@@ -7,7 +7,7 @@ import { add_form_reset_listener, autofocus } from './misc.js';
|
|
|
7
7
|
import * as w from '../../warnings.js';
|
|
8
8
|
import { LOADING_ATTR_SYMBOL } from '#client/constants';
|
|
9
9
|
import { queue_micro_task } from '../task.js';
|
|
10
|
-
import { is_capture_event,
|
|
10
|
+
import { is_capture_event, can_delegate_event, normalize_attribute } from '../../../../utils.js';
|
|
11
11
|
import {
|
|
12
12
|
active_effect,
|
|
13
13
|
active_reaction,
|
|
@@ -378,7 +378,7 @@ function set_attributes(
|
|
|
378
378
|
const opts = {};
|
|
379
379
|
const event_handle_key = '$$' + key;
|
|
380
380
|
let event_name = key.slice(2);
|
|
381
|
-
var delegated =
|
|
381
|
+
var delegated = can_delegate_event(event_name);
|
|
382
382
|
|
|
383
383
|
if (is_capture_event(event_name)) {
|
|
384
384
|
event_name = event_name.slice(0, -7);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { teardown } from '../../reactivity/effects.js';
|
|
2
|
-
import { define_property
|
|
2
|
+
import { define_property } from '../../../shared/utils.js';
|
|
3
3
|
import { hydrating } from '../hydration.js';
|
|
4
4
|
import { queue_micro_task } from '../task.js';
|
|
5
5
|
import { FILENAME } from '../../../../constants.js';
|
|
@@ -258,12 +258,7 @@ export function handle_event_propagation(event) {
|
|
|
258
258
|
// -> the target could not have been disabled because it emits the event in the first place
|
|
259
259
|
event.target === current_target)
|
|
260
260
|
) {
|
|
261
|
-
|
|
262
|
-
var [fn, ...data] = delegated;
|
|
263
|
-
fn.apply(current_target, [event, ...data]);
|
|
264
|
-
} else {
|
|
265
|
-
delegated.call(current_target, event);
|
|
266
|
-
}
|
|
261
|
+
delegated.call(current_target, event);
|
|
267
262
|
}
|
|
268
263
|
} catch (error) {
|
|
269
264
|
if (throw_error) {
|
|
@@ -29,7 +29,7 @@ export function handle_error(error) {
|
|
|
29
29
|
// if the error occurred while creating this subtree, we let it
|
|
30
30
|
// bubble up until it hits a boundary that can handle it
|
|
31
31
|
if ((effect.f & BOUNDARY_EFFECT) === 0) {
|
|
32
|
-
if (!effect.parent && error instanceof Error) {
|
|
32
|
+
if (DEV && !effect.parent && error instanceof Error) {
|
|
33
33
|
apply_adjustments(error);
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -61,7 +61,7 @@ export function invoke_error_boundary(error, effect) {
|
|
|
61
61
|
effect = effect.parent;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
if (error instanceof Error) {
|
|
64
|
+
if (DEV && error instanceof Error) {
|
|
65
65
|
apply_adjustments(error);
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -229,6 +229,22 @@ export function effect_update_depth_exceeded() {
|
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Cannot use `fork(...)` unless the `experimental.async` compiler option is `true`
|
|
234
|
+
* @returns {never}
|
|
235
|
+
*/
|
|
236
|
+
export function experimental_async_fork() {
|
|
237
|
+
if (DEV) {
|
|
238
|
+
const error = new Error(`experimental_async_fork\nCannot use \`fork(...)\` unless the \`experimental.async\` compiler option is \`true\`\nhttps://svelte.dev/e/experimental_async_fork`);
|
|
239
|
+
|
|
240
|
+
error.name = 'Svelte error';
|
|
241
|
+
|
|
242
|
+
throw error;
|
|
243
|
+
} else {
|
|
244
|
+
throw new Error(`https://svelte.dev/e/experimental_async_fork`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
232
248
|
/**
|
|
233
249
|
* Cannot use `flushSync` inside an effect
|
|
234
250
|
* @returns {never}
|
|
@@ -245,6 +261,38 @@ export function flush_sync_in_effect() {
|
|
|
245
261
|
}
|
|
246
262
|
}
|
|
247
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Cannot commit a fork that was already committed or discarded
|
|
266
|
+
* @returns {never}
|
|
267
|
+
*/
|
|
268
|
+
export function fork_discarded() {
|
|
269
|
+
if (DEV) {
|
|
270
|
+
const error = new Error(`fork_discarded\nCannot commit a fork that was already committed or discarded\nhttps://svelte.dev/e/fork_discarded`);
|
|
271
|
+
|
|
272
|
+
error.name = 'Svelte error';
|
|
273
|
+
|
|
274
|
+
throw error;
|
|
275
|
+
} else {
|
|
276
|
+
throw new Error(`https://svelte.dev/e/fork_discarded`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Cannot create a fork inside an effect or when state changes are pending
|
|
282
|
+
* @returns {never}
|
|
283
|
+
*/
|
|
284
|
+
export function fork_timing() {
|
|
285
|
+
if (DEV) {
|
|
286
|
+
const error = new Error(`fork_timing\nCannot create a fork inside an effect or when state changes are pending\nhttps://svelte.dev/e/fork_timing`);
|
|
287
|
+
|
|
288
|
+
error.name = 'Svelte error';
|
|
289
|
+
|
|
290
|
+
throw error;
|
|
291
|
+
} else {
|
|
292
|
+
throw new Error(`https://svelte.dev/e/fork_timing`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
248
296
|
/**
|
|
249
297
|
* `getAbortSignal()` can only be called inside an effect or derived
|
|
250
298
|
* @returns {never}
|
|
@@ -19,8 +19,8 @@ import {
|
|
|
19
19
|
state as source,
|
|
20
20
|
set,
|
|
21
21
|
increment,
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
flush_eager_effects,
|
|
23
|
+
set_eager_effects_deferred
|
|
24
24
|
} from './reactivity/sources.js';
|
|
25
25
|
import { PROXY_PATH_SYMBOL, STATE_SYMBOL } from '#client/constants';
|
|
26
26
|
import { UNINITIALIZED } from '../../constants.js';
|
|
@@ -53,7 +53,7 @@ export function proxy(value) {
|
|
|
53
53
|
var is_proxied_array = is_array(value);
|
|
54
54
|
var version = source(0);
|
|
55
55
|
|
|
56
|
-
var stack = DEV && tracing_mode_flag ? get_stack('
|
|
56
|
+
var stack = DEV && tracing_mode_flag ? get_stack('created at') : null;
|
|
57
57
|
var parent_version = update_version;
|
|
58
58
|
|
|
59
59
|
/**
|
|
@@ -421,9 +421,9 @@ function inspectable_array(array) {
|
|
|
421
421
|
* @param {any[]} args
|
|
422
422
|
*/
|
|
423
423
|
return function (...args) {
|
|
424
|
-
|
|
424
|
+
set_eager_effects_deferred();
|
|
425
425
|
var result = value.apply(this, args);
|
|
426
|
-
|
|
426
|
+
flush_eager_effects();
|
|
427
427
|
return result;
|
|
428
428
|
};
|
|
429
429
|
}
|