refactor: use derived by instead of effect

This commit is contained in:
2026-10-09 21:23:41 +05:00
parent 6dcbb7c0f8
commit 9916955b96
2 changed files with 25 additions and 31 deletions
+4 -4
View File
@@ -52,11 +52,11 @@
## Med
### M1. Маски через `$effect` вместо `$derived.by`
### M1. Маски через `$effect` вместо `$derived.by` — СДЕЛАНО (2026-10)
`SchemaToolView.svelte:579-600`: `$effect` чисто вычисляет `maskResults` из
`steps`/`stepResults`/`source`/`maskOnKeys` и пишет в `$state`. `runMask`
синхронный и чистый — учебниковый случай `$derived.by`, эффект не нужен.
`SchemaToolView.svelte`: эффект вычисления `maskResults` заменён на
`$derived.by`; ручной сброс `maskResults = {}` в `init()` удалён — derived
пересчитывается сам по смене `steps`/`source`/`maskOnKeys`.
### M2. `init()` в эффекте не сбрасывает часть состояния
@@ -138,7 +138,27 @@
// Mask preview per step (keyed by step.key): the toggle lives on every
// step result tile, not just the final one.
const maskOnKeys = new SvelteSet<string>();
let maskResults = $state<Record<string, PixelImage | null>>({});
// Mask preview: recomputed on the main thread per toggled step from that
// step's input; a mask never enters the chain itself.
const maskResults = $derived.by(() => {
const next: Record<string, PixelImage | null> = {};
steps.forEach((step, i) => {
if (!maskOnKeys.has(step.key)) return;
const stepTool = getTool(step.id);
if (!stepTool?.runMask) return;
const input = i === 0 ? source : stepResults[i - 1];
if (!input) return;
try {
next[step.key] = stepTool.runMask({
params: step.params,
source: input,
});
} catch {
next[step.key] = null;
}
});
return next;
});
let dragFrom = $state<number | null>(null);
const lastTool = $derived(
@@ -255,7 +275,6 @@
verdictVars = undefined;
displayError = null;
maskOnKeys.clear();
maskResults = {};
}
function setStepValue(
@@ -582,31 +601,6 @@
return () => debouncedRun.cancel();
});
// Mask preview: recomputed on the main thread per toggled step from that
// step's input; a mask never enters the chain itself.
$effect(() => {
void steps;
void stepResults;
void source;
const next: Record<string, PixelImage | null> = {};
steps.forEach((step, i) => {
if (!maskOnKeys.has(step.key)) return;
const stepTool = getTool(step.id);
if (!stepTool?.runMask) return;
const input = i === 0 ? source : stepResults[i - 1];
if (!input) return;
try {
next[step.key] = stepTool.runMask({
params: step.params,
source: input,
});
} catch {
next[step.key] = null;
}
});
maskResults = next;
});
function toggleStepMask(key: string) {
if (maskOnKeys.has(key)) maskOnKeys.delete(key);
else maskOnKeys.add(key);