Skip to content

Commit e1da295

Browse files
committed
Merge branch 'main' into sequencing
2 parents 35bf9bb + 9bbc332 commit e1da295

File tree

9 files changed

+163
-156
lines changed

9 files changed

+163
-156
lines changed

.changeset/eleven-beers-yell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
feat: use implicit return for each block keys

packages/svelte/src/compiler/phases/3-transform/client/visitors/javascript-runes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ export const javascript_visitors_runes = {
371371
const func = context.visit(node.expression.arguments[0]);
372372
return {
373373
...node,
374-
expression: b.call('$.pre_effect', /** @type {import('estree').Expression} */ (func))
374+
expression: b.call('$.user_pre_effect', /** @type {import('estree').Expression} */ (func))
375375
};
376376
}
377377
}

packages/svelte/src/compiler/phases/3-transform/client/visitors/template.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ function setup_select_synchronization(value_binding, context) {
231231
context.state.init.push(
232232
b.stmt(
233233
b.call(
234-
'$.invalidate_effect',
234+
'$.pre_effect',
235235
b.thunk(
236236
b.block([
237237
b.stmt(
@@ -747,7 +747,7 @@ function serialize_inline_component(node, component_name, context) {
747747
binding_initializers.push(
748748
b.stmt(
749749
b.call(
750-
b.id('$.pre_effect'),
750+
b.id('$.user_pre_effect'),
751751
b.thunk(b.call(b.id('$.add_owner'), expression, b.id(component_name)))
752752
)
753753
)
@@ -2329,11 +2329,13 @@ export const template_visitors = {
23292329
const key_function = node.key
23302330
? b.arrow(
23312331
[node.context.type === 'Identifier' ? node.context : b.id('$$item'), index],
2332-
b.block(
2333-
declarations.concat(
2334-
b.return(/** @type {import('estree').Expression} */ (context.visit(node.key)))
2335-
)
2336-
)
2332+
declarations.length > 0
2333+
? b.block(
2334+
declarations.concat(
2335+
b.return(/** @type {import('estree').Expression} */ (context.visit(node.key)))
2336+
)
2337+
)
2338+
: /** @type {import('estree').Expression} */ (context.visit(node.key))
23372339
)
23382340
: b.literal(null);
23392341

@@ -2359,16 +2361,16 @@ export const template_visitors = {
23592361

23602362
args.push(
23612363
context.state.node,
2362-
each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection),
23632364
b.literal(each_type),
2365+
each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection),
23642366
key_function,
23652367
b.arrow([b.id('$$anchor'), item, index], b.block(declarations.concat(children)))
23662368
);
23672369
} else {
23682370
args.push(
23692371
context.state.node,
2370-
each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection),
23712372
b.literal(each_type),
2373+
each_node_meta.array_name ? each_node_meta.array_name : b.thunk(collection),
23722374
b.arrow([b.id('$$anchor'), item, index], b.block(declarations.concat(children)))
23732375
);
23742376
}

packages/svelte/src/internal/client/dom/blocks/each.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ export function set_current_each_item(item) {
4646
/**
4747
* @template V
4848
* @param {Element | Comment} anchor The next sibling node, or the parent node if this is a 'controlled' block
49-
* @param {() => V[]} get_collection
5049
* @param {number} flags
50+
* @param {() => V[]} get_collection
5151
* @param {null | ((item: V) => string)} get_key
5252
* @param {(anchor: null, item: V, index: import('#client').MaybeSource<number>) => void} render_fn
5353
* @param {null | ((anchor: Node | null) => void)} fallback_fn
5454
* @param {typeof reconcile_indexed_array | reconcile_tracked_array} reconcile_fn
5555
* @returns {void}
5656
*/
57-
function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, reconcile_fn) {
57+
function each(anchor, flags, get_collection, get_key, render_fn, fallback_fn, reconcile_fn) {
5858
/** @type {import('#client').EachState} */
5959
var state = { flags, items: [] };
6060

@@ -193,28 +193,28 @@ function each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, re
193193
/**
194194
* @template V
195195
* @param {Element | Comment} anchor
196-
* @param {() => V[]} get_collection
197196
* @param {number} flags
197+
* @param {() => V[]} get_collection
198198
* @param {null | ((item: V) => string)} get_key
199199
* @param {(anchor: null, item: V, index: import('#client').MaybeSource<number>) => void} render_fn
200200
* @param {null | ((anchor: Node | null) => void)} [fallback_fn]
201201
* @returns {void}
202202
*/
203-
export function each_keyed(anchor, get_collection, flags, get_key, render_fn, fallback_fn = null) {
204-
each(anchor, get_collection, flags, get_key, render_fn, fallback_fn, reconcile_tracked_array);
203+
export function each_keyed(anchor, flags, get_collection, get_key, render_fn, fallback_fn = null) {
204+
each(anchor, flags, get_collection, get_key, render_fn, fallback_fn, reconcile_tracked_array);
205205
}
206206

207207
/**
208208
* @template V
209209
* @param {Element | Comment} anchor
210-
* @param {() => V[]} get_collection
211210
* @param {number} flags
211+
* @param {() => V[]} get_collection
212212
* @param {(anchor: null, item: V, index: import('#client').MaybeSource<number>) => void} render_fn
213213
* @param {null | ((anchor: Node | null) => void)} [fallback_fn]
214214
* @returns {void}
215215
*/
216-
export function each_indexed(anchor, get_collection, flags, render_fn, fallback_fn = null) {
217-
each(anchor, get_collection, flags, null, render_fn, fallback_fn, reconcile_indexed_array);
216+
export function each_indexed(anchor, flags, get_collection, render_fn, fallback_fn = null) {
217+
each(anchor, flags, get_collection, null, render_fn, fallback_fn, reconcile_indexed_array);
218218
}
219219

220220
/**

packages/svelte/src/internal/client/dom/legacy/lifecycle.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { run } from '../../../common.js';
2-
import { pre_effect, user_effect } from '../../reactivity/effects.js';
2+
import { user_pre_effect, user_effect } from '../../reactivity/effects.js';
33
import {
44
current_component_context,
55
deep_read_state,
@@ -19,7 +19,7 @@ export function init() {
1919

2020
// beforeUpdate
2121
if (callbacks.b.length) {
22-
pre_effect(() => {
22+
user_pre_effect(() => {
2323
observe_all(context);
2424
callbacks.b.forEach(run);
2525
// beforeUpdate might change state that affects rendering, ensure the render effects following from it

packages/svelte/src/internal/client/reactivity/effects.js

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import {
77
destroy_children,
88
execute_effect,
99
get,
10+
is_flushing_effect,
1011
remove_reactions,
1112
schedule_effect,
13+
set_is_flushing_effect,
1214
set_signal_status,
1315
untrack
1416
} from '../runtime.js';
@@ -20,7 +22,8 @@ import {
2022
PRE_EFFECT,
2123
DESTROYED,
2224
INERT,
23-
IS_ELSEIF
25+
IS_ELSEIF,
26+
EFFECT_RAN
2427
} from '../constants.js';
2528
import { set } from './sources.js';
2629
import { noop } from '../../common.js';
@@ -35,7 +38,7 @@ import { remove } from '../dom/reconciler.js';
3538
*/
3639
function create_effect(type, fn, sync, init = true) {
3740
/** @type {import('#client').Effect} */
38-
const signal = {
41+
const effect = {
3942
parent: current_effect,
4043
dom: null,
4144
deps: null,
@@ -51,22 +54,34 @@ function create_effect(type, fn, sync, init = true) {
5154
};
5255

5356
if (current_effect !== null) {
54-
signal.l = current_effect.l + 1;
57+
effect.l = current_effect.l + 1;
5558
}
5659

5760
if (current_reaction !== null) {
5861
if (current_reaction.effects === null) {
59-
current_reaction.effects = [signal];
62+
current_reaction.effects = [effect];
6063
} else {
61-
current_reaction.effects.push(signal);
64+
current_reaction.effects.push(effect);
6265
}
6366
}
6467

6568
if (init) {
66-
schedule_effect(signal, sync);
69+
if (sync) {
70+
const previously_flushing_effect = is_flushing_effect;
71+
72+
try {
73+
set_is_flushing_effect(true);
74+
execute_effect(effect);
75+
effect.f |= EFFECT_RAN;
76+
} finally {
77+
set_is_flushing_effect(previously_flushing_effect);
78+
}
79+
} else {
80+
schedule_effect(effect);
81+
}
6782
}
6883

69-
return signal;
84+
return effect;
7085
}
7186

7287
/**
@@ -108,6 +123,24 @@ export function user_effect(fn) {
108123
return effect;
109124
}
110125

126+
/**
127+
* Internal representation of `$effect.pre(...)`
128+
* @param {() => void | (() => void)} fn
129+
* @returns {import('#client').Effect}
130+
*/
131+
export function user_pre_effect(fn) {
132+
if (current_effect === null) {
133+
throw new Error(
134+
'ERR_SVELTE_ORPHAN_EFFECT' +
135+
(DEV
136+
? ': The Svelte $effect.pre rune can only be used during component initialisation.'
137+
: '')
138+
);
139+
}
140+
141+
return pre_effect(fn);
142+
}
143+
111144
/**
112145
* Internal representation of `$effect.root(...)`
113146
* @param {() => void | (() => void)} fn
@@ -128,24 +161,6 @@ export function effect(fn) {
128161
return create_effect(EFFECT, fn, false);
129162
}
130163

131-
/**
132-
* Internal representation of `$effect.pre(...)`
133-
* @param {() => void | (() => void)} fn
134-
* @returns {import('#client').Effect}
135-
*/
136-
export function pre_effect(fn) {
137-
if (current_effect === null) {
138-
throw new Error(
139-
'ERR_SVELTE_ORPHAN_EFFECT' +
140-
(DEV
141-
? ': The Svelte $effect.pre rune can only be used during component initialisation.'
142-
: '')
143-
);
144-
}
145-
146-
return create_effect(PRE_EFFECT, fn, true);
147-
}
148-
149164
/**
150165
* Internal representation of `$: ..`
151166
* @param {() => any} deps
@@ -157,19 +172,15 @@ export function legacy_pre_effect(deps, fn) {
157172
current_component_context
158173
);
159174
const token = {};
160-
return create_effect(
161-
PRE_EFFECT,
162-
() => {
163-
deps();
164-
if (component_context.l1.includes(token)) {
165-
return;
166-
}
167-
component_context.l1.push(token);
168-
set(component_context.l2, true);
169-
return untrack(fn);
170-
},
171-
true
172-
);
175+
return pre_effect(() => {
176+
deps();
177+
if (component_context.l1.includes(token)) {
178+
return;
179+
}
180+
component_context.l1.push(token);
181+
set(component_context.l2, true);
182+
return untrack(fn);
183+
});
173184
}
174185

175186
export function legacy_pre_effect_reset() {
@@ -186,13 +197,10 @@ export function legacy_pre_effect_reset() {
186197
}
187198

188199
/**
189-
* This effect is used to ensure binding are kept in sync. We use a pre effect to ensure we run before the
190-
* bindings which are in later effects. However, we don't use a pre_effect directly as we don't want to flush anything.
191-
*
192200
* @param {() => void | (() => void)} fn
193201
* @returns {import('#client').Effect}
194202
*/
195-
export function invalidate_effect(fn) {
203+
export function pre_effect(fn) {
196204
return create_effect(PRE_EFFECT, fn, true);
197205
}
198206

packages/svelte/src/internal/client/reactivity/sources.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ export function set(signal, value) {
135135
) {
136136
if (current_dependencies !== null && current_dependencies.includes(signal)) {
137137
set_signal_status(current_effect, DIRTY);
138-
schedule_effect(current_effect, false);
138+
schedule_effect(current_effect);
139139
} else {
140140
if (current_untracked_writes === null) {
141141
set_current_untracked_writes([signal]);

0 commit comments

Comments
 (0)