From ccb3c90cd57ca9d764efab317ed1cb8e5282926e Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Fri, 14 Jun 2024 04:00:38 +0100 Subject: [PATCH] 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 --- .changeset/khaki-cheetahs-refuse.md | 5 +++++ .prettierignore | 2 +- packages/svelte/messages/compile-errors/script.md | 4 ++++ packages/svelte/src/ambient.d.ts | 12 ++++++------ packages/svelte/src/compiler/errors.js | 11 +++++++++++ .../src/compiler/phases/2-analyze/validation.js | 6 +++++- .../client/visitors/javascript-runes.js | 6 +++--- .../phases/3-transform/server/transform-server.js | 4 ++-- packages/svelte/src/compiler/phases/constants.js | 2 +- packages/svelte/src/internal/client/index.js | 2 +- .../src/internal/client/reactivity/effects.js | 7 +++++-- .../samples/effect-active-derived/main.svelte | 2 +- .../samples/effect-active/main.svelte | 11 ----------- .../{effect-active => effect-tracking}/_config.js | 2 ++ .../samples/effect-tracking/main.svelte | 14 ++++++++++++++ packages/svelte/types/index.d.ts | 12 ++++++------ sites/svelte-5-preview/src/lib/autocomplete.js | 2 +- .../src/routes/docs/content/01-api/02-runes.md | 10 +++++----- 18 files changed, 73 insertions(+), 41 deletions(-) create mode 100644 .changeset/khaki-cheetahs-refuse.md delete mode 100644 packages/svelte/tests/runtime-runes/samples/effect-active/main.svelte rename packages/svelte/tests/runtime-runes/samples/{effect-active => effect-tracking}/_config.js (85%) create mode 100644 packages/svelte/tests/runtime-runes/samples/effect-tracking/main.svelte diff --git a/.changeset/khaki-cheetahs-refuse.md b/.changeset/khaki-cheetahs-refuse.md new file mode 100644 index 000000000000..5ac5e7c15d74 --- /dev/null +++ b/.changeset/khaki-cheetahs-refuse.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +breaking: rename `$effect.active` to `$effect.tracking` diff --git a/.prettierignore b/.prettierignore index 7806e458e0df..0550f0a2df58 100644 --- a/.prettierignore +++ b/.prettierignore @@ -44,4 +44,4 @@ sites/svelte.dev/src/lib/generated .prettierignore .changeset pnpm-lock.yaml -pnpm-workspace.yaml \ No newline at end of file +pnpm-workspace.yaml diff --git a/packages/svelte/messages/compile-errors/script.md b/packages/svelte/messages/compile-errors/script.md index dbce3403d41a..cfa92ce0adf7 100644 --- a/packages/svelte/messages/compile-errors/script.md +++ b/packages/svelte/messages/compile-errors/script.md @@ -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 diff --git a/packages/svelte/src/ambient.d.ts b/packages/svelte/src/ambient.d.ts index 68d881ced09d..d024c5d5213b 100644 --- a/packages/svelte/src/ambient.d.ts +++ b/packages/svelte/src/ambient.d.ts @@ -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 * * - *

in template: {$effect.active()}

+ *

in template: {$effect.tracking()}

* ``` * * 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 diff --git a/packages/svelte/src/compiler/errors.js b/packages/svelte/src/compiler/errors.js index f4ce20c7401c..ee8afd8f5d88 100644 --- a/packages/svelte/src/compiler/errors.js +++ b/packages/svelte/src/compiler/errors.js @@ -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 diff --git a/packages/svelte/src/compiler/phases/2-analyze/validation.js b/packages/svelte/src/compiler/phases/2-analyze/validation.js index 473141bf3ec6..8ae8c264bdf4 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/validation.js +++ b/packages/svelte/src/compiler/phases/2-analyze/validation.js @@ -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); } @@ -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); } } diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/javascript-runes.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/javascript-runes.js index e08bb6c8ac1c..b35e01b2d7e7 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/javascript-runes.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/javascript-runes.js @@ -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' || @@ -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') { diff --git a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js index 3d21d6972fe3..5b0f16db9d31 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js @@ -407,7 +407,7 @@ const global_visitors = { return b.id('undefined'); } - if (rune === '$effect.active') { + if (rune === '$effect.tracking') { return b.literal(false); } @@ -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; } diff --git a/packages/svelte/src/compiler/phases/constants.js b/packages/svelte/src/compiler/phases/constants.js index 29474d79fa93..4201e54c7771 100644 --- a/packages/svelte/src/compiler/phases/constants.js +++ b/packages/svelte/src/compiler/phases/constants.js @@ -39,7 +39,7 @@ export const Runes = /** @type {const} */ ([ '$derived.by', '$effect', '$effect.pre', - '$effect.active', + '$effect.tracking', '$effect.root', '$inspect', '$inspect().with', diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index 2a747dda907e..148c64bb6942 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -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, diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index 356986dce926..6d2b5c4659f4 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -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; } diff --git a/packages/svelte/tests/runtime-runes/samples/effect-active-derived/main.svelte b/packages/svelte/tests/runtime-runes/samples/effect-active-derived/main.svelte index e4d46edd7738..a87690e8fe6d 100644 --- a/packages/svelte/tests/runtime-runes/samples/effect-active-derived/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/effect-active-derived/main.svelte @@ -1,7 +1,7 @@ - -

{foo}

-

{bar}

-

{$effect.active()}

diff --git a/packages/svelte/tests/runtime-runes/samples/effect-active/_config.js b/packages/svelte/tests/runtime-runes/samples/effect-tracking/_config.js similarity index 85% rename from packages/svelte/tests/runtime-runes/samples/effect-active/_config.js rename to packages/svelte/tests/runtime-runes/samples/effect-tracking/_config.js index 69ba5793b808..b28d3fe36057 100644 --- a/packages/svelte/tests/runtime-runes/samples/effect-active/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/effect-tracking/_config.js @@ -5,11 +5,13 @@ export default test({

false

false

false

+

false

`, html: `

false

true

true

+

false

` }); diff --git a/packages/svelte/tests/runtime-runes/samples/effect-tracking/main.svelte b/packages/svelte/tests/runtime-runes/samples/effect-tracking/main.svelte new file mode 100644 index 000000000000..bb4895888050 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/effect-tracking/main.svelte @@ -0,0 +1,14 @@ + + +

{foo}

+

{bar}

+

{$effect.tracking()}

+

{untrack(() => $effect.tracking())}

diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 9b03ac1deed4..d80f35ca960a 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -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 * * - *

in template: {$effect.active()}

+ *

in template: {$effect.tracking()}

* ``` * * 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 diff --git a/sites/svelte-5-preview/src/lib/autocomplete.js b/sites/svelte-5-preview/src/lib/autocomplete.js index 7fe6b8e4c1a1..750b9f2e7cc1 100644 --- a/sites/svelte-5-preview/src/lib/autocomplete.js +++ b/sites/svelte-5-preview/src/lib/autocomplete.js @@ -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 } ]; diff --git a/sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md b/sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md index 7e5509e73ab8..efd02e8993d9 100644 --- a/sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md +++ b/sites/svelte-5-preview/src/routes/docs/content/01-api/02-runes.md @@ -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 -

in template: {$effect.active()}

+

in template: {$effect.tracking()}

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