Skip to content

Commit ccb3c90

Browse files
trueadmRich-Harris
andauthored
breaking: rename $effect.active to $effect.tracking (#12022)
* breaking: rename $effect.active to $effect.tracking * update type * add more helpful error * tweak changeset * fix prettier config --------- Co-authored-by: Rich Harris <rich.harris@vercel.com>
1 parent 9dc2d71 commit ccb3c90

File tree

18 files changed

+73
-41
lines changed

18 files changed

+73
-41
lines changed

.changeset/khaki-cheetahs-refuse.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+
breaking: rename `$effect.active` to `$effect.tracking`

.prettierignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ sites/svelte.dev/src/lib/generated
4444
.prettierignore
4545
.changeset
4646
pnpm-lock.yaml
47-
pnpm-workspace.yaml
47+
pnpm-workspace.yaml

packages/svelte/messages/compile-errors/script.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@
114114

115115
> Cannot use rune without parentheses
116116
117+
## rune_renamed
118+
119+
> `%name%` is now `%replacement%`
120+
117121
## runes_mode_invalid_import
118122

119123
> %name% cannot be used in runes mode

packages/svelte/src/ambient.d.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,26 +201,26 @@ declare namespace $effect {
201201
export function pre(fn: () => void | (() => void)): void;
202202

203203
/**
204-
* The `$effect.active` rune is an advanced feature that tells you whether or not the code is running inside an effect or inside your template.
204+
* The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template.
205205
*
206206
* Example:
207207
* ```svelte
208208
* <script>
209-
* console.log('in component setup:', $effect.active()); // false
209+
* console.log('in component setup:', $effect.tracking()); // false
210210
*
211211
* $effect(() => {
212-
* console.log('in effect:', $effect.active()); // true
212+
* console.log('in effect:', $effect.tracking()); // true
213213
* });
214214
* </script>
215215
*
216-
* <p>in template: {$effect.active()}</p> <!-- true -->
216+
* <p>in template: {$effect.tracking()}</p> <!-- true -->
217217
* ```
218218
*
219219
* This allows you to (for example) add things like subscriptions without causing memory leaks, by putting them in child effects.
220220
*
221-
* https://svelte-5-preview.vercel.app/docs/runes#$effect-active
221+
* https://svelte-5-preview.vercel.app/docs/runes#$effect-tracking
222222
*/
223-
export function active(): boolean;
223+
export function tracking(): boolean;
224224

225225
/**
226226
* The `$effect.root` rune is an advanced feature that creates a non-tracked scope that doesn't auto-cleanup. This is useful for

packages/svelte/src/compiler/errors.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,17 @@ export function rune_missing_parentheses(node) {
363363
e(node, "rune_missing_parentheses", "Cannot use rune without parentheses");
364364
}
365365

366+
/**
367+
* `%name%` is now `%replacement%`
368+
* @param {null | number | NodeLike} node
369+
* @param {string} name
370+
* @param {string} replacement
371+
* @returns {never}
372+
*/
373+
export function rune_renamed(node, name, replacement) {
374+
e(node, "rune_renamed", `\`${name}\` is now \`${replacement}\``);
375+
}
376+
366377
/**
367378
* %name% cannot be used in runes mode
368379
* @param {null | number | NodeLike} node

packages/svelte/src/compiler/phases/2-analyze/validation.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ function validate_call_expression(node, scope, path) {
880880
}
881881
}
882882

883-
if (rune === '$effect.active') {
883+
if (rune === '$effect.tracking') {
884884
if (node.arguments.length !== 0) {
885885
e.rune_invalid_arguments(node, rune);
886886
}
@@ -1141,6 +1141,10 @@ export const validation_runes = merge(validation, a11y_validators, {
11411141
parent = /** @type {import('estree').Expression} */ (path[--i]);
11421142

11431143
if (!Runes.includes(/** @type {Runes[number]} */ (name))) {
1144+
if (name === '$effect.active') {
1145+
e.rune_renamed(parent, '$effect.active', '$effect.tracking');
1146+
}
1147+
11441148
e.rune_invalid_name(parent, name);
11451149
}
11461150
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ export const javascript_visitors_runes = {
215215
const rune = get_rune(init, state.scope);
216216
if (
217217
!rune ||
218-
rune === '$effect.active' ||
218+
rune === '$effect.tracking' ||
219219
rune === '$effect.root' ||
220220
rune === '$inspect' ||
221221
rune === '$state.snapshot' ||
@@ -434,8 +434,8 @@ export const javascript_visitors_runes = {
434434
return b.id('$$props.$$host');
435435
}
436436

437-
if (rune === '$effect.active') {
438-
return b.call('$.effect_active');
437+
if (rune === '$effect.tracking') {
438+
return b.call('$.effect_tracking');
439439
}
440440

441441
if (rune === '$state.snapshot') {

packages/svelte/src/compiler/phases/3-transform/server/transform-server.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ const global_visitors = {
407407
return b.id('undefined');
408408
}
409409

410-
if (rune === '$effect.active') {
410+
if (rune === '$effect.tracking') {
411411
return b.literal(false);
412412
}
413413

@@ -571,7 +571,7 @@ const javascript_visitors_runes = {
571571
for (const declarator of node.declarations) {
572572
const init = declarator.init;
573573
const rune = get_rune(init, state.scope);
574-
if (!rune || rune === '$effect.active' || rune === '$inspect') {
574+
if (!rune || rune === '$effect.tracking' || rune === '$inspect') {
575575
declarations.push(/** @type {import('estree').VariableDeclarator} */ (visit(declarator)));
576576
continue;
577577
}

packages/svelte/src/compiler/phases/constants.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const Runes = /** @type {const} */ ([
3939
'$derived.by',
4040
'$effect',
4141
'$effect.pre',
42-
'$effect.active',
42+
'$effect.tracking',
4343
'$effect.root',
4444
'$inspect',
4545
'$inspect().with',

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export {
9090
} from './dom/template.js';
9191
export { derived, derived_safe_equal } from './reactivity/deriveds.js';
9292
export {
93-
effect_active,
93+
effect_tracking,
9494
effect_root,
9595
legacy_pre_effect,
9696
legacy_pre_effect_reset,

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,13 @@ function create_effect(type, fn, sync) {
139139
}
140140

141141
/**
142-
* Internal representation of `$effect.active()`
142+
* Internal representation of `$effect.tracking()`
143143
* @returns {boolean}
144144
*/
145-
export function effect_active() {
145+
export function effect_tracking() {
146+
if (current_untracking) {
147+
return false;
148+
}
146149
if (current_reaction && (current_reaction.f & DERIVED) !== 0) {
147150
return (current_reaction.f & UNOWNED) === 0;
148151
}

packages/svelte/tests/runtime-runes/samples/effect-active-derived/main.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script>
22
let value = $state(false);
33
const fn = () => {
4-
if ($effect.active()) {
4+
if ($effect.tracking()) {
55
$effect(() => {
66
value = true;
77
});

packages/svelte/tests/runtime-runes/samples/effect-active/main.svelte

Lines changed: 0 additions & 11 deletions
This file was deleted.

packages/svelte/tests/runtime-runes/samples/effect-active/_config.js renamed to packages/svelte/tests/runtime-runes/samples/effect-tracking/_config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ export default test({
55
<p>false</p>
66
<p>false</p>
77
<p>false</p>
8+
<p>false</p>
89
`,
910

1011
html: `
1112
<p>false</p>
1213
<p>true</p>
1314
<p>true</p>
15+
<p>false</p>
1416
`
1517
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script>
2+
import {untrack} from 'svelte';
3+
4+
const foo = $effect.tracking();
5+
let bar = $state(false);
6+
$effect.pre(() => {
7+
bar = $effect.tracking();
8+
});
9+
</script>
10+
11+
<p>{foo}</p>
12+
<p>{bar}</p>
13+
<p>{$effect.tracking()}</p>
14+
<p>{untrack(() => $effect.tracking())}</p>

packages/svelte/types/index.d.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,26 +2830,26 @@ declare namespace $effect {
28302830
export function pre(fn: () => void | (() => void)): void;
28312831

28322832
/**
2833-
* The `$effect.active` rune is an advanced feature that tells you whether or not the code is running inside an effect or inside your template.
2833+
* The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template.
28342834
*
28352835
* Example:
28362836
* ```svelte
28372837
* <script>
2838-
* console.log('in component setup:', $effect.active()); // false
2838+
* console.log('in component setup:', $effect.tracking()); // false
28392839
*
28402840
* $effect(() => {
2841-
* console.log('in effect:', $effect.active()); // true
2841+
* console.log('in effect:', $effect.tracking()); // true
28422842
* });
28432843
* </script>
28442844
*
2845-
* <p>in template: {$effect.active()}</p> <!-- true -->
2845+
* <p>in template: {$effect.tracking()}</p> <!-- true -->
28462846
* ```
28472847
*
28482848
* This allows you to (for example) add things like subscriptions without causing memory leaks, by putting them in child effects.
28492849
*
2850-
* https://svelte-5-preview.vercel.app/docs/runes#$effect-active
2850+
* https://svelte-5-preview.vercel.app/docs/runes#$effect-tracking
28512851
*/
2852-
export function active(): boolean;
2852+
export function tracking(): boolean;
28532853

28542854
/**
28552855
* The `$effect.root` rune is an advanced feature that creates a non-tracked scope that doesn't auto-cleanup. This is useful for

sites/svelte-5-preview/src/lib/autocomplete.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ const runes = [
119119
{ snippet: '$effect.root(() => {\n\t${}\n})' },
120120
{ snippet: '$state.snapshot(${})' },
121121
{ snippet: '$state.is(${})' },
122-
{ snippet: '$effect.active()' },
122+
{ snippet: '$effect.tracking()' },
123123
{ snippet: '$inspect(${});', test: is_statement }
124124
];
125125

sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -436,20 +436,20 @@ Apart from the timing, `$effect.pre` works exactly like [`$effect`](#$effect)
436436

437437
Previously, you would have used `beforeUpdate`, which — like `afterUpdate` — is deprecated in Svelte 5.
438438

439-
## `$effect.active`
439+
## `$effect.tracking`
440440

441-
The `$effect.active` rune is an advanced feature that tells you whether or not the code is running inside an effect or inside your template ([demo](/#H4sIAAAAAAAAE3XP0QrCMAwF0F-JRXAD595rLfgdzodRUyl0bVgzQcb-3VYFQfExl5tDMgvrPCYhT7MI_YBCiiOR2Aq-UxnSDT1jnlOcRlMSlczoiHUXOjYxpOhx5-O12rgAJg4UAwaGhDyR3Gxhjdai4V1v2N2wqus9tC3Y3ifMQjbehaqq4aBhLtEv_Or893icCsdLve-Caj8nBkU67zMO5HtGCfM3sKiWNKhV0zwVaBqd3x3ixVmHFyFLuJyXB-moOe8pAQAA)):
441+
The `$effect.tracking` rune is an advanced feature that tells you whether or not the code is running inside a tracking context, such as an effect or inside your template ([demo](/#H4sIAAAAAAAAE3XP0QrCMAwF0F-JRXAD595rLfgdzodRUyl0bVgzQcb-3VYFQfExl5tDMgvrPCYhT7MI_YBCiiOR2Aq-UxnSDT1jnlOcRlMSlczoiHUXOjYxpOhx5-O12rgAJg4UAwaGhDyR3Gxhjdai4V1v2N2wqus9tC3Y3ifMQjbehaqq4aBhLtEv_Or893icCsdLve-Caj8nBkU67zMO5HtGCfM3sKiWNKhV0zwVaBqd3x3ixVmHFyFLuJyXB-moOe8pAQAA)):
442442

443443
```svelte
444444
<script>
445-
console.log('in component setup:', $effect.active()); // false
445+
console.log('in component setup:', $effect.tracking()); // false
446446
447447
$effect(() => {
448-
console.log('in effect:', $effect.active()); // true
448+
console.log('in effect:', $effect.tracking()); // true
449449
});
450450
</script>
451451
452-
<p>in template: {$effect.active()}</p> <!-- true -->
452+
<p>in template: {$effect.tracking()}</p> <!-- true -->
453453
```
454454

455455
This allows you to (for example) add things like subscriptions without causing memory leaks, by putting them in child effects.

0 commit comments

Comments
 (0)