Skip to content

Commit 6d3b223

Browse files
committed
wip
1 parent 7bad0c7 commit 6d3b223

File tree

7 files changed

+21
-39
lines changed

7 files changed

+21
-39
lines changed

packages/svelte/src/ambient.d.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ declare namespace $derived {
196196
*/
197197
export function by<T>(fn: () => T): T;
198198

199+
export function async<T>(expression: T, options?: { defer?: boolean }): T;
200+
199201
// prevent intellisense from being unhelpful
200202
/** @deprecated */
201203
export const apply: never;
@@ -218,12 +220,6 @@ declare namespace $derived {
218220
export const toString: never;
219221
}
220222

221-
declare function $async<T>(expression: T): T;
222-
223-
declare namespace $async {
224-
export function defer<T>(expression: T): T;
225-
}
226-
227223
/**
228224
* Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. `$state` or `$derived` values.
229225
* The timing of the execution is after the DOM has been updated.

packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,16 @@ export function CallExpression(node, context) {
9595

9696
break;
9797

98-
case '$async':
99-
case '$async.defer': {
98+
case '$derived.async': {
10099
if (
101100
parent.type !== 'VariableDeclarator' ||
102101
get_parent(context.path, -3).type === 'ConstTag'
103102
) {
104103
e.state_invalid_placement(node, rune);
105104
}
106105

107-
if (node.arguments.length !== 1) {
108-
e.rune_invalid_arguments_length(node, rune, 'exactly one argument');
106+
if (node.arguments.length !== 1 && node.arguments.length !== 2) {
107+
e.rune_invalid_arguments_length(node, rune, 'one or two arguments');
109108
}
110109

111110
break;
@@ -221,7 +220,7 @@ export function CallExpression(node, context) {
221220
function_depth: context.state.function_depth + 1,
222221
expression
223222
});
224-
} else if (rune === '$inspect' || rune === '$async' || rune === '$async.defer') {
223+
} else if (rune === '$inspect' || rune === '$derived.async') {
225224
context.next({ ...context.state, function_depth: context.state.function_depth + 1 });
226225
} else {
227226
context.next();

packages/svelte/src/compiler/phases/2-analyze/visitors/VariableDeclarator.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ export function VariableDeclarator(node, context) {
2929
rune === '$state.raw' ||
3030
rune === '$derived' ||
3131
rune === '$derived.by' ||
32-
rune === '$async' ||
33-
rune === '$async.defer' ||
32+
rune === '$derived.async' ||
3433
rune === '$props'
3534
) {
3635
for (const path of paths) {
@@ -41,10 +40,7 @@ export function VariableDeclarator(node, context) {
4140
? 'state'
4241
: rune === '$state.raw'
4342
? 'raw_state'
44-
: rune === '$derived' ||
45-
rune === '$derived.by' ||
46-
rune === '$async' ||
47-
rune === '$async.defer'
43+
: rune === '$derived' || rune === '$derived.by' || rune === '$derived.async'
4844
? 'derived'
4945
: path.is_rest
5046
? 'rest_prop'

packages/svelte/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -157,22 +157,15 @@ export function VariableDeclaration(node, context) {
157157
continue;
158158
}
159159

160-
if (rune === '$async' || rune === '$async.defer') {
160+
if (rune === '$derived.async') {
161161
if (declarator.id.type === 'Identifier') {
162+
const options =
163+
args.length > 1 ? /** @type {Expression} */ (context.visit(args[1])) : undefined;
162164
declarations.push(
163165
b.declarator(
164166
declarator.id,
165167
b.call(
166-
b.await(
167-
b.call(
168-
'$.save',
169-
b.call(
170-
'$.async_derived',
171-
b.thunk(value, true),
172-
rune === '$async.defer' && b.literal(true)
173-
)
174-
)
175-
)
168+
b.await(b.call('$.save', b.call('$.async_derived', b.thunk(value, true), options)))
176169
)
177170
)
178171
);

packages/svelte/src/internal/client/reactivity/deriveds.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ export function derived(fn) {
7777
/**
7878
* @template V
7979
* @param {() => Promise<V>} fn
80-
* @param {boolean} [deferred]
80+
* @param {{ defer?: boolean }} [options]
8181
* @returns {Promise<Source<V>>}
8282
*/
8383
/*#__NO_SIDE_EFFECTS__*/
84-
export function async_derived(fn, deferred = false) {
84+
export function async_derived(fn, options = {}) {
8585
let parent = /** @type {Effect | null} */ (active_effect);
8686

8787
if (parent === null) {
@@ -90,6 +90,7 @@ export function async_derived(fn, deferred = false) {
9090

9191
var promise = /** @type {Promise<V>} */ (/** @type {unknown} */ (undefined));
9292
var value = source(/** @type {V} */ (undefined));
93+
var deferred = options.defer === true;
9394

9495
block(async () => {
9596
var current = (promise = fn());

packages/svelte/src/utils.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,16 +436,15 @@ const RUNES = /** @type {const} */ ([
436436
'$bindable',
437437
'$derived',
438438
'$derived.by',
439+
'$derived.async',
439440
'$effect',
440441
'$effect.pre',
441442
'$effect.tracking',
442443
'$effect.root',
443444
'$inspect',
444445
'$inspect().with',
445446
'$inspect.trace',
446-
'$host',
447-
'$async',
448-
'$async.defer'
447+
'$host'
449448
]);
450449

451450
/**

packages/svelte/types/index.d.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,8 @@ declare module 'svelte' {
512512
* ```
513513
* */
514514
export function untrack<T>(fn: () => T): T;
515+
516+
export function isDeferred(fn: () => any): boolean;
515517
type Getters<T> = {
516518
[K in keyof T]: () => T[K];
517519
};
@@ -2862,6 +2864,8 @@ declare namespace $derived {
28622864
*/
28632865
export function by<T>(fn: () => T): T;
28642866

2867+
export function async<T>(expression: T, options?: { defer?: boolean }): T;
2868+
28652869
// prevent intellisense from being unhelpful
28662870
/** @deprecated */
28672871
export const apply: never;
@@ -2884,12 +2888,6 @@ declare namespace $derived {
28842888
export const toString: never;
28852889
}
28862890

2887-
declare function $async<T>(expression: T): T;
2888-
2889-
declare namespace $async {
2890-
export function defer<T>(expression: T): T;
2891-
}
2892-
28932891
/**
28942892
* Runs code when a component is mounted to the DOM, and then whenever its dependencies change, i.e. `$state` or `$derived` values.
28952893
* The timing of the execution is after the DOM has been updated.

0 commit comments

Comments
 (0)