diff --git a/.changeset/pre.json b/.changeset/pre.json index 62faa4b5c..5ad02e875 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -144,6 +144,7 @@ "gestures-solid2-migration", "graphql-solid2-migration", "history-solid2-migration", + "history-undo-multi-source-fix", "i18n-missing-key-handler", "i18n-rich-text", "i18n-solid2-migration", diff --git a/packages/history/CHANGELOG.md b/packages/history/CHANGELOG.md index 3a691ad91..52b7d4122 100644 --- a/packages/history/CHANGELOG.md +++ b/packages/history/CHANGELOG.md @@ -1,5 +1,19 @@ # @solid-primitives/history +## 1.0.0-next.3 + +### Patch Changes + +- c061229: Fix two independent bugs in `createUndoHistory` that could each cause `undo`/`redo` to misfire — the second affects single-source usage too, not just multiple sources. + + **Microtask race on the internal "ignore" flag.** The previous implementation suppressed re-recording a history entry during `undo`/`redo` with a flag (`ignoreNext`) reset via a separately-scheduled microtask (`createMicrotask`). Since Solid 2.0 batches signal writes into their own microtask-scheduled flush, the flag's reset microtask could resolve _before_ the write's own flush — so the restore triggered by `undo`/`redo` got recorded as a brand-new history entry instead of being suppressed, corrupting `canRedo`/`canUndo` bookkeeping. This reproduces with a single source and no multi-source setup at all. The rewrite replaces the flag with `createOptimistic`, whose revert is coordinated by Solid's own flush (it runs after the same flush's pending recomputes, not via an independent competing microtask), which structurally removes this race. + + **Misaligned/spurious restores with multiple sources.** Separately, each history entry stored a compacted array of setters, dropping any paused source — so entries on either side of a pause/resume boundary could end up with different lengths, causing `undo`/`redo` to compare setters by the wrong array index and either restore the wrong source or spuriously re-fire one that hadn't actually changed. Entries now keep a fixed-length slot per source (`undefined` when paused), so index alignment is stable across every recorded entry. + + Also fixes the `limit` option: the default silently became unbounded and `limit: 0` no longer meant zero retention. Restored the documented default of `100` and made trimming unconditional so `limit: 0` correctly retains no undo history. + + Credit to @mesram, whose `createStore`/`createOptimistic`-based rewrite is the basis for this fix. + ## 1.0.0-next.2 ### Patch Changes diff --git a/packages/history/deno.jsonc b/packages/history/deno.jsonc index 2fd98545e..490091038 100644 --- a/packages/history/deno.jsonc +++ b/packages/history/deno.jsonc @@ -1,6 +1,6 @@ { "name": "@solid-primitives/history", - "version": "1.0.0-next.2", + "version": "1.0.0-next.3", "description": "Primitives for managing undo/redo history in Solid.", "license": "MIT", "exports": "./src/index.ts", diff --git a/packages/history/package.json b/packages/history/package.json index 06080a01d..c3ecb8bd0 100644 --- a/packages/history/package.json +++ b/packages/history/package.json @@ -1,6 +1,6 @@ { "name": "@solid-primitives/history", - "version": "1.0.0-next.2", + "version": "1.0.0-next.3", "description": "Primitives for managing undo/redo history.", "author": "Damian Tarnawski ", "contributors": [],