Skip to content

Commit

Permalink
correctly inspect derived values (#9731)
Browse files Browse the repository at this point in the history
Co-authored-by: Rich Harris <rich.harris@vercel.com>
  • Loading branch information
Rich-Harris and Rich-Harris authored Dec 1, 2023
1 parent 1108587 commit 765d01d
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/lemon-geese-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: improve `$inspect` type definition
5 changes: 5 additions & 0 deletions .changeset/two-dragons-yell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: correctly inspect derived values
45 changes: 43 additions & 2 deletions packages/svelte/src/internal/client/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,36 @@ function create_source_signal(flags, value) {
* @param {import('./types.js').SignalFlags} flags
* @param {V} value
* @param {import('./types.js').Block | null} block
* @returns {import('./types.js').ComputationSignal<V>}
* @returns {import('./types.js').ComputationSignal<V> | import('./types.js').ComputationSignal<V> & import('./types.js').SourceSignalDebug}
*/
function create_computation_signal(flags, value, block) {
if (DEV) {
return {
// block
b: block,
// consumers
c: null,
// destroy
d: null,
// equals
e: null,
// flags
f: flags,
// init
i: null,
// references
r: null,
// value
v: value,
// context: We can remove this if we get rid of beforeUpdate/afterUpdate
x: null,
// destroy
y: null,
// this is for DEV only
inspect: new Set()
};
}

return {
// block
b: block,
Expand Down Expand Up @@ -671,6 +698,12 @@ function update_derived(signal, force_schedule) {
if (!equals(value, signal.v)) {
signal.v = value;
mark_signal_consumers(signal, DIRTY, force_schedule);

// @ts-expect-error
if (DEV && signal.inspect && force_schedule) {
// @ts-expect-error
for (const fn of signal.inspect) fn();
}
}
}

Expand Down Expand Up @@ -836,7 +869,15 @@ export function get(signal) {
}

if ((flags & DERIVED) !== 0 && is_signal_dirty(signal)) {
update_derived(/** @type {import('./types.js').ComputationSignal<V>} **/ (signal), false);
if (DEV) {
// we want to avoid tracking indirect dependencies
const previous_inspect_fn = inspect_fn;
inspect_fn = null;
update_derived(/** @type {import('./types.js').ComputationSignal<V>} **/ (signal), false);
inspect_fn = previous_inspect_fn;
} else {
update_derived(/** @type {import('./types.js').ComputationSignal<V>} **/ (signal), false);
}
}
return signal.v;
}
Expand Down
17 changes: 14 additions & 3 deletions packages/svelte/src/main/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,23 @@ declare namespace $effect {
declare function $props<T>(): T;

/**
* Logs the arguments whenever they, or the properties they contain, change. Example:
* Inspects a value whenever it, or the properties it contains, change. Example:
*
* ```ts
* $inspect(someValue, someOtherValue)
* $inspect({ someValue, someOtherValue })
* ```
*
* If a second argument is provided, it will be called with the value and the event type
* (`'init'` or `'update'`), otherwise the value will be logged to the console.
*
* ```ts
* $inspect(x, console.trace);
* $inspect(y, (y) => { debugger; });
* ```
*
* https://svelte-5-preview.vercel.app/docs/runes#$inspect
*/
declare function $inspect(): void;
declare function $inspect<T>(
value: T,
callback?: (value: T, type: 'init' | 'update') => void
): void;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { test } from '../../test';

/**
* @type {any[]}
*/
let log;

export default test({
compileOptions: {
dev: true
},

get props() {
log = [];
return {
push: (/** @type {any} */ ...v) => log.push(...v)
};
},

async test({ assert, target }) {
const button = target.querySelector('button');

button?.click();
await Promise.resolve();

button?.click();
await Promise.resolve();

assert.deepEqual(log, ['X', 'init', 'XX', 'update', 'XXX', 'update']);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
/** @type {{ push: (v: any) => void }} */
let { push } = $props();
let x = $state('x');
let y = $derived(x.toUpperCase());
$inspect(y, push);
</script>

<button on:click={() => x += 'x'}>{x}</button>

1 comment on commit 765d01d

@vercel
Copy link

@vercel vercel bot commented on 765d01d Dec 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

svelte-5-preview – ./sites/svelte-5-preview

svelte-5-preview-svelte.vercel.app
svelte-octane.vercel.app
svelte-5-preview.vercel.app
svelte-5-preview-git-main-svelte.vercel.app

Please sign in to comment.