Skip to content

Commit 74ceb6d

Browse files
committed
add test + some docs
1 parent f8eee24 commit 74ceb6d

File tree

8 files changed

+109
-25
lines changed

8 files changed

+109
-25
lines changed

packages/svelte/src/ambient.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,21 @@ declare function $inspect<T extends any[]>(
372372
): { with: (fn: (type: 'init' | 'update', ...values: T) => void) => void };
373373

374374
declare namespace $inspect {
375+
/**
376+
* Traces the reactive graph of the tracking reactive context. Must be placed within a block statement.
377+
* Example:
378+
*
379+
* ```svelte
380+
* <script>
381+
* let count = $state(0);
382+
*
383+
* $effect(() => {
384+
* $inspect.trace('my effect');
385+
*
386+
* count;
387+
* });
388+
* </script>
389+
*/
375390
export function trace(name: string): void;
376391
}
377392

packages/svelte/src/compiler/errors.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -470,30 +470,30 @@ export function store_invalid_subscription_module(node) {
470470
}
471471

472472
/**
473-
* `$track` requires a string argument for the trace name
473+
* `$track` must only be used once within the same block statement
474474
* @param {null | number | NodeLike} node
475475
* @returns {never}
476476
*/
477-
export function trace_rune_invalid_argument(node) {
478-
e(node, "trace_rune_invalid_argument", "`$track` requires a string argument for the trace name");
477+
export function trace_rune_duplicate(node) {
478+
e(node, "trace_rune_duplicate", "`$track` must only be used once within the same block statement");
479479
}
480480

481481
/**
482-
* `$track` must be placed directly inside a block statement
482+
* `$track` requires a string argument for the trace name
483483
* @param {null | number | NodeLike} node
484484
* @returns {never}
485485
*/
486-
export function trace_rune_invalid_location(node) {
487-
e(node, "trace_rune_invalid_location", "`$track` must be placed directly inside a block statement");
486+
export function trace_rune_invalid_argument(node) {
487+
e(node, "trace_rune_invalid_argument", "`$track` requires a string argument for the trace name");
488488
}
489489

490490
/**
491-
* `$track` must only be used once within the same block statement
491+
* `$track` must be placed directly inside a block statement
492492
* @param {null | number | NodeLike} node
493493
* @returns {never}
494494
*/
495-
export function trace_rune_duplicate(node) {
496-
e(node, "trace_rune_duplicate", "`$track` must only be used once within the same block statement");
495+
export function trace_rune_invalid_location(node) {
496+
e(node, "trace_rune_invalid_location", "`$track` must be placed directly inside a block statement");
497497
}
498498

499499
/**
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
compileOptions: {
5+
dev: true
6+
},
7+
8+
async test({ assert, target, logs }) {
9+
assert.deepEqual(logs, []);
10+
11+
const [b1, b2] = target.querySelectorAll('button');
12+
b1.click();
13+
b2.click();
14+
await Promise.resolve();
15+
16+
assert.ok(logs[0].stack.startsWith('Error:') && logs[0].stack.includes('HTMLButtonElement.'));
17+
assert.deepEqual(logs[1], 1);
18+
}
19+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script>
2+
let x = $state(0);
3+
let y = $state(0);
4+
5+
$inspect(x).with((type, x) => {
6+
if (type === 'update') console.log(new Error(), x);
7+
});
8+
</script>
9+
10+
<button on:click={() => x++}>{x}</button>
11+
<button on:click={() => y++}>{y}</button>
Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,41 @@
1+
import { flushSync } from 'svelte';
12
import { test } from '../../test';
23

4+
/**
5+
* @param {any[]} logs
6+
*/
7+
function normalise_trace_logs(logs) {
8+
let normalised = [];
9+
for (let i = 0; i < logs.length; i++) {
10+
const log = logs[i];
11+
12+
if (typeof log === 'string' && log.includes('%c')) {
13+
const split = log.split('%c');
14+
normalised.push((split[0].length !== 0 ? split[0] : split[1]).trim());
15+
i++;
16+
} else if (log instanceof Error) {
17+
continue;
18+
} else {
19+
normalised.push(log);
20+
}
21+
}
22+
return normalised;
23+
}
24+
325
export default test({
426
compileOptions: {
527
dev: true
628
},
729

8-
async test({ assert, target, logs }) {
9-
assert.deepEqual(logs, []);
30+
test({ assert, target, logs }) {
31+
assert.deepEqual(normalise_trace_logs(logs), ['effect', '$derived', 0, '$state', 0]);
32+
33+
logs.length = 0;
1034

11-
const [b1, b2] = target.querySelectorAll('button');
12-
b1.click();
13-
b2.click();
14-
await Promise.resolve();
35+
const button = target.querySelector('button');
36+
button?.click();
37+
flushSync();
1538

16-
assert.ok(logs[0].stack.startsWith('Error:') && logs[0].stack.includes('HTMLButtonElement.'));
17-
assert.deepEqual(logs[1], 1);
39+
assert.deepEqual(normalise_trace_logs(logs), ['effect', '$derived', 2, '$state', 1]);
1840
}
1941
});
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<script>
2-
let x = $state(0);
3-
let y = $state(0);
2+
let count = $state(0);
3+
let double = $derived(count * 2);
44
5-
$inspect(x).with((type, x) => {
6-
if (type === 'update') console.log(new Error(), x);
7-
});
5+
$effect(() => {
6+
$inspect.trace('effect');
7+
8+
double;
9+
})
810
</script>
911

10-
<button on:click={() => x++}>{x}</button>
11-
<button on:click={() => y++}>{y}</button>
12+
<button onclick={() => count++}>{double}</button>

packages/svelte/types/index.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2693,6 +2693,21 @@ declare function $inspect<T extends any[]>(
26932693
): { with: (fn: (type: 'init' | 'update', ...values: T) => void) => void };
26942694

26952695
declare namespace $inspect {
2696+
/**
2697+
* Traces the reactive graph of the tracking reactive context. Must be placed within a block statement.
2698+
* Example:
2699+
*
2700+
* ```svelte
2701+
* <script>
2702+
* let count = $state(0);
2703+
*
2704+
* $effect(() => {
2705+
* $inspect.trace('my effect');
2706+
*
2707+
* count;
2708+
* });
2709+
* </script>
2710+
*/
26962711
export function trace(name: string): void;
26972712
}
26982713

sites/svelte-5-preview/src/lib/autocomplete.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ const runes = [
119119
{ snippet: '$effect.root(() => {\n\t${}\n})' },
120120
{ snippet: '$state.snapshot(${})' },
121121
{ snippet: '$effect.tracking()' },
122-
{ snippet: '$inspect(${});', test: is_statement }
122+
{ snippet: '$inspect(${});', test: is_statement },
123+
{ snippet: '$inspect.trace(${})' }
123124
];
124125

125126
const options = runes.map(({ snippet, test }, i) => ({

0 commit comments

Comments
 (0)