mirror of https://github.com/sveltejs/svelte
fix: correctly highlight sources reassigned inside `trace` (#14811)
* fix: correctly highlight sources reassigned inside `trace` * chore: add missing effect logs * fix: prevent `null` access on `tracing_expressions` for nested tracing * chore: add test case for #14853 * fix: types for `$inpect.trace`pull/14889/head
parent
f3a7ded734
commit
a91308d9db
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: correctly highlight sources reassigned inside `trace`
|
@ -0,0 +1,56 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
/**
|
||||
* @param {any[]} logs
|
||||
*/
|
||||
function normalise_trace_logs(logs) {
|
||||
let normalised = [];
|
||||
for (let i = 0; i < logs.length; i++) {
|
||||
const log = logs[i];
|
||||
|
||||
if (typeof log === 'string' && log.includes('%c')) {
|
||||
const split = log.split('%c');
|
||||
normalised.push({
|
||||
log: (split[0].length !== 0 ? split[0] : split[1]).trim(),
|
||||
highlighted: logs[i + 1] === 'color: CornflowerBlue; font-weight: bold'
|
||||
});
|
||||
i++;
|
||||
} else if (log instanceof Error) {
|
||||
continue;
|
||||
} else {
|
||||
normalised.push({ log });
|
||||
}
|
||||
}
|
||||
return normalised;
|
||||
}
|
||||
|
||||
export default test({
|
||||
compileOptions: {
|
||||
dev: true
|
||||
},
|
||||
|
||||
test({ assert, target, logs }) {
|
||||
// initial log, everything is highlighted
|
||||
|
||||
assert.deepEqual(normalise_trace_logs(logs), [
|
||||
{ log: 'iife', highlighted: false },
|
||||
{ log: '$state', highlighted: true },
|
||||
{ log: 0 },
|
||||
{ log: 'effect', highlighted: false }
|
||||
]);
|
||||
|
||||
logs.length = 0;
|
||||
|
||||
const button = target.querySelector('button');
|
||||
button?.click();
|
||||
flushSync();
|
||||
|
||||
assert.deepEqual(normalise_trace_logs(logs), [
|
||||
{ log: 'iife', highlighted: false },
|
||||
{ log: '$state', highlighted: true },
|
||||
{ log: 1 },
|
||||
{ log: 'effect', highlighted: false }
|
||||
]);
|
||||
}
|
||||
});
|
@ -0,0 +1,13 @@
|
||||
<script>
|
||||
let count = $state(0);
|
||||
|
||||
$effect(() => {
|
||||
$inspect.trace('effect');
|
||||
(()=>{
|
||||
$inspect.trace("iife");
|
||||
count;
|
||||
})();
|
||||
});
|
||||
</script>
|
||||
|
||||
<button onclick={() => count++}>{count}</button>
|
@ -0,0 +1,8 @@
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
compileOptions: {
|
||||
dev: true
|
||||
},
|
||||
test() {}
|
||||
});
|
@ -0,0 +1,9 @@
|
||||
<script>
|
||||
let count = $state(null);
|
||||
$effect(() => {
|
||||
$inspect.trace();
|
||||
count;
|
||||
});
|
||||
</script>
|
||||
|
||||
<button onclick={()=>count++}>{count}</button>
|
@ -0,0 +1,72 @@
|
||||
import { flushSync } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
/**
|
||||
* @param {any[]} logs
|
||||
*/
|
||||
function normalise_trace_logs(logs) {
|
||||
let normalised = [];
|
||||
for (let i = 0; i < logs.length; i++) {
|
||||
const log = logs[i];
|
||||
|
||||
if (typeof log === 'string' && log.includes('%c')) {
|
||||
const split = log.split('%c');
|
||||
normalised.push({
|
||||
log: (split[0].length !== 0 ? split[0] : split[1]).trim(),
|
||||
highlighted: logs[i + 1] === 'color: CornflowerBlue; font-weight: bold'
|
||||
});
|
||||
i++;
|
||||
} else if (log instanceof Error) {
|
||||
continue;
|
||||
} else {
|
||||
normalised.push({ log });
|
||||
}
|
||||
}
|
||||
return normalised;
|
||||
}
|
||||
|
||||
export default test({
|
||||
compileOptions: {
|
||||
dev: true
|
||||
},
|
||||
|
||||
test({ assert, target, logs }) {
|
||||
// initial log, everything is highlighted
|
||||
|
||||
assert.deepEqual(normalise_trace_logs(logs), [
|
||||
{ log: 'effect', highlighted: false },
|
||||
{ log: '$state', highlighted: true },
|
||||
{ log: false }
|
||||
]);
|
||||
|
||||
logs.length = 0;
|
||||
|
||||
const button = target.querySelector('button');
|
||||
button?.click();
|
||||
flushSync();
|
||||
|
||||
const input = target.querySelector('input');
|
||||
input?.click();
|
||||
flushSync();
|
||||
|
||||
// checked changed, effect reassign state, values should be correct and be correctly highlighted
|
||||
|
||||
assert.deepEqual(normalise_trace_logs(logs), [
|
||||
{ log: 'effect', highlighted: false },
|
||||
{ log: '$state', highlighted: true },
|
||||
{ log: true },
|
||||
{ log: '$state', highlighted: true },
|
||||
{ log: 1 },
|
||||
{ log: 'effect', highlighted: false },
|
||||
{ log: '$state', highlighted: false },
|
||||
{ log: true },
|
||||
{ log: '$state', highlighted: true },
|
||||
{ log: 2 },
|
||||
{ log: 'effect', highlighted: false },
|
||||
{ log: '$state', highlighted: false },
|
||||
{ log: true },
|
||||
{ log: '$state', highlighted: true },
|
||||
{ log: 3 }
|
||||
]);
|
||||
}
|
||||
});
|
@ -0,0 +1,18 @@
|
||||
<script>
|
||||
let count = $state(0);
|
||||
let checked = $state(false);
|
||||
|
||||
$effect(() => {
|
||||
$inspect.trace("effect");
|
||||
if(checked && count > 0 && count < 3){
|
||||
let old = count;
|
||||
// this should not show up in the logs
|
||||
count = 1000;
|
||||
count = old + 1;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<input type="checkbox" bind:checked />
|
||||
<button onclick={()=>{
|
||||
count++;
|
||||
}}>{count}</button>
|
Loading…
Reference in new issue