chore: rename `$derived.call` to `$derived.by` (#10445)

* rename $derived.call to $derived.by

* more replacements, plus a compiler error

* regenerate types

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/10470/head
Rich Harris 11 months ago committed by GitHub
parent 9cee83c864
commit d41d0c26ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
breaking: replace `$derived.call` with `$derived.by`

@ -208,7 +208,8 @@ const runes = {
'invalid-runes-mode-import': (name) => `${name} cannot be used in runes mode`,
'duplicate-props-rune': () => `Cannot use $props() more than once`,
'invalid-each-assignment': () =>
`Cannot reassign or bind to each block argument in runes mode. Use the array and index variables instead (e.g. 'array[i] = value' instead of 'entry = value')`
`Cannot reassign or bind to each block argument in runes mode. Use the array and index variables instead (e.g. 'array[i] = value' instead of 'entry = value')`,
'invalid-derived-call': () => `$derived.call(...) has been replaced with $derived.by(...)`
};
/** @satisfies {Errors} */

@ -681,7 +681,7 @@ const runes_scope_js_tweaker = {
rune !== '$state' &&
rune !== '$state.frozen' &&
rune !== '$derived' &&
rune !== '$derived.call'
rune !== '$derived.by'
)
return;
@ -717,7 +717,7 @@ const runes_scope_tweaker = {
rune !== '$state' &&
rune !== '$state.frozen' &&
rune !== '$derived' &&
rune !== '$derived.call' &&
rune !== '$derived.by' &&
rune !== '$props'
)
return;
@ -730,7 +730,7 @@ const runes_scope_tweaker = {
? 'state'
: rune === '$state.frozen'
? 'frozen_state'
: rune === '$derived' || rune === '$derived.call'
: rune === '$derived' || rune === '$derived.by'
? 'derived'
: path.is_rest
? 'rest_prop'

@ -746,7 +746,7 @@ function validate_call_expression(node, scope, path) {
error(node, 'invalid-props-location');
}
if (rune === '$state' || rune === '$derived' || rune === '$derived.call') {
if (rune === '$state' || rune === '$derived' || rune === '$derived.by') {
if (parent.type === 'VariableDeclarator') return;
if (parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) return;
error(node, 'invalid-state-location', rune);
@ -817,7 +817,7 @@ export const validation_runes_js = {
const args = /** @type {import('estree').CallExpression} */ (init).arguments;
if ((rune === '$derived' || rune === '$derived.call') && args.length !== 1) {
if ((rune === '$derived' || rune === '$derived.by') && args.length !== 1) {
error(node, 'invalid-rune-args-length', rune, [1]);
} else if (rune === '$state' && args.length > 1) {
error(node, 'invalid-rune-args-length', rune, [0, 1]);
@ -842,7 +842,7 @@ export const validation_runes_js = {
definition.value?.type === 'CallExpression'
) {
const rune = get_rune(definition.value, context.state.scope);
if (rune === '$derived' || rune === '$derived.call') {
if (rune === '$derived' || rune === '$derived.by') {
private_derived_state.push(definition.key.name);
}
}
@ -988,7 +988,7 @@ export const validation_runes = merge(validation, a11y_validators, {
const args = /** @type {import('estree').CallExpression} */ (init).arguments;
// TODO some of this is duplicated with above, seems off
if ((rune === '$derived' || rune === '$derived.call') && args.length !== 1) {
if ((rune === '$derived' || rune === '$derived.by') && args.length !== 1) {
error(node, 'invalid-rune-args-length', rune, [1]);
} else if (rune === '$state' && args.length > 1) {
error(node, 'invalid-rune-args-length', rune, [0, 1]);

@ -33,7 +33,7 @@ export const javascript_visitors_runes = {
rune === '$state' ||
rune === '$state.frozen' ||
rune === '$derived' ||
rune === '$derived.call'
rune === '$derived.by'
) {
/** @type {import('../types.js').StateField} */
const field = {
@ -42,7 +42,7 @@ export const javascript_visitors_runes = {
? 'state'
: rune === '$state.frozen'
? 'frozen_state'
: rune === '$derived.call'
: rune === '$derived.by'
? 'derived_call'
: 'derived',
// @ts-expect-error this is set in the next pass
@ -289,12 +289,12 @@ export const javascript_visitors_runes = {
continue;
}
if (rune === '$derived' || rune === '$derived.call') {
if (rune === '$derived' || rune === '$derived.by') {
if (declarator.id.type === 'Identifier') {
declarations.push(
b.declarator(
declarator.id,
b.call('$.derived', rune === '$derived.call' ? value : b.thunk(value))
b.call('$.derived', rune === '$derived.by' ? value : b.thunk(value))
)
);
} else {
@ -307,7 +307,7 @@ export const javascript_visitors_runes = {
'$.derived',
b.thunk(
b.block([
b.let(declarator.id, rune === '$derived.call' ? b.call(value) : value),
b.let(declarator.id, rune === '$derived.by' ? b.call(value) : value),
b.return(b.array(bindings.map((binding) => binding.node)))
])
)

@ -548,7 +548,7 @@ const javascript_visitors_runes = {
: /** @type {import('estree').Expression} */ (visit(node.value.arguments[0]))
};
}
if (rune === '$derived.call') {
if (rune === '$derived.by') {
return {
...node,
value:
@ -582,7 +582,7 @@ const javascript_visitors_runes = {
? b.id('undefined')
: /** @type {import('estree').Expression} */ (visit(args[0]));
if (rune === '$derived.call') {
if (rune === '$derived.by') {
declarations.push(
b.declarator(
/** @type {import('estree').Pattern} */ (visit(declarator.id)),

@ -33,7 +33,7 @@ export const Runes = /** @type {const} */ ([
'$state.frozen',
'$props',
'$derived',
'$derived.call',
'$derived.by',
'$effect',
'$effect.pre',
'$effect.active',

@ -717,6 +717,8 @@ export function get_rune(node, scope) {
if (n.type !== 'Identifier') return null;
joined = n.name + joined;
if (joined === '$derived.call') error(node, 'invalid-derived-call');
if (!Runes.includes(/** @type {any} */ (joined))) return null;
const binding = scope.get(n.name);

@ -24,8 +24,7 @@ const runes = {
/** @param {string} name */
'non-state-reference': (name) =>
`${name} is updated, but is not declared with $state(...). Changing its value will not correctly trigger updates.`,
'derived-iife': () =>
`Use \`$derived.call(() => {...})\` instead of \`$derived((() => {...})());\``
'derived-iife': () => `Use \`$derived.by(() => {...})\` instead of \`$derived((() => {...})());\``
};
/** @satisfies {Warnings} */

@ -62,11 +62,11 @@ declare function $derived<T>(expression: T): T;
declare namespace $derived {
/**
* Sometimes you need to create complex derivations that don't fit inside a short expression.
* In these cases, you can use `$derived.call` which accepts a function as its argument.
* In these cases, you can use `$derived.by` which accepts a function as its argument.
*
* Example:
* ```ts
* let total = $derived.call(() => {
* let total = $derived.by(() => {
* let result = 0;
* for (const n of numbers) {
* result += n;
@ -75,9 +75,9 @@ declare namespace $derived {
* });
* ```
*
* https://svelte-5-preview.vercel.app/docs/runes#$derived-call
* https://svelte-5-preview.vercel.app/docs/runes#$derived-by
*/
export function call<T>(fn: () => T): T;
export function by<T>(fn: () => T): T;
}
/**

@ -1,7 +1,7 @@
<script>
class Counter {
count = $state(0);
doubled = $derived.call(() => this.count * 2);
doubled = $derived.by(() => this.count * 2);
}
const counter = new Counter();

@ -1,6 +1,6 @@
<script>
let count = $state(0);
let double = $derived.call(() => count * 2);
let double = $derived.by(() => count * 2);
</script>
<button on:click={() => count++}>{double}</button>

@ -2501,11 +2501,11 @@ declare function $derived<T>(expression: T): T;
declare namespace $derived {
/**
* Sometimes you need to create complex derivations that don't fit inside a short expression.
* In these cases, you can use `$derived.call` which accepts a function as its argument.
* In these cases, you can use `$derived.by` which accepts a function as its argument.
*
* Example:
* ```ts
* let total = $derived.call(() => {
* let total = $derived.by(() => {
* let result = 0;
* for (const n of numbers) {
* result += n;
@ -2514,9 +2514,9 @@ declare namespace $derived {
* });
* ```
*
* https://svelte-5-preview.vercel.app/docs/runes#$derived-call
* https://svelte-5-preview.vercel.app/docs/runes#$derived-by
*/
export function call<T>(fn: () => T): T;
export function by<T>(fn: () => T): T;
}
/**

@ -208,8 +208,8 @@
{ label: '$state', type: 'keyword', boost: 10 },
{ label: '$props', type: 'keyword', boost: 9 },
{ label: '$derived', type: 'keyword', boost: 8 },
snip('$derived.call(() => {\n\t${}\n});', {
label: '$derived.call',
snip('$derived.by(() => {\n\t${}\n});', {
label: '$derived.by',
type: 'keyword',
boost: 7
}),

@ -134,14 +134,14 @@ If the value of a reactive variable is being computed it should be replaced with
```
...`double` will be calculated first despite the source order. In runes mode, `triple` cannot reference `double` before it has been declared.
## `$derived.call`
## `$derived.by`
Sometimes you need to create complex derivations that don't fit inside a short expression. In these cases, you can use `$derived.call` which accepts a function as its argument.
Sometimes you need to create complex derivations that don't fit inside a short expression. In these cases, you can use `$derived.by` which accepts a function as its argument.
```svelte
<script>
let numbers = $state([1, 2, 3]);
let total = $derived.call(() => {
let total = $derived.by(() => {
let total = 0;
for (const n of numbers) {
total += n;
@ -155,7 +155,7 @@ Sometimes you need to create complex derivations that don't fit inside a short e
</button>
```
In essence, `$derived(expression)` is equivalent to `$derived.call(() => expression)`.
In essence, `$derived(expression)` is equivalent to `$derived.by(() => expression)`.
## `$effect`

Loading…
Cancel
Save