Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

breaking: rename $effect.active to $effect.tracking #12022

Merged
merged 6 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/khaki-cheetahs-refuse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte": patch
---

breaking: rename `$effect.active` to `$effect.tracking`
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ sites/svelte.dev/src/lib/generated
.prettierignore
.changeset
pnpm-lock.yaml
pnpm-workspace.yaml
pnpm-workspace.yaml
4 changes: 4 additions & 0 deletions packages/svelte/messages/compile-errors/script.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@

> Cannot use rune without parentheses

## rune_renamed

> `%name%` is now `%replacement%`

## runes_mode_invalid_import

> %name% cannot be used in runes mode
Expand Down
12 changes: 6 additions & 6 deletions packages/svelte/src/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,26 +201,26 @@ declare namespace $effect {
export function pre(fn: () => void | (() => void)): void;

/**
* 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.
* 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.
*
* Example:
* ```svelte
* <script>
* console.log('in component setup:', $effect.active()); // false
* console.log('in component setup:', $effect.tracking()); // false
*
* $effect(() => {
* console.log('in effect:', $effect.active()); // true
* console.log('in effect:', $effect.tracking()); // true
* });
* </script>
*
* <p>in template: {$effect.active()}</p> <!-- true -->
* <p>in template: {$effect.tracking()}</p> <!-- true -->
* ```
*
* This allows you to (for example) add things like subscriptions without causing memory leaks, by putting them in child effects.
*
* https://svelte-5-preview.vercel.app/docs/runes#$effect-active
* https://svelte-5-preview.vercel.app/docs/runes#$effect-tracking
*/
export function active(): boolean;
export function tracking(): boolean;

/**
* The `$effect.root` rune is an advanced feature that creates a non-tracked scope that doesn't auto-cleanup. This is useful for
Expand Down
11 changes: 11 additions & 0 deletions packages/svelte/src/compiler/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,17 @@ export function rune_missing_parentheses(node) {
e(node, "rune_missing_parentheses", "Cannot use rune without parentheses");
}

/**
* `%name%` is now `%replacement%`
* @param {null | number | NodeLike} node
* @param {string} name
* @param {string} replacement
* @returns {never}
*/
export function rune_renamed(node, name, replacement) {
e(node, "rune_renamed", `\`${name}\` is now \`${replacement}\``);
}

/**
* %name% cannot be used in runes mode
* @param {null | number | NodeLike} node
Expand Down
6 changes: 5 additions & 1 deletion packages/svelte/src/compiler/phases/2-analyze/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,7 @@ function validate_call_expression(node, scope, path) {
}
}

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

if (!Runes.includes(/** @type {Runes[number]} */ (name))) {
if (name === '$effect.active') {
e.rune_renamed(parent, '$effect.active', '$effect.tracking');
}

e.rune_invalid_name(parent, name);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export const javascript_visitors_runes = {
const rune = get_rune(init, state.scope);
if (
!rune ||
rune === '$effect.active' ||
rune === '$effect.tracking' ||
rune === '$effect.root' ||
rune === '$inspect' ||
rune === '$state.snapshot' ||
Expand Down Expand Up @@ -434,8 +434,8 @@ export const javascript_visitors_runes = {
return b.id('$$props.$$host');
}

if (rune === '$effect.active') {
return b.call('$.effect_active');
if (rune === '$effect.tracking') {
return b.call('$.effect_tracking');
}

if (rune === '$state.snapshot') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ const global_visitors = {
return b.id('undefined');
}

if (rune === '$effect.active') {
if (rune === '$effect.tracking') {
return b.literal(false);
}

Expand Down Expand Up @@ -571,7 +571,7 @@ const javascript_visitors_runes = {
for (const declarator of node.declarations) {
const init = declarator.init;
const rune = get_rune(init, state.scope);
if (!rune || rune === '$effect.active' || rune === '$inspect') {
if (!rune || rune === '$effect.tracking' || rune === '$inspect') {
declarations.push(/** @type {import('estree').VariableDeclarator} */ (visit(declarator)));
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/svelte/src/compiler/phases/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const Runes = /** @type {const} */ ([
'$derived.by',
'$effect',
'$effect.pre',
'$effect.active',
'$effect.tracking',
'$effect.root',
'$inspect',
'$inspect().with',
Expand Down
2 changes: 1 addition & 1 deletion packages/svelte/src/internal/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export {
} from './dom/template.js';
export { derived, derived_safe_equal } from './reactivity/deriveds.js';
export {
effect_active,
effect_tracking,
effect_root,
legacy_pre_effect,
legacy_pre_effect_reset,
Expand Down
7 changes: 5 additions & 2 deletions packages/svelte/src/internal/client/reactivity/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,13 @@ function create_effect(type, fn, sync) {
}

/**
* Internal representation of `$effect.active()`
* Internal representation of `$effect.tracking()`
* @returns {boolean}
*/
export function effect_active() {
export function effect_tracking() {
if (current_untracking) {
return false;
}
if (current_reaction && (current_reaction.f & DERIVED) !== 0) {
return (current_reaction.f & UNOWNED) === 0;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
let value = $state(false);
const fn = () => {
if ($effect.active()) {
if ($effect.tracking()) {
$effect(() => {
value = true;
});
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ export default test({
<p>false</p>
<p>false</p>
<p>false</p>
<p>false</p>
`,

html: `
<p>false</p>
<p>true</p>
<p>true</p>
<p>false</p>
`
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script>
import {untrack} from 'svelte';

const foo = $effect.tracking();
let bar = $state(false);
$effect.pre(() => {
bar = $effect.tracking();
});
</script>

<p>{foo}</p>
<p>{bar}</p>
<p>{$effect.tracking()}</p>
<p>{untrack(() => $effect.tracking())}</p>
12 changes: 6 additions & 6 deletions packages/svelte/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2830,26 +2830,26 @@ declare namespace $effect {
export function pre(fn: () => void | (() => void)): void;

/**
* 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.
* 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.
*
* Example:
* ```svelte
* <script>
* console.log('in component setup:', $effect.active()); // false
* console.log('in component setup:', $effect.tracking()); // false
*
* $effect(() => {
* console.log('in effect:', $effect.active()); // true
* console.log('in effect:', $effect.tracking()); // true
* });
* </script>
*
* <p>in template: {$effect.active()}</p> <!-- true -->
* <p>in template: {$effect.tracking()}</p> <!-- true -->
* ```
*
* This allows you to (for example) add things like subscriptions without causing memory leaks, by putting them in child effects.
*
* https://svelte-5-preview.vercel.app/docs/runes#$effect-active
* https://svelte-5-preview.vercel.app/docs/runes#$effect-tracking
*/
export function active(): boolean;
export function tracking(): boolean;

/**
* The `$effect.root` rune is an advanced feature that creates a non-tracked scope that doesn't auto-cleanup. This is useful for
Expand Down
2 changes: 1 addition & 1 deletion sites/svelte-5-preview/src/lib/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ const runes = [
{ snippet: '$effect.root(() => {\n\t${}\n})' },
{ snippet: '$state.snapshot(${})' },
{ snippet: '$state.is(${})' },
{ snippet: '$effect.active()' },
{ snippet: '$effect.tracking()' },
{ snippet: '$inspect(${});', test: is_statement }
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,20 +436,20 @@ Apart from the timing, `$effect.pre` works exactly like [`$effect`](#$effect)

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

## `$effect.active`
## `$effect.tracking`

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)):
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)):

```svelte
<script>
console.log('in component setup:', $effect.active()); // false
console.log('in component setup:', $effect.tracking()); // false

$effect(() => {
console.log('in effect:', $effect.active()); // true
console.log('in effect:', $effect.tracking()); // true
});
</script>

<p>in template: {$effect.active()}</p> <!-- true -->
<p>in template: {$effect.tracking()}</p> <!-- true -->
```

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