$derived.fn -> $derived.call

pull/10240/head
Rich Harris 3 years ago
parent f3681d8fc7
commit e3ff46e0de

@ -2,4 +2,4 @@
"svelte": patch "svelte": patch
--- ---
chore: add $derived.fn rune chore: add $derived.call rune

@ -674,7 +674,7 @@ const runes_scope_js_tweaker = {
rune !== '$state' && rune !== '$state' &&
rune !== '$state.frozen' && rune !== '$state.frozen' &&
rune !== '$derived' && rune !== '$derived' &&
rune !== '$derived.fn' rune !== '$derived.call'
) )
return; return;
@ -710,7 +710,7 @@ const runes_scope_tweaker = {
rune !== '$state' && rune !== '$state' &&
rune !== '$state.frozen' && rune !== '$state.frozen' &&
rune !== '$derived' && rune !== '$derived' &&
rune !== '$derived.fn' && rune !== '$derived.call' &&
rune !== '$props' rune !== '$props'
) )
return; return;
@ -723,7 +723,7 @@ const runes_scope_tweaker = {
? 'state' ? 'state'
: rune === '$state.frozen' : rune === '$state.frozen'
? 'frozen_state' ? 'frozen_state'
: rune === '$derived' || rune === '$derived.fn' : rune === '$derived' || rune === '$derived.call'
? 'derived' ? 'derived'
: path.is_rest : path.is_rest
? 'rest_prop' ? 'rest_prop'

@ -715,7 +715,7 @@ function validate_call_expression(node, scope, path) {
error(node, 'invalid-props-location'); error(node, 'invalid-props-location');
} }
if (rune === '$state' || rune === '$derived' || rune === '$derived.fn') { if (rune === '$state' || rune === '$derived' || rune === '$derived.call') {
if (parent.type === 'VariableDeclarator') return; if (parent.type === 'VariableDeclarator') return;
if (parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) return; if (parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) return;
error(node, rune === '$derived' ? 'invalid-derived-location' : 'invalid-state-location'); error(node, rune === '$derived' ? 'invalid-derived-location' : 'invalid-state-location');

@ -58,7 +58,7 @@ export interface ComponentClientTransformState extends ClientTransformState {
} }
export interface StateField { export interface StateField {
kind: 'state' | 'frozen_state' | 'derived' | 'derived_fn'; kind: 'state' | 'frozen_state' | 'derived' | 'derived_call';
id: PrivateIdentifier; id: PrivateIdentifier;
} }

@ -33,7 +33,7 @@ export const javascript_visitors_runes = {
rune === '$state' || rune === '$state' ||
rune === '$state.frozen' || rune === '$state.frozen' ||
rune === '$derived' || rune === '$derived' ||
rune === '$derived.fn' rune === '$derived.call'
) { ) {
/** @type {import('../types.js').StateField} */ /** @type {import('../types.js').StateField} */
const field = { const field = {
@ -42,8 +42,8 @@ export const javascript_visitors_runes = {
? 'state' ? 'state'
: rune === '$state.frozen' : rune === '$state.frozen'
? 'frozen_state' ? 'frozen_state'
: rune === '$derived.fn' : rune === '$derived.call'
? 'derived_fn' ? 'derived_call'
: 'derived', : 'derived',
// @ts-expect-error this is set in the next pass // @ts-expect-error this is set in the next pass
id: is_private ? definition.key : null id: is_private ? definition.key : null
@ -102,7 +102,7 @@ export const javascript_visitors_runes = {
'$.source', '$.source',
should_proxy_or_freeze(init) ? b.call('$.freeze', init) : init should_proxy_or_freeze(init) ? b.call('$.freeze', init) : init
) )
: field.kind === 'derived_fn' : field.kind === 'derived_call'
? b.call('$.derived', init) ? b.call('$.derived', init)
: b.call('$.derived', b.thunk(init)); : b.call('$.derived', b.thunk(init));
} else { } else {
@ -146,7 +146,7 @@ export const javascript_visitors_runes = {
); );
} }
if ((field.kind === 'derived' || field.kind === 'derived_fn') && state.options.dev) { if ((field.kind === 'derived' || field.kind === 'derived_call') && state.options.dev) {
body.push( body.push(
b.method( b.method(
'set', 'set',
@ -286,12 +286,12 @@ export const javascript_visitors_runes = {
continue; continue;
} }
if (rune === '$derived' || rune === '$derived.fn') { if (rune === '$derived' || rune === '$derived.call') {
if (declarator.id.type === 'Identifier') { if (declarator.id.type === 'Identifier') {
declarations.push( declarations.push(
b.declarator( b.declarator(
declarator.id, declarator.id,
b.call('$.derived', rune === '$derived.fn' ? value : b.thunk(value)) b.call('$.derived', rune === '$derived.call' ? value : b.thunk(value))
) )
); );
} else { } else {
@ -307,7 +307,7 @@ export const javascript_visitors_runes = {
b.block([ b.block([
b.let( b.let(
declarator.id, declarator.id,
rune === '$derived.fn' ? b.call(value, b.id('$$derived')) : value rune === '$derived.call' ? b.call(value, b.id('$$derived')) : value
), ),
b.return(b.array(bindings.map((binding) => binding.node))) b.return(b.array(bindings.map((binding) => binding.node)))
]) ])

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

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

@ -62,11 +62,11 @@ declare function $derived<T>(expression: T): T;
declare namespace $derived { declare namespace $derived {
/** /**
* Sometimes you need to create complex derivations which don't fit inside a short expression. * Sometimes you need to create complex derivations which don't fit inside a short expression.
* In this case, you can resort to `$derived.fn` which accepts a function as its argument and returns its value. * In this case, you can resort to `$derived.call` which accepts a function as its argument and returns its value.
* *
* Example: * Example:
* ```ts * ```ts
* $derived.fn(() => { * $derived.call(() => {
* let tmp = count; * let tmp = count;
* if (count > 10) { * if (count > 10) {
* tmp += 100; * tmp += 100;

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

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

@ -988,15 +988,15 @@ declare module 'svelte/compiler' {
filename?: string | undefined; filename?: string | undefined;
} | undefined): Promise<Processed>; } | undefined): Promise<Processed>;
export class CompileError extends Error { export class CompileError extends Error {
constructor(code: string, message: string, position: [number, number] | undefined); constructor(code: string, message: string, position: [number, number] | undefined);
filename: CompileError_1['filename']; filename: CompileError_1['filename'];
position: CompileError_1['position']; position: CompileError_1['position'];
start: CompileError_1['start']; start: CompileError_1['start'];
end: CompileError_1['end']; end: CompileError_1['end'];
code: string; code: string;
} }
@ -1007,9 +1007,9 @@ declare module 'svelte/compiler' {
* */ * */
export const VERSION: string; export const VERSION: string;
class Scope { class Scope {
constructor(root: ScopeRoot, parent: Scope | null, porous: boolean); constructor(root: ScopeRoot, parent: Scope | null, porous: boolean);
root: ScopeRoot; root: ScopeRoot;
/** /**
* A map of every identifier declared by this scope, and all the * A map of every identifier declared by this scope, and all the
@ -1033,25 +1033,25 @@ declare module 'svelte/compiler' {
* which is usually an error. Block statements do not increase this value * which is usually an error. Block statements do not increase this value
*/ */
function_depth: number; function_depth: number;
declare(node: import('estree').Identifier, kind: Binding['kind'], declaration_kind: DeclarationKind, initial?: null | import('estree').Expression | import('estree').FunctionDeclaration | import('estree').ClassDeclaration | import('estree').ImportDeclaration | EachBlock): Binding; declare(node: import('estree').Identifier, kind: Binding['kind'], declaration_kind: DeclarationKind, initial?: null | import('estree').Expression | import('estree').FunctionDeclaration | import('estree').ClassDeclaration | import('estree').ImportDeclaration | EachBlock): Binding;
child(porous?: boolean): Scope; child(porous?: boolean): Scope;
generate(preferred_name: string): string; generate(preferred_name: string): string;
get(name: string): Binding | null; get(name: string): Binding | null;
get_bindings(node: import('estree').VariableDeclarator | LetDirective): Binding[]; get_bindings(node: import('estree').VariableDeclarator | LetDirective): Binding[];
owner(name: string): Scope | null; owner(name: string): Scope | null;
reference(node: import('estree').Identifier, path: SvelteNode[]): void; reference(node: import('estree').Identifier, path: SvelteNode[]): void;
#private; #private;
} }
class ScopeRoot { class ScopeRoot {
conflicts: Set<string>; conflicts: Set<string>;
unique(preferred_name: string): import("estree").Identifier; unique(preferred_name: string): import("estree").Identifier;
} }
interface BaseNode { interface BaseNode {
@ -2464,11 +2464,11 @@ declare function $derived<T>(expression: T): T;
declare namespace $derived { declare namespace $derived {
/** /**
* Sometimes you need to create complex derivations which don't fit inside a short expression. * Sometimes you need to create complex derivations which don't fit inside a short expression.
* In this case, you can resort to `$derived.fn` which accepts a function as its argument and returns its value. * In this case, you can resort to `$derived.call` which accepts a function as its argument and returns its value.
* *
* Example: * Example:
* ```ts * ```ts
* $derived.fn(() => { * $derived.call(() => {
* let tmp = count; * let tmp = count;
* if (count > 10) { * if (count > 10) {
* tmp += 100; * tmp += 100;
@ -2603,4 +2603,4 @@ declare function $inspect<T extends any[]>(
...values: T ...values: T
): { with: (fn: (type: 'init' | 'update', ...values: T) => void) => void }; ): { with: (fn: (type: 'init' | 'update', ...values: T) => void) => void };
//# sourceMappingURL=index.d.ts.map //# sourceMappingURL=index.d.ts.map

@ -208,8 +208,8 @@
{ label: '$state', type: 'keyword', boost: 10 }, { label: '$state', type: 'keyword', boost: 10 },
{ label: '$props', type: 'keyword', boost: 9 }, { label: '$props', type: 'keyword', boost: 9 },
{ label: '$derived', type: 'keyword', boost: 8 }, { label: '$derived', type: 'keyword', boost: 8 },
snip('$derived.fn(() => {\n\t${}\n});', { snip('$derived.call(() => {\n\t${}\n});', {
label: '$derived.fn', label: '$derived.call',
type: 'keyword', type: 'keyword',
boost: 7 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. ...`double` will be calculated first despite the source order. In runes mode, `triple` cannot reference `double` before it has been declared.
### `$derived.fn` ### `$derived.call`
Sometimes you need to create complex derivations which don't fit inside a short expression. In this case, you can resort to `$derived.fn` which accepts a function as its argument and returns its value. Sometimes you need to create complex derivations which don't fit inside a short expression. In this case, you can resort to `$derived.call` which accepts a function as its argument and returns its value.
```svelte ```svelte
<script> <script>
let count = $state(0); let count = $state(0);
let complex = $derived.fn(() => { let complex = $derived.call(() => {
let tmp = count; let tmp = count;
if (count > 10) { if (count > 10) {
tmp += 100; tmp += 100;

Loading…
Cancel
Save