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

chore: rename $derived.call to $derived.by #10445

Merged
merged 3 commits into from
Feb 13, 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/dirty-donuts-yell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

breaking: replace `$derived.call` with `$derived.by`
3 changes: 2 additions & 1 deletion packages/svelte/src/compiler/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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} */
Expand Down
6 changes: 3 additions & 3 deletions packages/svelte/src/compiler/phases/2-analyze/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ const runes_scope_js_tweaker = {
rune !== '$state' &&
rune !== '$state.frozen' &&
rune !== '$derived' &&
rune !== '$derived.call'
rune !== '$derived.by'
)
return;

Expand Down Expand Up @@ -717,7 +717,7 @@ const runes_scope_tweaker = {
rune !== '$state' &&
rune !== '$state.frozen' &&
rune !== '$derived' &&
rune !== '$derived.call' &&
rune !== '$derived.by' &&
rune !== '$props'
)
return;
Expand All @@ -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'
Expand Down
8 changes: 4 additions & 4 deletions packages/svelte/src/compiler/phases/2-analyze/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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]);
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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)))
])
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)),
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 @@ -33,7 +33,7 @@ export const Runes = /** @type {const} */ ([
'$state.frozen',
'$props',
'$derived',
'$derived.call',
'$derived.by',
'$effect',
'$effect.pre',
'$effect.active',
Expand Down
2 changes: 2 additions & 0 deletions packages/svelte/src/compiler/phases/scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions packages/svelte/src/compiler/warnings.js
Original file line number Diff line number Diff line change
Expand Up @@ -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} */
Expand Down
8 changes: 4 additions & 4 deletions packages/svelte/src/main/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
8 changes: 4 additions & 4 deletions packages/svelte/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions sites/svelte-5-preview/src/lib/CodeMirror.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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`

Expand Down
Loading