diff --git a/.changeset/gentle-mayflies-try.md b/.changeset/gentle-mayflies-try.md new file mode 100644 index 0000000000..7e39468ff6 --- /dev/null +++ b/.changeset/gentle-mayflies-try.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: `$derived.by` get current value as first argument diff --git a/packages/svelte/src/ambient.d.ts b/packages/svelte/src/ambient.d.ts index 6af8ca5156..a2d6aea0de 100644 --- a/packages/svelte/src/ambient.d.ts +++ b/packages/svelte/src/ambient.d.ts @@ -202,7 +202,7 @@ declare namespace $derived { * * https://svelte-5-preview.vercel.app/docs/runes#$derived-by */ - export function by(fn: () => T): T; + export function by(fn: (current: T | null) => T): T; // prevent intellisense from being unhelpful /** @deprecated */ diff --git a/packages/svelte/src/compiler/utils/builders.js b/packages/svelte/src/compiler/utils/builders.js index 060a8c2990..a43b3a48c7 100644 --- a/packages/svelte/src/compiler/utils/builders.js +++ b/packages/svelte/src/compiler/utils/builders.js @@ -419,16 +419,6 @@ export function template(elements, expressions) { * @returns {ESTree.Expression} */ export function thunk(expression, async = false) { - if ( - expression.type === 'CallExpression' && - expression.callee.type !== 'Super' && - expression.callee.type !== 'MemberExpression' && - expression.callee.type !== 'CallExpression' && - expression.arguments.length === 0 - ) { - return expression.callee; - } - const fn = arrow([], expression); if (async) fn.async = true; return fn; diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index e3af722ea5..bd28de3147 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -17,7 +17,7 @@ import { inspect_effects, set_inspect_effects } from './sources.js'; /** * @template V - * @param {() => V} fn + * @param {(current: V | null ) => V} fn * @returns {Derived} */ /*#__NO_SIDE_EFFECTS__*/ @@ -47,7 +47,7 @@ export function derived(fn) { /** * @template V - * @param {() => V} fn + * @param {(current: NoInfer | null) => V} fn * @returns {Derived} */ /*#__NO_SIDE_EFFECTS__*/ diff --git a/packages/svelte/src/internal/client/reactivity/types.d.ts b/packages/svelte/src/internal/client/reactivity/types.d.ts index ecc3029580..e6aace1ee4 100644 --- a/packages/svelte/src/internal/client/reactivity/types.d.ts +++ b/packages/svelte/src/internal/client/reactivity/types.d.ts @@ -25,7 +25,7 @@ export interface Reaction extends Signal { export interface Derived extends Value, Reaction { /** The derived function */ - fn: () => V; + fn: (current: V | null) => V; /** Reactions created inside this signal */ children: null | Reaction[]; } diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 5dd6a5f067..42d585e072 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -309,7 +309,11 @@ export function update_reaction(reaction) { derived_sources = null; try { - var result = /** @type {Function} */ (0, reaction.fn)(); + var args = []; + if (reaction.f & DERIVED) { + args.push(/**@type {Derived}*/ (reaction).v); + } + var result = /** @type {Function} */ (0, reaction.fn)(...args); var deps = reaction.deps; if (new_deps !== null) { @@ -783,7 +787,6 @@ export function get(signal) { update_derived(derived); } } - return signal.v; } diff --git a/packages/svelte/tests/signals/test.ts b/packages/svelte/tests/signals/test.ts index 9935291c0a..18b93f1e5c 100644 --- a/packages/svelte/tests/signals/test.ts +++ b/packages/svelte/tests/signals/test.ts @@ -471,7 +471,7 @@ describe('signals', () => { }); test('owned deriveds correctly cleanup when no longer connected to graph', () => { - let a: Derived; + let a: Derived; let s = state(0); const destroy = effect_root(() => { diff --git a/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js index a4bbea582b..6e7feef630 100644 --- a/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client/index.svelte.js @@ -6,6 +6,6 @@ export default function Svelte_element($$anchor, $$props) { var fragment = $.comment(); var node = $.first_child(fragment); - $.element(node, tag, false); + $.element(node, () => tag(), false); $.append($$anchor, fragment); } \ No newline at end of file