Skip to content

Commit 1f04045

Browse files
authored
chore: move legacy context stuff into its own object (#11298)
1 parent 7b55bd4 commit 1f04045

File tree

6 files changed

+75
-63
lines changed

6 files changed

+75
-63
lines changed

packages/svelte/src/index-client.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ export function onMount(fn) {
2121
throw new Error('onMount can only be used during component initialisation.');
2222
}
2323

24-
if (current_component_context.r) {
24+
if (current_component_context.l !== null) {
25+
init_update_callbacks(current_component_context).m.push(fn);
26+
} else {
2527
user_effect(() => {
2628
const cleanup = untrack(fn);
2729
if (typeof cleanup === 'function') return /** @type {() => void} */ (cleanup);
2830
});
29-
} else {
30-
init_update_callbacks(current_component_context).m.push(fn);
3131
}
3232
}
3333

@@ -129,7 +129,7 @@ export function beforeUpdate(fn) {
129129
throw new Error('beforeUpdate can only be used during component initialisation');
130130
}
131131

132-
if (current_component_context.r) {
132+
if (current_component_context.l === null) {
133133
throw new Error('beforeUpdate cannot be used in runes mode');
134134
}
135135

@@ -153,7 +153,7 @@ export function afterUpdate(fn) {
153153
throw new Error('afterUpdate can only be used during component initialisation.');
154154
}
155155

156-
if (current_component_context.r) {
156+
if (current_component_context.l === null) {
157157
throw new Error('afterUpdate cannot be used in runes mode');
158158
}
159159

@@ -162,10 +162,11 @@ export function afterUpdate(fn) {
162162

163163
/**
164164
* Legacy-mode: Init callbacks object for onMount/beforeUpdate/afterUpdate
165-
* @param {import('./internal/client/types.js').ComponentContext} context
165+
* @param {import('#client').ComponentContext} context
166166
*/
167167
function init_update_callbacks(context) {
168-
return (context.u ??= { a: [], b: [], m: [] });
168+
var l = /** @type {import('#client').ComponentContextLegacy} */ (context).l;
169+
return (l.u ??= { a: [], b: [], m: [] });
169170
}
170171

171172
/**

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import {
1414
* Legacy-mode only: Call `onMount` callbacks and set up `beforeUpdate`/`afterUpdate` effects
1515
*/
1616
export function init() {
17-
const context = /** @type {import('#client').ComponentContext} */ (current_component_context);
18-
const callbacks = context.u;
17+
const context = /** @type {import('#client').ComponentContextLegacy} */ (
18+
current_component_context
19+
);
1920

21+
const callbacks = context.l.u;
2022
if (!callbacks) return;
2123

2224
// beforeUpdate
@@ -58,11 +60,11 @@ export function init() {
5860
/**
5961
* Invoke the getter of all signals associated with a component
6062
* so they can be registered to the effect this function is called in.
61-
* @param {import('#client').ComponentContext} context
63+
* @param {import('#client').ComponentContextLegacy} context
6264
*/
6365
function observe_all(context) {
64-
if (context.d) {
65-
for (const signal of context.d) get(signal);
66+
if (context.l.s) {
67+
for (const signal of context.l.s) get(signal);
6668
}
6769

6870
deep_read_state(context.s);

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,11 @@ export function effect(fn) {
182182
* @param {() => void | (() => void)} fn
183183
*/
184184
export function legacy_pre_effect(deps, fn) {
185-
var context = /** @type {import('#client').ComponentContext} */ (current_component_context);
185+
var context = /** @type {import('#client').ComponentContextLegacy} */ (current_component_context);
186186

187187
/** @type {{ effect: null | import('#client').Effect, ran: boolean }} */
188188
var token = { effect: null, ran: false };
189-
context.l1.push(token);
189+
context.l.r1.push(token);
190190

191191
token.effect = render_effect(() => {
192192
deps();
@@ -196,19 +196,19 @@ export function legacy_pre_effect(deps, fn) {
196196
if (token.ran) return;
197197

198198
token.ran = true;
199-
set(context.l2, true);
199+
set(context.l.r2, true);
200200
untrack(fn);
201201
});
202202
}
203203

204204
export function legacy_pre_effect_reset() {
205-
var context = /** @type {import('#client').ComponentContext} */ (current_component_context);
205+
var context = /** @type {import('#client').ComponentContextLegacy} */ (current_component_context);
206206

207207
render_effect(() => {
208-
if (!get(context.l2)) return;
208+
if (!get(context.l.r2)) return;
209209

210210
// Run dirty `$:` statements
211-
for (var token of context.l1) {
211+
for (var token of context.l.r1) {
212212
var effect = token.effect;
213213

214214
if (check_dirtiness(effect)) {
@@ -218,7 +218,7 @@ export function legacy_pre_effect_reset() {
218218
token.ran = false;
219219
}
220220

221-
context.l2.v = false; // set directly to avoid rerunning this effect
221+
context.l.r2.v = false; // set directly to avoid rerunning this effect
222222
});
223223
}
224224

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ export function mutable_source(initial_value) {
5555

5656
// bind the signal to the component context, in case we need to
5757
// track updates to trigger beforeUpdate/afterUpdate callbacks
58-
if (current_component_context) {
59-
(current_component_context.d ??= []).push(s);
58+
if (current_component_context !== null && current_component_context.l !== null) {
59+
(current_component_context.l.s ??= []).push(s);
6060
}
6161

6262
return s;

packages/svelte/src/internal/client/runtime.js

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export function set_current_component_context(context) {
115115

116116
/** @returns {boolean} */
117117
export function is_runes() {
118-
return current_component_context !== null && current_component_context.r;
118+
return current_component_context !== null && current_component_context.l === null;
119119
}
120120

121121
/**
@@ -1043,29 +1043,24 @@ export async function value_or_fallback_async(value, fallback) {
10431043
*/
10441044
export function push(props, runes = false, fn) {
10451045
current_component_context = {
1046-
// exports (and props, if `accessors: true`)
1047-
x: null,
1048-
// context
1046+
p: current_component_context,
10491047
c: null,
1050-
// effects
10511048
e: null,
1052-
// mounted
10531049
m: false,
1054-
// parent
1055-
p: current_component_context,
1056-
// signals
1057-
d: null,
1058-
// props
10591050
s: props,
1060-
// runes
1061-
r: runes,
1062-
// legacy $:
1063-
l1: [],
1064-
l2: source(false),
1065-
// update_callbacks
1066-
u: null
1051+
x: null,
1052+
l: null
10671053
};
10681054

1055+
if (!runes) {
1056+
current_component_context.l = {
1057+
s: null,
1058+
u: null,
1059+
r1: [],
1060+
r2: source(false)
1061+
};
1062+
}
1063+
10691064
if (DEV) {
10701065
// component function
10711066
// @ts-expect-error

packages/svelte/src/internal/client/types.d.ts

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,51 @@ export type EventCallbackMap = Record<string, EventCallback | EventCallback[]>;
1010
// when the JS VM JITs the code.
1111

1212
export type ComponentContext = {
13-
/** local signals (needed for beforeUpdate/afterUpdate) */
14-
d: null | Source[];
15-
/** props */
16-
s: Record<string, unknown>;
17-
/** exports (and props, if `accessors: true`) */
18-
x: Record<string, any> | null;
19-
/** deferred effects */
20-
e: null | Array<() => void | (() => void)>;
21-
/** mounted */
22-
m: boolean;
2313
/** parent */
2414
p: null | ComponentContext;
2515
/** context */
2616
c: null | Map<unknown, unknown>;
27-
/** runes */
28-
r: boolean;
29-
/** legacy mode: if `$:` statements are allowed to run (ensures they only run once per render) */
30-
l1: any[];
31-
/** legacy mode: if `$:` statements are allowed to run (ensures they only run once per render) */
32-
l2: Source<boolean>;
33-
/** update_callbacks */
34-
u: null | {
35-
/** afterUpdate callbacks */
36-
a: Array<() => void>;
37-
/** beforeUpdate callbacks */
38-
b: Array<() => void>;
39-
/** onMount callbacks */
40-
m: Array<() => any>;
17+
/** deferred effects */
18+
e: null | Array<() => void | (() => void)>;
19+
/** mounted */
20+
m: boolean;
21+
/**
22+
* props — needed for legacy mode lifecycle functions, and for `createEventDispatcher`
23+
* @deprecated remove in 6.0
24+
*/
25+
s: Record<string, unknown>;
26+
/**
27+
* exports (and props, if `accessors: true`) — needed for `createEventDispatcher`
28+
* @deprecated remove in 6.0
29+
*/
30+
x: Record<string, any> | null;
31+
/**
32+
* legacy stuff
33+
* @deprecated remove in 6.0
34+
*/
35+
l: null | {
36+
/** local signals (needed for beforeUpdate/afterUpdate) */
37+
s: null | Source[];
38+
/** update_callbacks */
39+
u: null | {
40+
/** afterUpdate callbacks */
41+
a: Array<() => void>;
42+
/** beforeUpdate callbacks */
43+
b: Array<() => void>;
44+
/** onMount callbacks */
45+
m: Array<() => any>;
46+
};
47+
/** `$:` statements */
48+
r1: any[];
49+
/** This tracks whether `$:` statements have run in the current cycle, to ensure they only run once */
50+
r2: Source<boolean>;
4151
};
4252
};
4353

54+
export type ComponentContextLegacy = ComponentContext & {
55+
l: NonNullable<ComponentContext['l']>;
56+
};
57+
4458
export type Equals = (this: Value, value: unknown) => boolean;
4559

4660
export type TemplateNode = Text | Element | Comment;

0 commit comments

Comments
 (0)