@vielzeug/ledger 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # @vielzeug/ledger
2
+
3
+ Async undo/redo command history with Ripple signals for reactive `canUndo`/`canRedo` state.
4
+
5
+ ## Features
6
+
7
+ - **Async commands** — `execute` and `rollback` can return `Promise<void>`; operations are serialised
8
+ - **Reactive state** — `canUndo`, `canRedo`, `historySize`, `isProcessing`, `historySnapshot` are Ripple `Computed` values
9
+ - **Batch** — group multiple commands into one undo step
10
+ - **Max history** — configurable cap; oldest entries evicted automatically
11
+ - **Disposable** — `dispose()` + `[Symbol.dispose]` for `using` declarations
12
+
13
+ ## Install
14
+
15
+ ```sh
16
+ pnpm add @vielzeug/ledger
17
+ ```
18
+
19
+ ## Quick start
20
+
21
+ ```typescript
22
+ import { compose, createLedger } from '@vielzeug/ledger';
23
+ import { effect } from '@vielzeug/ripple';
24
+
25
+ const ledger = createLedger({ maxHistory: 50 });
26
+
27
+ // Execute a command
28
+ await ledger.do({
29
+ execute: async () => { item.name = newName; },
30
+ rollback: async () => { item.name = oldName; },
31
+ label: 'Rename item',
32
+ });
33
+
34
+ // Undo / redo
35
+ await ledger.undo();
36
+ await ledger.redo();
37
+
38
+ // Batch — compose multiple commands into one undo step
39
+ await ledger.do(compose([cmd1, cmd2, cmd3], 'Multi-edit'));
40
+
41
+ // Bind to UI
42
+ effect(() => {
43
+ undoButton.disabled = !ledger.canUndo.value;
44
+ redoButton.disabled = !ledger.canRedo.value;
45
+ });
46
+
47
+ ledger.dispose(); // or: using ledger = createLedger()
48
+ ```
49
+
50
+ [Full docs →](https://vielzeug.dev/ledger/)
package/dist/_dev.cjs ADDED
@@ -0,0 +1,2 @@
1
+ var e=!globalThis.__LEDGER_PROD__;function t(t){e&&console.warn(`[@vielzeug/ledger] ${t}`)}exports.warn=t;
2
+ //# sourceMappingURL=_dev.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __LEDGER_PROD__?: boolean }).__LEDGER_PROD__;\n\n/** @internal @security Messages may include user data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/ledger] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":"AAAA,IAAM,EAAQ,CAAE,WAA6C,gBAG7D,SAAgB,EAAK,EAAmB,CAClC,GAAO,QAAQ,KAAK,sBAAsB,GAAK,CACrD"}
package/dist/_dev.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=_dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dev.d.ts","sourceRoot":"","sources":["../src/_dev.ts"],"names":[],"mappings":""}
package/dist/_dev.js ADDED
@@ -0,0 +1,9 @@
1
+ //#region src/_dev.ts
2
+ var e = !globalThis.__LEDGER_PROD__;
3
+ function t(t) {
4
+ e && console.warn(`[@vielzeug/ledger] ${t}`);
5
+ }
6
+ //#endregion
7
+ export { t as warn };
8
+
9
+ //# sourceMappingURL=_dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __LEDGER_PROD__?: boolean }).__LEDGER_PROD__;\n\n/** @internal @security Messages may include user data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/ledger] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":";AAAA,IAAM,IAAQ,CAAE,WAA6C;AAG7D,SAAgB,EAAK,GAAmB;CACtC,AAAI,KAAO,QAAQ,KAAK,sBAAsB,GAAK;AACrD"}
@@ -0,0 +1,2 @@
1
+ function e(e,t){return{execute:async t=>{let n=[];try{for(let r of e)await r.execute(t),n.push(r)}catch(e){for(let e of[...n].reverse())try{await e.rollback?.(t)}catch{}throw e}},label:t,rollback:e.some(e=>e.rollback!=null)?async t=>{let n,r=!1;for(let i of[...e].reverse())try{await i.rollback?.(t)}catch(e){r||=(n=e,!0)}if(r)throw n}:void 0}}exports.compose=e;
2
+ //# sourceMappingURL=compose.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.cjs","names":[],"sources":["../src/compose.ts"],"sourcesContent":["import type { Command } from './types';\n\n/**\n * Composes multiple commands into a single reversible command.\n *\n * `execute` runs all sub-commands in order. `rollback` runs them in reverse,\n * skipping any that have no rollback defined. The composed command counts as\n * one undo step.\n *\n * @example\n * await ledger.do(compose([\n * { execute: () => { node.x = newX; }, rollback: () => { node.x = oldX; } },\n * { execute: () => { node.y = newY; }, rollback: () => { node.y = oldY; } },\n * ], 'Move node'));\n */\nexport function compose<TData = unknown>(commands: Command<TData>[], label?: string): Command<TData> {\n const anyHasRollback = commands.some((c) => c.rollback != null);\n\n return {\n execute: async (signal) => {\n const done: Command<TData>[] = [];\n\n try {\n for (const c of commands) {\n await c.execute(signal);\n done.push(c);\n }\n } catch (err) {\n for (const c of [...done].reverse()) {\n try {\n await c.rollback?.(signal);\n } catch {\n // best-effort: suppress compensation errors\n }\n }\n\n throw err;\n }\n },\n label,\n rollback: anyHasRollback\n ? async (signal) => {\n let firstError: unknown;\n let hasError = false;\n\n for (const c of [...commands].reverse()) {\n try {\n await c.rollback?.(signal);\n } catch (err) {\n if (!hasError) {\n firstError = err;\n hasError = true;\n }\n }\n }\n\n if (hasError) throw firstError;\n }\n : undefined,\n };\n}\n"],"mappings":"AAeA,SAAgB,EAAyB,EAA4B,EAAgC,CAGnG,MAAO,CACL,QAAS,KAAO,IAAW,CACzB,IAAM,EAAyB,CAAC,EAEhC,GAAI,CACF,IAAK,IAAM,KAAK,EACd,MAAM,EAAE,QAAQ,CAAM,EACtB,EAAK,KAAK,CAAC,CAEf,OAAS,EAAK,CACZ,IAAK,IAAM,IAAK,CAAC,GAAG,CAAI,CAAC,CAAC,QAAQ,EAChC,GAAI,CACF,MAAM,EAAE,WAAW,CAAM,CAC3B,MAAQ,CAER,CAGF,MAAM,CACR,CACF,EACA,QACA,SAxBqB,EAAS,KAAM,GAAM,EAAE,UAAY,IAwB9C,EACN,KAAO,IAAW,CAChB,IAAI,EACA,EAAW,GAEf,IAAK,IAAM,IAAK,CAAC,GAAG,CAAQ,CAAC,CAAC,QAAQ,EACpC,GAAI,CACF,MAAM,EAAE,WAAW,CAAM,CAC3B,OAAS,EAAK,CACZ,AAEE,KADA,EAAa,EACF,GAEf,CAGF,GAAI,EAAU,MAAM,CACtB,EACA,IAAA,EACN,CACF"}
@@ -0,0 +1,16 @@
1
+ import type { Command } from './types';
2
+ /**
3
+ * Composes multiple commands into a single reversible command.
4
+ *
5
+ * `execute` runs all sub-commands in order. `rollback` runs them in reverse,
6
+ * skipping any that have no rollback defined. The composed command counts as
7
+ * one undo step.
8
+ *
9
+ * @example
10
+ * await ledger.do(compose([
11
+ * { execute: () => { node.x = newX; }, rollback: () => { node.x = oldX; } },
12
+ * { execute: () => { node.y = newY; }, rollback: () => { node.y = oldY; } },
13
+ * ], 'Move node'));
14
+ */
15
+ export declare function compose<TData = unknown>(commands: Command<TData>[], label?: string): Command<TData>;
16
+ //# sourceMappingURL=compose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CA6CnG"}
@@ -0,0 +1,30 @@
1
+ //#region src/compose.ts
2
+ function e(e, t) {
3
+ return {
4
+ execute: async (t) => {
5
+ let n = [];
6
+ try {
7
+ for (let r of e) await r.execute(t), n.push(r);
8
+ } catch (e) {
9
+ for (let e of [...n].reverse()) try {
10
+ await e.rollback?.(t);
11
+ } catch {}
12
+ throw e;
13
+ }
14
+ },
15
+ label: t,
16
+ rollback: e.some((e) => e.rollback != null) ? async (t) => {
17
+ let n, r = !1;
18
+ for (let i of [...e].reverse()) try {
19
+ await i.rollback?.(t);
20
+ } catch (e) {
21
+ r ||= (n = e, !0);
22
+ }
23
+ if (r) throw n;
24
+ } : void 0
25
+ };
26
+ }
27
+ //#endregion
28
+ export { e as compose };
29
+
30
+ //# sourceMappingURL=compose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.js","names":[],"sources":["../src/compose.ts"],"sourcesContent":["import type { Command } from './types';\n\n/**\n * Composes multiple commands into a single reversible command.\n *\n * `execute` runs all sub-commands in order. `rollback` runs them in reverse,\n * skipping any that have no rollback defined. The composed command counts as\n * one undo step.\n *\n * @example\n * await ledger.do(compose([\n * { execute: () => { node.x = newX; }, rollback: () => { node.x = oldX; } },\n * { execute: () => { node.y = newY; }, rollback: () => { node.y = oldY; } },\n * ], 'Move node'));\n */\nexport function compose<TData = unknown>(commands: Command<TData>[], label?: string): Command<TData> {\n const anyHasRollback = commands.some((c) => c.rollback != null);\n\n return {\n execute: async (signal) => {\n const done: Command<TData>[] = [];\n\n try {\n for (const c of commands) {\n await c.execute(signal);\n done.push(c);\n }\n } catch (err) {\n for (const c of [...done].reverse()) {\n try {\n await c.rollback?.(signal);\n } catch {\n // best-effort: suppress compensation errors\n }\n }\n\n throw err;\n }\n },\n label,\n rollback: anyHasRollback\n ? async (signal) => {\n let firstError: unknown;\n let hasError = false;\n\n for (const c of [...commands].reverse()) {\n try {\n await c.rollback?.(signal);\n } catch (err) {\n if (!hasError) {\n firstError = err;\n hasError = true;\n }\n }\n }\n\n if (hasError) throw firstError;\n }\n : undefined,\n };\n}\n"],"mappings":";AAeA,SAAgB,EAAyB,GAA4B,GAAgC;CAGnG,OAAO;EACL,SAAS,OAAO,MAAW;GACzB,IAAM,IAAyB,CAAC;GAEhC,IAAI;IACF,KAAK,IAAM,KAAK,GAEd,AADA,MAAM,EAAE,QAAQ,CAAM,GACtB,EAAK,KAAK,CAAC;GAEf,SAAS,GAAK;IACZ,KAAK,IAAM,KAAK,CAAC,GAAG,CAAI,CAAC,CAAC,QAAQ,GAChC,IAAI;KACF,MAAM,EAAE,WAAW,CAAM;IAC3B,QAAQ,CAER;IAGF,MAAM;GACR;EACF;EACA;EACA,UAxBqB,EAAS,MAAM,MAAM,EAAE,YAAY,IAwB9C,IACN,OAAO,MAAW;GAChB,IAAI,GACA,IAAW;GAEf,KAAK,IAAM,KAAK,CAAC,GAAG,CAAQ,CAAC,CAAC,QAAQ,GACpC,IAAI;IACF,MAAM,EAAE,WAAW,CAAM;GAC3B,SAAS,GAAK;IACZ,AAEE,OADA,IAAa,GACF;GAEf;GAGF,IAAI,GAAU,MAAM;EACtB,IACA,KAAA;CACN;AACF"}
@@ -0,0 +1,2 @@
1
+ var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class extends e{},n=class extends e{},r=class extends e{};exports.LedgerDisposedError=t,exports.LedgerError=e,exports.LedgerExecutionError=n,exports.LedgerRollbackError=r;
2
+ //# sourceMappingURL=errors.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all ledger errors. Use `instanceof LedgerError` to catch any ledger-originated error. */\nexport class LedgerError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is LedgerError {\n return err instanceof LedgerError;\n }\n}\n\n/** Thrown when a method is called on a disposed ledger instance. */\nexport class LedgerDisposedError extends LedgerError {}\n\n/** Thrown when a command's `execute()` function throws. The original error is available via `.cause`. */\nexport class LedgerExecutionError extends LedgerError {}\n\n/** Passed to `onRollbackError` when a command's `rollback()` function throws during an undo operation. The original error is available via `.cause`. */\nexport class LedgerRollbackError extends LedgerError {}\n"],"mappings":"AACA,IAAa,EAAb,MAAa,UAAoB,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,IAAI,OAAO,KACvB,OAAO,eAAe,KAAM,IAAI,OAAO,SAAS,CAClD,CAEA,OAAO,GAAG,EAAkC,CAC1C,OAAO,aAAe,CACxB,CACF,EAGa,EAAb,cAAyC,CAAY,CAAC,EAGzC,EAAb,cAA0C,CAAY,CAAC,EAG1C,EAAb,cAAyC,CAAY,CAAC"}
@@ -0,0 +1,15 @@
1
+ /** Base class for all ledger errors. Use `instanceof LedgerError` to catch any ledger-originated error. */
2
+ export declare class LedgerError extends Error {
3
+ constructor(message: string, opts?: ErrorOptions);
4
+ static is(err: unknown): err is LedgerError;
5
+ }
6
+ /** Thrown when a method is called on a disposed ledger instance. */
7
+ export declare class LedgerDisposedError extends LedgerError {
8
+ }
9
+ /** Thrown when a command's `execute()` function throws. The original error is available via `.cause`. */
10
+ export declare class LedgerExecutionError extends LedgerError {
11
+ }
12
+ /** Passed to `onRollbackError` when a command's `rollback()` function throws during an undo operation. The original error is available via `.cause`. */
13
+ export declare class LedgerRollbackError extends LedgerError {
14
+ }
15
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,2GAA2G;AAC3G,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;IAMhD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,WAAW;CAG5C;AAED,oEAAoE;AACpE,qBAAa,mBAAoB,SAAQ,WAAW;CAAG;AAEvD,yGAAyG;AACzG,qBAAa,oBAAqB,SAAQ,WAAW;CAAG;AAExD,wJAAwJ;AACxJ,qBAAa,mBAAoB,SAAQ,WAAW;CAAG"}
package/dist/errors.js ADDED
@@ -0,0 +1,13 @@
1
+ //#region src/errors.ts
2
+ var e = class e extends Error {
3
+ constructor(e, t) {
4
+ super(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);
5
+ }
6
+ static is(t) {
7
+ return t instanceof e;
8
+ }
9
+ }, t = class extends e {}, n = class extends e {}, r = class extends e {};
10
+ //#endregion
11
+ export { t as LedgerDisposedError, e as LedgerError, n as LedgerExecutionError, r as LedgerRollbackError };
12
+
13
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all ledger errors. Use `instanceof LedgerError` to catch any ledger-originated error. */\nexport class LedgerError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is LedgerError {\n return err instanceof LedgerError;\n }\n}\n\n/** Thrown when a method is called on a disposed ledger instance. */\nexport class LedgerDisposedError extends LedgerError {}\n\n/** Thrown when a command's `execute()` function throws. The original error is available via `.cause`. */\nexport class LedgerExecutionError extends LedgerError {}\n\n/** Passed to `onRollbackError` when a command's `rollback()` function throws during an undo operation. The original error is available via `.cause`. */\nexport class LedgerRollbackError extends LedgerError {}\n"],"mappings":";AACA,IAAa,IAAb,MAAa,UAAoB,MAAM;CACrC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,IAAI,OAAO,MACvB,OAAO,eAAe,MAAM,IAAI,OAAO,SAAS;CAClD;CAEA,OAAO,GAAG,GAAkC;EAC1C,OAAO,aAAe;CACxB;AACF,GAGa,IAAb,cAAyC,EAAY,CAAC,GAGzC,IAAb,cAA0C,EAAY,CAAC,GAG1C,IAAb,cAAyC,EAAY,CAAC"}
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./compose.cjs"),t=require("./errors.cjs"),n=require("./ledger.cjs");exports.LedgerDisposedError=t.LedgerDisposedError,exports.LedgerError=t.LedgerError,exports.LedgerExecutionError=t.LedgerExecutionError,exports.LedgerRollbackError=t.LedgerRollbackError,exports.compose=e.compose,exports.createLedger=n.createLedger;
@@ -0,0 +1,5 @@
1
+ export { compose } from './compose';
2
+ export { LedgerDisposedError, LedgerError, LedgerExecutionError, LedgerRollbackError } from './errors';
3
+ export { createLedger } from './ledger';
4
+ export type { Command, CommandMeta, Ledger, LedgerCallOptions, LedgerOptions } from './types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACvG,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import { compose as e } from "./compose.js";
2
+ import { LedgerDisposedError as t, LedgerError as n, LedgerExecutionError as r, LedgerRollbackError as i } from "./errors.js";
3
+ import { createLedger as a } from "./ledger.js";
4
+ export { t as LedgerDisposedError, n as LedgerError, r as LedgerExecutionError, i as LedgerRollbackError, e as compose, a as createLedger };
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e,t){return{execute:async t=>{let n=[];try{for(let r of e)await r.execute(t),n.push(r)}catch(e){for(let e of[...n].reverse())try{await e.rollback?.(t)}catch{}throw e}},label:t,rollback:e.some(e=>e.rollback!=null)?async t=>{let n,r=!1;for(let i of[...e].reverse())try{await i.rollback?.(t)}catch(e){r||=(n=e,!0)}if(r)throw n}:void 0}}var t=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},n=class extends t{},r=class extends t{},i=class extends t{},a=null,o=()=>a,s=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},c=class extends s{},l=class extends s{},u=0,d=()=>++u,f=()=>u,p={scheduling:{activeDirty:`a`,batchDepth:0,dirtyWithEffectSubsA:new Set,dirtyWithEffectSubsB:new Set,pendingSubscribers:new Set},scopeCleanups:null,tracking:null},m=null,h=()=>m===null?p:m.get(),g=()=>h().scheduling,_=()=>m!==null,v=()=>h().tracking,y=(e,t)=>{if(m!==null){let n=m.get();return m.run({...n,tracking:e},t)}let n=p;p={...p,tracking:e};try{return t()}finally{p=n}},b=()=>h().scopeCleanups,x=e=>{let t=v();t?.kind===`effect`?t.cleanups.push(e):b()?.push(e)},S=e=>{let t=v();if(t!==null){if(t.sourceObserver?.(e),t.kind===`computed`)t.depCollector.push({source:e,version:e.version});else if(t.kind===`effect`){let n=t.effect;e.addEffectSub(n),t.subscriptions.add(()=>e.removeEffectSub(n)),t.deps.set(e,e.version)}}},C=e=>e instanceof Error?e:Error(`Non-Error thrown: ${String(e)}`),w=e=>{let t=[];for(let n of e)try{n()}catch(e){t.push(C(e))}return t},T=(e,t)=>{let n=w(e);if(n.length===1)throw n[0];if(n.length>0)throw AggregateError(n,t)},E=!globalThis.__RIPPLE_PROD__;function D(e){E&&console.warn(`[@vielzeug/ripple] ${e}`)}var O=!1,k=0,A=[],j=e=>e.activeDirty===`a`?e.dirtyWithEffectSubsA:e.dirtyWithEffectSubsB,M=(e,t)=>{let n=++k;for(let n of t.effectSubs())e.pendingSubscribers.add(n);for(let e of t.computedSubs())A.push(e);try{for(;A.length>0;){let t=A.pop();if(t.lastPropEpoch_!==n&&(t.lastPropEpoch_=n,t.markDirty())){t.effectSubs().size>0&&j(e).add(t);for(let e of t.computedSubs())A.push(e)}}}finally{A.length=0}},N=e=>{for(;j(e).size>0;){let t=j(e);e.activeDirty=e.activeDirty===`a`?`b`:`a`,j(e).clear();for(let n of t)if(n.hasSubscribers()&&n.refreshIfDirty()){for(let t of n.effectSubs())e.pendingSubscribers.add(t);for(let t of n.computedSubs())t.markDirty()&&t.effectSubs().size>0&&j(e).add(t)}t.clear()}},P=e=>{let t=0;for(;e.pendingSubscribers.size>0||j(e).size>0;){if(++t>100)throw new l(`infinite flush loop (> 100 iterations)`);if(j(e).size>0&&N(e),e.pendingSubscribers.size===0)continue;let n=[...e.pendingSubscribers];e.pendingSubscribers.clear(),T(n,`subscriber errors`)}},F=globalThis.process?.versions!=null,I=e=>{if(!e.hasSubscribers())return;!O&&F&&!_()&&(O=!0,D(`Signal updated in a Node.js-like environment. The module-level flush queue is shared across concurrent requests — use per-request worker isolation or the @vielzeug/ripple/ssr sub-path for request-isolated scheduling.`));let t=g();M(t,e),t.batchDepth===0&&P(t)},L=class{fn_;disposed_=!1;constructor(e){this.fn_=e}get disposed(){return this.disposed_}dispose(){if(this.disposed_)return;this.disposed_=!0;let e=this.fn_;this.fn_=null,e()}[Symbol.dispose](){this.dispose()}},R=Symbol(`ripple.is-signal`),z=Symbol(`ripple.is-computed`),B=Symbol(`ripple.uninitialized`),V=new FinalizationRegistry(({key:e,map:t})=>{t.delete(e)}),H=class{version=0;name;[R]=!0;computedSubs_=new Map;effectSubs_=new Set;constructor(e){this.name=e}addComputedSub(e){let t=new WeakRef(e);this.computedSubs_.set(e,t),V.register(e,{key:e,map:this.computedSubs_},t)}removeComputedSub(e){let t=this.computedSubs_.get(e);t!==void 0&&(this.computedSubs_.delete(e),V.unregister(t))}addEffectSub(e){this.effectSubs_.add(e)}removeEffectSub(e){this.effectSubs_.delete(e)}clearSubscribers(){for(let e of this.computedSubs_.values())V.unregister(e);this.computedSubs_.clear(),this.effectSubs_.clear()}hasSubscribers(){if(this.effectSubs_.size>0)return!0;for(let e of this.computedSubs_.values())if(e.deref()!==void 0)return!0;return!1}*computedSubs(){for(let[e,t]of this.computedSubs_){let n=t.deref();n===void 0?(this.computedSubs_.delete(e),V.unregister(t)):yield n}}effectSubs(){return this.effectSubs_}},U=class extends H{[z]=!0;lastPropEpoch_=0},W=class extends U{value_;dirty_;computing_;disposed_;deps_;compute_;equals_;maxRevision_;constructor(e,t){let{equals:n,name:r}=t??{};super(r),this.value_=B,this.dirty_=!0,this.computing_=!1,this.disposed_=!1,this.deps_=[],this.maxRevision_=-1,this.compute_=e,this.equals_=n===void 0?Object.is:(e,t)=>n(e,t)}markDirty(){return this.disposed_||this.dirty_?!1:(this.dirty_=!0,!0)}refreshIfDirty(){if(!this.dirty_)return!1;if(f()<=this.maxRevision_)return this.dirty_=!1,!1;if(this.deps_.length>0){let e=!0;for(let t of this.deps_){let n=t.source;if(`refreshIfDirty`in n&&n.refreshIfDirty(),n.version!==t.version){e=!1;break}}if(e)return this.dirty_=!1,this.maxRevision_=f(),!1}return this.recompute()}runCompute(e){try{return y({computed:this,depCollector:e,kind:`computed`},this.compute_)}catch(e){throw C(e)}}recompute(){if(this.computing_)throw new c(`computed cycle detected${this.name?` "${this.name}"`:``}`);this.computing_=!0;try{let e=[];o()?.compute?.({name:this.name});let t=this.runCompute(e);return this.dirty_=!1,this.maxRevision_=f(),this.updateDeps(e),this.value_===B||!this.equals_(this.value_,t)?(this.value_=t,this.version++,!0):!1}finally{this.computing_=!1}}updateDeps(e){let t=this.deps_;if(t.length===e.length&&t.every((t,n)=>t.source===e[n].source)){for(let n=0;n<e.length;n++)t[n].version=e[n].version;return}let n=new Set(t.map(e=>e.source)),r=new Set(e.map(e=>e.source));for(let e of t)r.has(e.source)||e.source.removeComputedSub(this);for(let t of e)n.has(t.source)||t.source.addComputedSub(this);this.deps_=e}get value(){return this.disposed_?this.value_===B?void 0:this.value_:(this.refreshIfDirty(),S(this),this.value_)}peek(){return this.disposed_?this.value_===B?void 0:this.value_:(this.refreshIfDirty(),this.value_)}subscribe=e=>{if(this.disposed_){let e=new L(()=>{});return e.dispose(),e}return this.refreshIfDirty(),this.addEffectSub(e),new L(()=>{this.removeEffectSub(e)})};get disposed(){return this.disposed_}dispose(){if(!this.disposed_){this.disposed_=!0;for(let e of this.deps_)e.source.removeComputedSub(this);this.deps_=[],this.clearSubscribers(),o()?.dispose?.({kind:`computed`,name:this.name})}}[Symbol.dispose](){this.dispose()}},G=(e,t)=>{let n=new W(e,t);return x(()=>n.dispose()),n},K=class extends H{value_;equals_;disposed_;constructor(e,t,n){super(n),this.value_=e,this.equals_=t??Object.is,this.disposed_=!1}get value(){return this.disposed_||S(this),this.value_}set value(e){if(this.disposed_||this.equals_(this.value_,e))return;let t=this.value_;this.value_=e,this.version=d(),o()?.write?.({name:this.name,newValue:e,oldValue:t}),I(this)}peek(){return this.value_}subscribe=e=>{if(this.disposed_){let e=new L(()=>{});return e.dispose(),e}return this.addEffectSub(e),new L(()=>{this.removeEffectSub(e)})};get disposed(){return this.disposed_}dispose(){this.disposed_||(this.disposed_=!0,this.clearSubscribers(),o()?.dispose?.({kind:`signal`,name:this.name}))}[Symbol.dispose](){this.dispose()}},q=(e,t)=>new K(e,t?.equals,t?.name),J=!globalThis.__LEDGER_PROD__;function Y(e){J&&console.warn(`[@vielzeug/ledger] ${e}`)}function X(e){return e instanceof Error?e.message:String(e)}function Z(e){let{rollback:t}=e;return{execute:async t=>e.execute(t),meta:{data:e.data,label:e.label},rollback:t==null?void 0:async e=>t(e)}}function Q(e={}){let{maxHistory:t=100,onRollbackError:a}=e;t<1&&Y(`maxHistory must be >= 1; history tracking is disabled for this ledger.`);let o=q([],{name:`ledger:undoStack`}),s=q([],{name:`ledger:redoStack`}),c=q(0,{name:`ledger:pending`}),l=q(!1,{name:`ledger:processing`}),u=G(()=>o.value.length>0,{name:`ledger:canUndo`}),d=G(()=>s.value.length>0,{name:`ledger:canRedo`}),f=G(()=>o.value.length,{name:`ledger:historySize`}),p=G(()=>l.value,{name:`ledger:isProcessing`}),m=G(()=>c.value,{name:`ledger:pendingCount`}),h=G(()=>[...o.value].reverse().map(e=>e.meta),{name:`ledger:historySnapshot`}),g=[o,s,c,l,u,d,f,p,m,h],_=!1,v=Promise.resolve(),y=new AbortController;function b(e){return e?AbortSignal.any([e,y.signal]):y.signal}function x(e,t){if(_)return Promise.reject(new n(`Cannot call ${e}() on a disposed ledger.`));c.value++;let r=v.then(t).finally(()=>{_||c.value--});return v=r.catch(()=>{}),r}async function S(e){l.value=!0;try{await e()}finally{_||(l.value=!1)}}async function C(e,n){await S(async()=>{try{await e.execute(n)}catch(e){throw new r(X(e),{cause:e})}if(_)return;let i=[...o.value,e];i.length>t&&i.shift(),o.value=i,s.value=[]})}async function w(e){let t=o.value;if(t.length===0)return;let n=t[t.length-1];await S(async()=>{if(n.rollback)try{await n.rollback(e)}catch(e){Y(`rollback() threw for "${n.meta.label??`(unlabelled)`}". Stack position unchanged.`),a?.(new i(X(e),{cause:e}),n.meta);return}_||(o.value=t.slice(0,-1),s.value=[...s.value,n])})}async function T(e){let t=s.value;if(t.length===0)return;let n=t[t.length-1];await S(async()=>{try{await n.execute(e)}catch(e){throw new r(X(e),{cause:e})}_||(s.value=t.slice(0,-1),o.value=[...o.value,n])})}function E(){return x(`clear`,async()=>{_||(o.value=[],s.value=[])})}function D(){_=!0,y.abort(),o.value=[],s.value=[];for(let e of g)e.dispose()}return{canRedo:d,canUndo:u,clear:E,get disposalSignal(){return y.signal},dispose:D,get disposed(){return _},do(e,t){return x(`do`,()=>C(Z(e),b(t?.signal)))},historySize:f,historySnapshot:h,isProcessing:p,pendingCount:m,redo(e){return x(`redo`,()=>T(b(e?.signal)))},[Symbol.dispose](){D()},undo(e){return x(`undo`,()=>w(b(e?.signal)))}}}exports.LedgerDisposedError=n,exports.LedgerError=t,exports.LedgerExecutionError=r,exports.LedgerRollbackError=i,exports.compose=e,exports.createLedger=Q;
2
+ //# sourceMappingURL=ledger.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.cjs","names":["e","t","n","e","t","n","r","i","a","o","e","t","n","r","i","a","o","s","c","l","u","d","f","p","m","e","t","n","r","e","t","o","s","u","d","t","e","i","n","r","e","t","n","r","t","e","l","c","i","o","t","n","a","s","e","r","a","n","t","e","r","i"],"sources":["../src/compose.ts","../src/errors.ts","../../ripple/dist/devtools-hook.js","../../ripple/dist/errors.js","../../ripple/dist/tracking.js","../../ripple/dist/_error-utils.js","../../ripple/dist/_dev.js","../../ripple/dist/scheduling.js","../../ripple/dist/subscription.js","../../ripple/dist/symbols.js","../../ripple/dist/reactive-base.js","../../ripple/dist/computed.js","../../ripple/dist/signal.js","../src/_dev.ts","../src/ledger.ts"],"sourcesContent":["import type { Command } from './types';\n\n/**\n * Composes multiple commands into a single reversible command.\n *\n * `execute` runs all sub-commands in order. `rollback` runs them in reverse,\n * skipping any that have no rollback defined. The composed command counts as\n * one undo step.\n *\n * @example\n * await ledger.do(compose([\n * { execute: () => { node.x = newX; }, rollback: () => { node.x = oldX; } },\n * { execute: () => { node.y = newY; }, rollback: () => { node.y = oldY; } },\n * ], 'Move node'));\n */\nexport function compose<TData = unknown>(commands: Command<TData>[], label?: string): Command<TData> {\n const anyHasRollback = commands.some((c) => c.rollback != null);\n\n return {\n execute: async (signal) => {\n const done: Command<TData>[] = [];\n\n try {\n for (const c of commands) {\n await c.execute(signal);\n done.push(c);\n }\n } catch (err) {\n for (const c of [...done].reverse()) {\n try {\n await c.rollback?.(signal);\n } catch {\n // best-effort: suppress compensation errors\n }\n }\n\n throw err;\n }\n },\n label,\n rollback: anyHasRollback\n ? async (signal) => {\n let firstError: unknown;\n let hasError = false;\n\n for (const c of [...commands].reverse()) {\n try {\n await c.rollback?.(signal);\n } catch (err) {\n if (!hasError) {\n firstError = err;\n hasError = true;\n }\n }\n }\n\n if (hasError) throw firstError;\n }\n : undefined,\n };\n}\n","/** Base class for all ledger errors. Use `instanceof LedgerError` to catch any ledger-originated error. */\nexport class LedgerError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is LedgerError {\n return err instanceof LedgerError;\n }\n}\n\n/** Thrown when a method is called on a disposed ledger instance. */\nexport class LedgerDisposedError extends LedgerError {}\n\n/** Thrown when a command's `execute()` function throws. The original error is available via `.cause`. */\nexport class LedgerExecutionError extends LedgerError {}\n\n/** Passed to `onRollbackError` when a command's `rollback()` function throws during an undo operation. The original error is available via `.cause`. */\nexport class LedgerRollbackError extends LedgerError {}\n","//#region src/devtools-hook.ts\nvar e = null, t = () => e, n = (t) => {\n\te = t;\n};\n//#endregion\nexport { t as getDevToolsHook, n as setDevToolsHook };\n\n//# sourceMappingURL=devtools-hook.js.map","//#region src/errors.ts\nvar e = class e extends Error {\n\tconstructor(e, t) {\n\t\tsuper(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);\n\t}\n\tstatic is(t) {\n\t\treturn t instanceof e;\n\t}\n}, t = class extends e {}, n = class extends e {}, r = class extends e {}, i = class extends e {}, a = class extends e {}, o = class extends e {};\n//#endregion\nexport { t as RippleComputedCycleError, n as RippleDisposedScopeError, r as RippleEnvironmentError, e as RippleError, i as RippleInfiniteLoopError, a as RippleInvalidCleanupError, o as RippleInvalidStoreError };\n\n//# sourceMappingURL=errors.js.map","//#region src/tracking.ts\nvar e = 0, t = () => ++e, n = () => e, r = () => ({\n\tactiveDirty: \"a\",\n\tbatchDepth: 0,\n\tdirtyWithEffectSubsA: /* @__PURE__ */ new Set(),\n\tdirtyWithEffectSubsB: /* @__PURE__ */ new Set(),\n\tpendingSubscribers: /* @__PURE__ */ new Set()\n}), i = {\n\tscheduling: r(),\n\tscopeCleanups: null,\n\ttracking: null\n}, a = null, o = () => a === null ? i : a.get(), s = () => o().scheduling, c = () => a !== null, l = () => o().tracking, u = (e, t) => {\n\tif (a !== null) {\n\t\tlet n = a.get();\n\t\treturn a.run({\n\t\t\t...n,\n\t\t\ttracking: e\n\t\t}, t);\n\t}\n\tlet n = i;\n\ti = {\n\t\t...i,\n\t\ttracking: e\n\t};\n\ttry {\n\t\treturn t();\n\t} finally {\n\t\ti = n;\n\t}\n}, d = (e, t) => {\n\tif (a !== null) {\n\t\tlet n = a.get();\n\t\treturn a.run({\n\t\t\t...n,\n\t\t\tscopeCleanups: e\n\t\t}, t);\n\t}\n\tlet n = i;\n\ti = {\n\t\t...i,\n\t\tscopeCleanups: e\n\t};\n\ttry {\n\t\treturn t();\n\t} finally {\n\t\ti = n;\n\t}\n}, f = () => o().scopeCleanups, p = (e) => {\n\tlet t = l();\n\tt?.kind === \"effect\" ? t.cleanups.push(e) : f()?.push(e);\n}, m = (e) => {\n\tlet t = a;\n\treturn a = e, t;\n}, h = (e, t) => {\n\tlet n = l();\n\treturn n === null ? t() : u({\n\t\t...n,\n\t\tsourceObserver: e\n\t}, t);\n}, g = (e) => u(null, e), _ = (e) => {\n\tlet t = l();\n\tif (t !== null) {\n\t\tif (t.sourceObserver?.(e), t.kind === \"computed\") t.depCollector.push({\n\t\t\tsource: e,\n\t\t\tversion: e.version\n\t\t});\n\t\telse if (t.kind === \"effect\") {\n\t\t\tlet n = t.effect;\n\t\t\te.addEffectSub(n), t.subscriptions.add(() => e.removeEffectSub(n)), t.deps.set(e, e.version);\n\t\t}\n\t}\n};\n//#endregion\nexport { m as _installContextHook, p as autoRegisterDisposal, r as createSchedulingState, n as getRevision, s as getSchedulingState, f as getScopeCleanups, l as getTracking, c as hasContextHook, t as tickRevision, _ as trackSource, g as untrack, d as withScopeCleanups, h as withSourceObserver, u as withTracking };\n\n//# sourceMappingURL=tracking.js.map","//#region src/_error-utils.ts\nvar e = (e) => e instanceof Error ? e : /* @__PURE__ */ Error(`Non-Error thrown: ${String(e)}`), t = (t) => {\n\tlet n = [];\n\tfor (let r of t) try {\n\t\tr();\n\t} catch (t) {\n\t\tn.push(e(t));\n\t}\n\treturn n;\n}, n = (e, n) => {\n\tlet r = t(e);\n\tif (r.length === 1) throw r[0];\n\tif (r.length > 0) throw AggregateError(r, n);\n}, r = (t, n, r) => {\n\tthrow n.length === 0 ? t : AggregateError([e(t), ...n], r, { cause: e(t) });\n};\n//#endregion\nexport { t as collectErrors, e as ensureError, r as rethrowWith, n as runAll };\n\n//# sourceMappingURL=_error-utils.js.map","//#region src/_dev.ts\nvar e = !globalThis.__RIPPLE_PROD__;\nfunction t(t) {\n\te && console.warn(`[@vielzeug/ripple] ${t}`);\n}\n//#endregion\nexport { t as warn };\n\n//# sourceMappingURL=_dev.js.map","import { runAll as e } from \"./_error-utils.js\";\nimport { RippleInfiniteLoopError as t } from \"./errors.js\";\nimport { warn as n } from \"./_dev.js\";\nimport { getSchedulingState as r, hasContextHook as i } from \"./tracking.js\";\nvar a = !1, o = 0, s = [], c = (e) => e.activeDirty === \"a\" ? e.dirtyWithEffectSubsA : e.dirtyWithEffectSubsB, l = (e, t) => {\n\tlet n = ++o;\n\tfor (let n of t.effectSubs()) e.pendingSubscribers.add(n);\n\tfor (let e of t.computedSubs()) s.push(e);\n\ttry {\n\t\tfor (; s.length > 0;) {\n\t\t\tlet t = s.pop();\n\t\t\tif (t.lastPropEpoch_ !== n && (t.lastPropEpoch_ = n, t.markDirty())) {\n\t\t\t\tt.effectSubs().size > 0 && c(e).add(t);\n\t\t\t\tfor (let e of t.computedSubs()) s.push(e);\n\t\t\t}\n\t\t}\n\t} finally {\n\t\ts.length = 0;\n\t}\n}, u = (e) => {\n\tfor (; c(e).size > 0;) {\n\t\tlet t = c(e);\n\t\te.activeDirty = e.activeDirty === \"a\" ? \"b\" : \"a\", c(e).clear();\n\t\tfor (let n of t) if (n.hasSubscribers() && n.refreshIfDirty()) {\n\t\t\tfor (let t of n.effectSubs()) e.pendingSubscribers.add(t);\n\t\t\tfor (let t of n.computedSubs()) t.markDirty() && t.effectSubs().size > 0 && c(e).add(t);\n\t\t}\n\t\tt.clear();\n\t}\n}, d = (n) => {\n\tlet r = 0;\n\tfor (; n.pendingSubscribers.size > 0 || c(n).size > 0;) {\n\t\tif (++r > 100) throw new t(\"infinite flush loop (> 100 iterations)\");\n\t\tif (c(n).size > 0 && u(n), n.pendingSubscribers.size === 0) continue;\n\t\tlet i = [...n.pendingSubscribers];\n\t\tn.pendingSubscribers.clear(), e(i, \"subscriber errors\");\n\t}\n}, f = globalThis.process?.versions != null, p = (e) => {\n\tif (!e.hasSubscribers()) return;\n\t!a && f && !i() && (a = !0, n(\"Signal updated in a Node.js-like environment. The module-level flush queue is shared across concurrent requests — use per-request worker isolation or the @vielzeug/ripple/ssr sub-path for request-isolated scheduling.\"));\n\tlet t = r();\n\tl(t, e), t.batchDepth === 0 && d(t);\n}, m = (e) => {\n\tlet t = r();\n\tt.batchDepth++;\n\tlet n;\n\ttry {\n\t\tn = e();\n\t} catch (e) {\n\t\tthrow t.batchDepth--, t.batchDepth === 0 && (t.pendingSubscribers.clear(), t.dirtyWithEffectSubsA.clear(), t.dirtyWithEffectSubsB.clear()), e;\n\t}\n\treturn t.batchDepth--, t.batchDepth === 0 && d(t), n;\n};\n//#endregion\nexport { m as batch, p as notifyNodeChange };\n\n//# sourceMappingURL=scheduling.js.map","//#region src/subscription.ts\nvar e = class {\n\tfn_;\n\tdisposed_ = !1;\n\tconstructor(e) {\n\t\tthis.fn_ = e;\n\t}\n\tget disposed() {\n\t\treturn this.disposed_;\n\t}\n\tdispose() {\n\t\tif (this.disposed_) return;\n\t\tthis.disposed_ = !0;\n\t\tlet e = this.fn_;\n\t\tthis.fn_ = null, e();\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n}, t = class {\n\tawaitDone_;\n\tgetCurrentRun_;\n\tsyncStop_;\n\tasyncDisposePromise_ = null;\n\tconstructor(e, t, n) {\n\t\tthis.awaitDone_ = t, this.getCurrentRun_ = n, this.syncStop_ = e;\n\t}\n\tget disposed() {\n\t\treturn this.syncStop_.disposed;\n\t}\n\tdispose() {\n\t\tthis.syncStop_.dispose();\n\t}\n\trun() {\n\t\treturn this.getCurrentRun_() ?? Promise.resolve();\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n\t[Symbol.asyncDispose]() {\n\t\treturn this.asyncDisposePromise_ === null ? (this.dispose(), this.asyncDisposePromise_ = this.awaitDone_(), this.asyncDisposePromise_) : this.asyncDisposePromise_;\n\t}\n};\n//#endregion\nexport { t as AsyncSubscriptionImpl, e as SubscriptionImpl };\n\n//# sourceMappingURL=subscription.js.map","//#region src/symbols.ts\nvar e = Symbol(\"ripple.is-signal\"), t = Symbol(\"ripple.is-computed\"), n = Symbol(\"ripple.is-store\"), r = Symbol(\"ripple.uninitialized\");\n//#endregion\nexport { t as IS_COMPUTED, e as IS_SIGNAL, n as IS_STORE, r as UNINITIALIZED };\n\n//# sourceMappingURL=symbols.js.map","import { IS_COMPUTED as e, IS_SIGNAL as t } from \"./symbols.js\";\n//#region src/reactive-base.ts\nvar n = new FinalizationRegistry(({ key: e, map: t }) => {\n\tt.delete(e);\n}), r = class {\n\tversion = 0;\n\tname;\n\t[t] = !0;\n\tcomputedSubs_ = /* @__PURE__ */ new Map();\n\teffectSubs_ = /* @__PURE__ */ new Set();\n\tconstructor(e) {\n\t\tthis.name = e;\n\t}\n\taddComputedSub(e) {\n\t\tlet t = new WeakRef(e);\n\t\tthis.computedSubs_.set(e, t), n.register(e, {\n\t\t\tkey: e,\n\t\t\tmap: this.computedSubs_\n\t\t}, t);\n\t}\n\tremoveComputedSub(e) {\n\t\tlet t = this.computedSubs_.get(e);\n\t\tt !== void 0 && (this.computedSubs_.delete(e), n.unregister(t));\n\t}\n\taddEffectSub(e) {\n\t\tthis.effectSubs_.add(e);\n\t}\n\tremoveEffectSub(e) {\n\t\tthis.effectSubs_.delete(e);\n\t}\n\tclearSubscribers() {\n\t\tfor (let e of this.computedSubs_.values()) n.unregister(e);\n\t\tthis.computedSubs_.clear(), this.effectSubs_.clear();\n\t}\n\thasSubscribers() {\n\t\tif (this.effectSubs_.size > 0) return !0;\n\t\tfor (let e of this.computedSubs_.values()) if (e.deref() !== void 0) return !0;\n\t\treturn !1;\n\t}\n\t*computedSubs() {\n\t\tfor (let [e, t] of this.computedSubs_) {\n\t\t\tlet r = t.deref();\n\t\t\tr === void 0 ? (this.computedSubs_.delete(e), n.unregister(t)) : yield r;\n\t\t}\n\t}\n\teffectSubs() {\n\t\treturn this.effectSubs_;\n\t}\n}, i = class extends r {\n\t[e] = !0;\n\tlastPropEpoch_ = 0;\n};\n//#endregion\nexport { i as ComputedBase, r as ReactiveBase };\n\n//# sourceMappingURL=reactive-base.js.map","import { getDevToolsHook as e } from \"./devtools-hook.js\";\nimport { ensureError as t } from \"./_error-utils.js\";\nimport { RippleComputedCycleError as n } from \"./errors.js\";\nimport { autoRegisterDisposal as r, getRevision as i, trackSource as a, withTracking as o } from \"./tracking.js\";\nimport { SubscriptionImpl as s } from \"./subscription.js\";\nimport { UNINITIALIZED as c } from \"./symbols.js\";\nimport { ComputedBase as l } from \"./reactive-base.js\";\n//#region src/computed.ts\nvar u = class extends l {\n\tvalue_;\n\tdirty_;\n\tcomputing_;\n\tdisposed_;\n\tdeps_;\n\tcompute_;\n\tequals_;\n\tmaxRevision_;\n\tconstructor(e, t) {\n\t\tlet { equals: n, name: r } = t ?? {};\n\t\tsuper(r), this.value_ = c, this.dirty_ = !0, this.computing_ = !1, this.disposed_ = !1, this.deps_ = [], this.maxRevision_ = -1, this.compute_ = e, this.equals_ = n === void 0 ? Object.is : (e, t) => n(e, t);\n\t}\n\tmarkDirty() {\n\t\treturn this.disposed_ || this.dirty_ ? !1 : (this.dirty_ = !0, !0);\n\t}\n\trefreshIfDirty() {\n\t\tif (!this.dirty_) return !1;\n\t\tif (i() <= this.maxRevision_) return this.dirty_ = !1, !1;\n\t\tif (this.deps_.length > 0) {\n\t\t\tlet e = !0;\n\t\t\tfor (let t of this.deps_) {\n\t\t\t\tlet n = t.source;\n\t\t\t\tif (\"refreshIfDirty\" in n && n.refreshIfDirty(), n.version !== t.version) {\n\t\t\t\t\te = !1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (e) return this.dirty_ = !1, this.maxRevision_ = i(), !1;\n\t\t}\n\t\treturn this.recompute();\n\t}\n\trunCompute(e) {\n\t\ttry {\n\t\t\treturn o({\n\t\t\t\tcomputed: this,\n\t\t\t\tdepCollector: e,\n\t\t\t\tkind: \"computed\"\n\t\t\t}, this.compute_);\n\t\t} catch (e) {\n\t\t\tthrow t(e);\n\t\t}\n\t}\n\trecompute() {\n\t\tif (this.computing_) throw new n(`computed cycle detected${this.name ? ` \"${this.name}\"` : \"\"}`);\n\t\tthis.computing_ = !0;\n\t\ttry {\n\t\t\tlet t = [];\n\t\t\te()?.compute?.({ name: this.name });\n\t\t\tlet n = this.runCompute(t);\n\t\t\treturn this.dirty_ = !1, this.maxRevision_ = i(), this.updateDeps(t), this.value_ === c || !this.equals_(this.value_, n) ? (this.value_ = n, this.version++, !0) : !1;\n\t\t} finally {\n\t\t\tthis.computing_ = !1;\n\t\t}\n\t}\n\tupdateDeps(e) {\n\t\tlet t = this.deps_;\n\t\tif (t.length === e.length && t.every((t, n) => t.source === e[n].source)) {\n\t\t\tfor (let n = 0; n < e.length; n++) t[n].version = e[n].version;\n\t\t\treturn;\n\t\t}\n\t\tlet n = new Set(t.map((e) => e.source)), r = new Set(e.map((e) => e.source));\n\t\tfor (let e of t) r.has(e.source) || e.source.removeComputedSub(this);\n\t\tfor (let t of e) n.has(t.source) || t.source.addComputedSub(this);\n\t\tthis.deps_ = e;\n\t}\n\tget value() {\n\t\treturn this.disposed_ ? this.value_ === c ? void 0 : this.value_ : (this.refreshIfDirty(), a(this), this.value_);\n\t}\n\tpeek() {\n\t\treturn this.disposed_ ? this.value_ === c ? void 0 : this.value_ : (this.refreshIfDirty(), this.value_);\n\t}\n\tsubscribe = (e) => {\n\t\tif (this.disposed_) {\n\t\t\tlet e = new s(() => {});\n\t\t\treturn e.dispose(), e;\n\t\t}\n\t\treturn this.refreshIfDirty(), this.addEffectSub(e), new s(() => {\n\t\t\tthis.removeEffectSub(e);\n\t\t});\n\t};\n\tget disposed() {\n\t\treturn this.disposed_;\n\t}\n\tdispose() {\n\t\tif (!this.disposed_) {\n\t\t\tthis.disposed_ = !0;\n\t\t\tfor (let e of this.deps_) e.source.removeComputedSub(this);\n\t\t\tthis.deps_ = [], this.clearSubscribers(), e()?.dispose?.({\n\t\t\t\tkind: \"computed\",\n\t\t\t\tname: this.name\n\t\t\t});\n\t\t}\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n}, d = (e, t) => {\n\tlet n = new u(e, t);\n\treturn r(() => n.dispose()), n;\n};\n//#endregion\nexport { u as ComputedImpl, d as computed };\n\n//# sourceMappingURL=computed.js.map","import { getDevToolsHook as e } from \"./devtools-hook.js\";\nimport { tickRevision as t, trackSource as n } from \"./tracking.js\";\nimport { notifyNodeChange as r } from \"./scheduling.js\";\nimport { SubscriptionImpl as i } from \"./subscription.js\";\nimport { ReactiveBase as a } from \"./reactive-base.js\";\n//#region src/signal.ts\nvar o = class extends a {\n\tvalue_;\n\tequals_;\n\tdisposed_;\n\tconstructor(e, t, n) {\n\t\tsuper(n), this.value_ = e, this.equals_ = t ?? Object.is, this.disposed_ = !1;\n\t}\n\tget value() {\n\t\treturn this.disposed_ || n(this), this.value_;\n\t}\n\tset value(n) {\n\t\tif (this.disposed_ || this.equals_(this.value_, n)) return;\n\t\tlet i = this.value_;\n\t\tthis.value_ = n, this.version = t(), e()?.write?.({\n\t\t\tname: this.name,\n\t\t\tnewValue: n,\n\t\t\toldValue: i\n\t\t}), r(this);\n\t}\n\tpeek() {\n\t\treturn this.value_;\n\t}\n\tsubscribe = (e) => {\n\t\tif (this.disposed_) {\n\t\t\tlet e = new i(() => {});\n\t\t\treturn e.dispose(), e;\n\t\t}\n\t\treturn this.addEffectSub(e), new i(() => {\n\t\t\tthis.removeEffectSub(e);\n\t\t});\n\t};\n\tget disposed() {\n\t\treturn this.disposed_;\n\t}\n\tdispose() {\n\t\tthis.disposed_ || (this.disposed_ = !0, this.clearSubscribers(), e()?.dispose?.({\n\t\t\tkind: \"signal\",\n\t\t\tname: this.name\n\t\t}));\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n}, s = (e, t) => new o(e, t?.equals, t?.name);\n//#endregion\nexport { o as SignalImpl, s as signal };\n\n//# sourceMappingURL=signal.js.map","const isDev = !(globalThis as { __LEDGER_PROD__?: boolean }).__LEDGER_PROD__;\n\n/** @internal @security Messages may include user data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/ledger] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n","import { computed, signal } from '@vielzeug/ripple';\n\nimport type { Command, CommandMeta, Ledger, LedgerCallOptions, LedgerOptions } from './types';\n\nimport { warn } from './_dev';\nimport { LedgerDisposedError, LedgerExecutionError, LedgerRollbackError } from './errors';\n\nfunction toMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\ntype StackEntry<TData = unknown> = {\n execute: (signal?: AbortSignal) => Promise<void>;\n meta: CommandMeta<TData>;\n rollback?: (signal?: AbortSignal) => Promise<void>;\n};\n\nfunction entryFromCommand<TData>(command: Command<TData>): StackEntry<TData> {\n const { rollback } = command;\n\n return {\n execute: async (signal) => command.execute(signal),\n meta: { data: command.data, label: command.label },\n rollback: rollback != null ? async (signal) => rollback(signal) : undefined,\n };\n}\n\n/**\n * Creates an async undo/redo command history.\n *\n * Each command is `{ execute, rollback? }`. `rollback` is optional — commands\n * without one are still tracked in history but undo skips the reversal step.\n * Operations are serialised — concurrent calls queue behind each other.\n * All state signals are Ripple `Computed` values for zero-glue UI binding.\n *\n * `execute`/`rollback` receive an `AbortSignal` — merged from the ledger's own\n * `disposalSignal` and any `signal` passed to `do()`/`undo()`/`redo()` — so long-running\n * commands can observe cancellation or disposal.\n *\n * @example\n * const ledger = createLedger({ maxHistory: 50 });\n * await ledger.do({ execute: () => { item.name = next; }, rollback: () => { item.name = prev; } });\n * await ledger.undo();\n * await ledger.redo();\n * using ledger = createLedger();\n */\nexport function createLedger<TData = unknown>(options: LedgerOptions<TData> = {}): Ledger<TData> {\n const { maxHistory = 100, onRollbackError } = options;\n\n if (maxHistory < 1) warn('maxHistory must be >= 1; history tracking is disabled for this ledger.');\n\n const undoStack = signal<StackEntry<TData>[]>([], { name: 'ledger:undoStack' });\n const redoStack = signal<StackEntry<TData>[]>([], { name: 'ledger:redoStack' });\n const pending = signal(0, { name: 'ledger:pending' });\n const processing = signal(false, { name: 'ledger:processing' });\n\n const canUndo = computed(() => undoStack.value.length > 0, { name: 'ledger:canUndo' });\n const canRedo = computed(() => redoStack.value.length > 0, { name: 'ledger:canRedo' });\n const historySize = computed(() => undoStack.value.length, { name: 'ledger:historySize' });\n const isProcessing = computed(() => processing.value, { name: 'ledger:isProcessing' });\n const pendingCount = computed(() => pending.value, { name: 'ledger:pendingCount' });\n const historySnapshot = computed(\n (): readonly CommandMeta<TData>[] => [...undoStack.value].reverse().map((e) => e.meta),\n { name: 'ledger:historySnapshot' },\n );\n\n const disposables = [\n undoStack,\n redoStack,\n pending,\n processing,\n canUndo,\n canRedo,\n historySize,\n isProcessing,\n pendingCount,\n historySnapshot,\n ];\n\n let isDisposed = false;\n let queue = Promise.resolve();\n\n const ac = new AbortController();\n\n function operationSignal(external?: AbortSignal): AbortSignal {\n return external ? AbortSignal.any([external, ac.signal]) : ac.signal;\n }\n\n function enqueue(method: string, task: () => Promise<void>): Promise<void> {\n if (isDisposed) return Promise.reject(new LedgerDisposedError(`Cannot call ${method}() on a disposed ledger.`));\n\n pending.value++;\n\n const current = queue.then(task).finally(() => {\n if (!isDisposed) pending.value--;\n });\n\n queue = current.catch(() => {});\n\n return current;\n }\n\n async function withProcessing(fn: () => Promise<void>): Promise<void> {\n processing.value = true;\n\n try {\n await fn();\n } finally {\n if (!isDisposed) processing.value = false;\n }\n }\n\n async function runDo(entry: StackEntry<TData>, signal: AbortSignal): Promise<void> {\n await withProcessing(async () => {\n try {\n await entry.execute(signal);\n } catch (err) {\n throw new LedgerExecutionError(toMessage(err), { cause: err });\n }\n\n if (isDisposed) return;\n\n const next = [...undoStack.value, entry];\n\n if (next.length > maxHistory) next.shift();\n\n undoStack.value = next;\n redoStack.value = [];\n });\n }\n\n async function runUndo(signal: AbortSignal): Promise<void> {\n const stack = undoStack.value;\n\n if (stack.length === 0) return;\n\n const entry = stack[stack.length - 1];\n\n await withProcessing(async () => {\n if (entry.rollback) {\n try {\n await entry.rollback(signal);\n } catch (err) {\n warn(`rollback() threw for \"${entry.meta.label ?? '(unlabelled)'}\". Stack position unchanged.`);\n onRollbackError?.(new LedgerRollbackError(toMessage(err), { cause: err }), entry.meta);\n\n return;\n }\n }\n\n if (isDisposed) return;\n\n undoStack.value = stack.slice(0, -1);\n redoStack.value = [...redoStack.value, entry];\n });\n }\n\n async function runRedo(signal: AbortSignal): Promise<void> {\n const stack = redoStack.value;\n\n if (stack.length === 0) return;\n\n const entry = stack[stack.length - 1];\n\n await withProcessing(async () => {\n try {\n await entry.execute(signal);\n } catch (err) {\n throw new LedgerExecutionError(toMessage(err), { cause: err });\n }\n\n if (isDisposed) return;\n\n redoStack.value = stack.slice(0, -1);\n undoStack.value = [...undoStack.value, entry];\n });\n }\n\n function clear(): Promise<void> {\n return enqueue('clear', async () => {\n if (isDisposed) return;\n\n undoStack.value = [];\n redoStack.value = [];\n });\n }\n\n function dispose(): void {\n isDisposed = true;\n ac.abort();\n\n undoStack.value = [];\n redoStack.value = [];\n\n for (const d of disposables) d.dispose();\n }\n\n return {\n canRedo,\n canUndo,\n\n clear,\n\n get disposalSignal(): AbortSignal {\n return ac.signal;\n },\n dispose,\n get disposed(): boolean {\n return isDisposed;\n },\n\n do(command: Command<TData>, callOptions?: LedgerCallOptions): Promise<void> {\n return enqueue('do', () => runDo(entryFromCommand<TData>(command), operationSignal(callOptions?.signal)));\n },\n\n historySize,\n historySnapshot,\n isProcessing,\n pendingCount,\n\n redo(callOptions?: LedgerCallOptions): Promise<void> {\n return enqueue('redo', () => runRedo(operationSignal(callOptions?.signal)));\n },\n\n [Symbol.dispose](): void {\n dispose();\n },\n\n undo(callOptions?: LedgerCallOptions): Promise<void> {\n return enqueue('undo', () => runUndo(operationSignal(callOptions?.signal)));\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { Ledger, LedgerOptions } from './types';
2
+ /**
3
+ * Creates an async undo/redo command history.
4
+ *
5
+ * Each command is `{ execute, rollback? }`. `rollback` is optional — commands
6
+ * without one are still tracked in history but undo skips the reversal step.
7
+ * Operations are serialised — concurrent calls queue behind each other.
8
+ * All state signals are Ripple `Computed` values for zero-glue UI binding.
9
+ *
10
+ * `execute`/`rollback` receive an `AbortSignal` — merged from the ledger's own
11
+ * `disposalSignal` and any `signal` passed to `do()`/`undo()`/`redo()` — so long-running
12
+ * commands can observe cancellation or disposal.
13
+ *
14
+ * @example
15
+ * const ledger = createLedger({ maxHistory: 50 });
16
+ * await ledger.do({ execute: () => { item.name = next; }, rollback: () => { item.name = prev; } });
17
+ * await ledger.undo();
18
+ * await ledger.redo();
19
+ * using ledger = createLedger();
20
+ */
21
+ export declare function createLedger<TData = unknown>(options?: LedgerOptions<TData>): Ledger<TData>;
22
+ //# sourceMappingURL=ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAwB,MAAM,EAAqB,aAAa,EAAE,MAAM,SAAS,CAAC;AAyB9F;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,KAAK,GAAG,OAAO,EAAE,OAAO,GAAE,aAAa,CAAC,KAAK,CAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CA0L/F"}
@@ -0,0 +1,2 @@
1
+ var Ledger=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e,t){return{execute:async t=>{let n=[];try{for(let r of e)await r.execute(t),n.push(r)}catch(e){for(let e of[...n].reverse())try{await e.rollback?.(t)}catch{}throw e}},label:t,rollback:e.some(e=>e.rollback!=null)?async t=>{let n,r=!1;for(let i of[...e].reverse())try{await i.rollback?.(t)}catch(e){r||=(n=e,!0)}if(r)throw n}:void 0}}var n=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},r=class extends n{},i=class extends n{},a=class extends n{},o=null,s=()=>o,c=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},l=class extends c{},u=class extends c{},d=0,f=()=>++d,p=()=>d,m={scheduling:{activeDirty:`a`,batchDepth:0,dirtyWithEffectSubsA:new Set,dirtyWithEffectSubsB:new Set,pendingSubscribers:new Set},scopeCleanups:null,tracking:null},h=null,g=()=>h===null?m:h.get(),_=()=>g().scheduling,v=()=>h!==null,y=()=>g().tracking,b=(e,t)=>{if(h!==null){let n=h.get();return h.run({...n,tracking:e},t)}let n=m;m={...m,tracking:e};try{return t()}finally{m=n}},x=()=>g().scopeCleanups,S=e=>{let t=y();t?.kind===`effect`?t.cleanups.push(e):x()?.push(e)},C=e=>{let t=y();if(t!==null){if(t.sourceObserver?.(e),t.kind===`computed`)t.depCollector.push({source:e,version:e.version});else if(t.kind===`effect`){let n=t.effect;e.addEffectSub(n),t.subscriptions.add(()=>e.removeEffectSub(n)),t.deps.set(e,e.version)}}},w=e=>e instanceof Error?e:Error(`Non-Error thrown: ${String(e)}`),T=e=>{let t=[];for(let n of e)try{n()}catch(e){t.push(w(e))}return t},E=(e,t)=>{let n=T(e);if(n.length===1)throw n[0];if(n.length>0)throw AggregateError(n,t)},D=!globalThis.__RIPPLE_PROD__;function O(e){D&&console.warn(`[@vielzeug/ripple] ${e}`)}var k=!1,A=0,j=[],M=e=>e.activeDirty===`a`?e.dirtyWithEffectSubsA:e.dirtyWithEffectSubsB,N=(e,t)=>{let n=++A;for(let n of t.effectSubs())e.pendingSubscribers.add(n);for(let e of t.computedSubs())j.push(e);try{for(;j.length>0;){let t=j.pop();if(t.lastPropEpoch_!==n&&(t.lastPropEpoch_=n,t.markDirty())){t.effectSubs().size>0&&M(e).add(t);for(let e of t.computedSubs())j.push(e)}}}finally{j.length=0}},P=e=>{for(;M(e).size>0;){let t=M(e);e.activeDirty=e.activeDirty===`a`?`b`:`a`,M(e).clear();for(let n of t)if(n.hasSubscribers()&&n.refreshIfDirty()){for(let t of n.effectSubs())e.pendingSubscribers.add(t);for(let t of n.computedSubs())t.markDirty()&&t.effectSubs().size>0&&M(e).add(t)}t.clear()}},F=e=>{let t=0;for(;e.pendingSubscribers.size>0||M(e).size>0;){if(++t>100)throw new u(`infinite flush loop (> 100 iterations)`);if(M(e).size>0&&P(e),e.pendingSubscribers.size===0)continue;let n=[...e.pendingSubscribers];e.pendingSubscribers.clear(),E(n,`subscriber errors`)}},I=globalThis.process?.versions!=null,L=e=>{if(!e.hasSubscribers())return;!k&&I&&!v()&&(k=!0,O(`Signal updated in a Node.js-like environment. The module-level flush queue is shared across concurrent requests — use per-request worker isolation or the @vielzeug/ripple/ssr sub-path for request-isolated scheduling.`));let t=_();N(t,e),t.batchDepth===0&&F(t)},R=class{fn_;disposed_=!1;constructor(e){this.fn_=e}get disposed(){return this.disposed_}dispose(){if(this.disposed_)return;this.disposed_=!0;let e=this.fn_;this.fn_=null,e()}[Symbol.dispose](){this.dispose()}},z=Symbol(`ripple.is-signal`),B=Symbol(`ripple.is-computed`),V=Symbol(`ripple.uninitialized`),H=new FinalizationRegistry(({key:e,map:t})=>{t.delete(e)}),U=class{version=0;name;[z]=!0;computedSubs_=new Map;effectSubs_=new Set;constructor(e){this.name=e}addComputedSub(e){let t=new WeakRef(e);this.computedSubs_.set(e,t),H.register(e,{key:e,map:this.computedSubs_},t)}removeComputedSub(e){let t=this.computedSubs_.get(e);t!==void 0&&(this.computedSubs_.delete(e),H.unregister(t))}addEffectSub(e){this.effectSubs_.add(e)}removeEffectSub(e){this.effectSubs_.delete(e)}clearSubscribers(){for(let e of this.computedSubs_.values())H.unregister(e);this.computedSubs_.clear(),this.effectSubs_.clear()}hasSubscribers(){if(this.effectSubs_.size>0)return!0;for(let e of this.computedSubs_.values())if(e.deref()!==void 0)return!0;return!1}*computedSubs(){for(let[e,t]of this.computedSubs_){let n=t.deref();n===void 0?(this.computedSubs_.delete(e),H.unregister(t)):yield n}}effectSubs(){return this.effectSubs_}},W=class extends U{[B]=!0;lastPropEpoch_=0},G=class extends W{value_;dirty_;computing_;disposed_;deps_;compute_;equals_;maxRevision_;constructor(e,t){let{equals:n,name:r}=t??{};super(r),this.value_=V,this.dirty_=!0,this.computing_=!1,this.disposed_=!1,this.deps_=[],this.maxRevision_=-1,this.compute_=e,this.equals_=n===void 0?Object.is:(e,t)=>n(e,t)}markDirty(){return this.disposed_||this.dirty_?!1:(this.dirty_=!0,!0)}refreshIfDirty(){if(!this.dirty_)return!1;if(p()<=this.maxRevision_)return this.dirty_=!1,!1;if(this.deps_.length>0){let e=!0;for(let t of this.deps_){let n=t.source;if(`refreshIfDirty`in n&&n.refreshIfDirty(),n.version!==t.version){e=!1;break}}if(e)return this.dirty_=!1,this.maxRevision_=p(),!1}return this.recompute()}runCompute(e){try{return b({computed:this,depCollector:e,kind:`computed`},this.compute_)}catch(e){throw w(e)}}recompute(){if(this.computing_)throw new l(`computed cycle detected${this.name?` "${this.name}"`:``}`);this.computing_=!0;try{let e=[];s()?.compute?.({name:this.name});let t=this.runCompute(e);return this.dirty_=!1,this.maxRevision_=p(),this.updateDeps(e),this.value_===V||!this.equals_(this.value_,t)?(this.value_=t,this.version++,!0):!1}finally{this.computing_=!1}}updateDeps(e){let t=this.deps_;if(t.length===e.length&&t.every((t,n)=>t.source===e[n].source)){for(let n=0;n<e.length;n++)t[n].version=e[n].version;return}let n=new Set(t.map(e=>e.source)),r=new Set(e.map(e=>e.source));for(let e of t)r.has(e.source)||e.source.removeComputedSub(this);for(let t of e)n.has(t.source)||t.source.addComputedSub(this);this.deps_=e}get value(){return this.disposed_?this.value_===V?void 0:this.value_:(this.refreshIfDirty(),C(this),this.value_)}peek(){return this.disposed_?this.value_===V?void 0:this.value_:(this.refreshIfDirty(),this.value_)}subscribe=e=>{if(this.disposed_){let e=new R(()=>{});return e.dispose(),e}return this.refreshIfDirty(),this.addEffectSub(e),new R(()=>{this.removeEffectSub(e)})};get disposed(){return this.disposed_}dispose(){if(!this.disposed_){this.disposed_=!0;for(let e of this.deps_)e.source.removeComputedSub(this);this.deps_=[],this.clearSubscribers(),s()?.dispose?.({kind:`computed`,name:this.name})}}[Symbol.dispose](){this.dispose()}},K=(e,t)=>{let n=new G(e,t);return S(()=>n.dispose()),n},q=class extends U{value_;equals_;disposed_;constructor(e,t,n){super(n),this.value_=e,this.equals_=t??Object.is,this.disposed_=!1}get value(){return this.disposed_||C(this),this.value_}set value(e){if(this.disposed_||this.equals_(this.value_,e))return;let t=this.value_;this.value_=e,this.version=f(),s()?.write?.({name:this.name,newValue:e,oldValue:t}),L(this)}peek(){return this.value_}subscribe=e=>{if(this.disposed_){let e=new R(()=>{});return e.dispose(),e}return this.addEffectSub(e),new R(()=>{this.removeEffectSub(e)})};get disposed(){return this.disposed_}dispose(){this.disposed_||(this.disposed_=!0,this.clearSubscribers(),s()?.dispose?.({kind:`signal`,name:this.name}))}[Symbol.dispose](){this.dispose()}},J=(e,t)=>new q(e,t?.equals,t?.name),Y=!globalThis.__LEDGER_PROD__;function X(e){Y&&console.warn(`[@vielzeug/ledger] ${e}`)}function Z(e){return e instanceof Error?e.message:String(e)}function Q(e){let{rollback:t}=e;return{execute:async t=>e.execute(t),meta:{data:e.data,label:e.label},rollback:t==null?void 0:async e=>t(e)}}function $(e={}){let{maxHistory:t=100,onRollbackError:n}=e;t<1&&X(`maxHistory must be >= 1; history tracking is disabled for this ledger.`);let o=J([],{name:`ledger:undoStack`}),s=J([],{name:`ledger:redoStack`}),c=J(0,{name:`ledger:pending`}),l=J(!1,{name:`ledger:processing`}),u=K(()=>o.value.length>0,{name:`ledger:canUndo`}),d=K(()=>s.value.length>0,{name:`ledger:canRedo`}),f=K(()=>o.value.length,{name:`ledger:historySize`}),p=K(()=>l.value,{name:`ledger:isProcessing`}),m=K(()=>c.value,{name:`ledger:pendingCount`}),h=K(()=>[...o.value].reverse().map(e=>e.meta),{name:`ledger:historySnapshot`}),g=[o,s,c,l,u,d,f,p,m,h],_=!1,v=Promise.resolve(),y=new AbortController;function b(e){return e?AbortSignal.any([e,y.signal]):y.signal}function x(e,t){if(_)return Promise.reject(new r(`Cannot call ${e}() on a disposed ledger.`));c.value++;let n=v.then(t).finally(()=>{_||c.value--});return v=n.catch(()=>{}),n}async function S(e){l.value=!0;try{await e()}finally{_||(l.value=!1)}}async function C(e,n){await S(async()=>{try{await e.execute(n)}catch(e){throw new i(Z(e),{cause:e})}if(_)return;let r=[...o.value,e];r.length>t&&r.shift(),o.value=r,s.value=[]})}async function w(e){let t=o.value;if(t.length===0)return;let r=t[t.length-1];await S(async()=>{if(r.rollback)try{await r.rollback(e)}catch(e){X(`rollback() threw for "${r.meta.label??`(unlabelled)`}". Stack position unchanged.`),n?.(new a(Z(e),{cause:e}),r.meta);return}_||(o.value=t.slice(0,-1),s.value=[...s.value,r])})}async function T(e){let t=s.value;if(t.length===0)return;let n=t[t.length-1];await S(async()=>{try{await n.execute(e)}catch(e){throw new i(Z(e),{cause:e})}_||(s.value=t.slice(0,-1),o.value=[...o.value,n])})}function E(){return x(`clear`,async()=>{_||(o.value=[],s.value=[])})}function D(){_=!0,y.abort(),o.value=[],s.value=[];for(let e of g)e.dispose()}return{canRedo:d,canUndo:u,clear:E,get disposalSignal(){return y.signal},dispose:D,get disposed(){return _},do(e,t){return x(`do`,()=>C(Q(e),b(t?.signal)))},historySize:f,historySnapshot:h,isProcessing:p,pendingCount:m,redo(e){return x(`redo`,()=>T(b(e?.signal)))},[Symbol.dispose](){D()},undo(e){return x(`undo`,()=>w(b(e?.signal)))}}}return e.LedgerDisposedError=r,e.LedgerError=n,e.LedgerExecutionError=i,e.LedgerRollbackError=a,e.compose=t,e.createLedger=$,e})({});
2
+ //# sourceMappingURL=ledger.iife.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.iife.js","names":["e","t","n","e","t","n","r","i","a","o","e","t","n","r","i","a","o","s","c","l","u","d","f","p","m","e","t","n","r","e","t","o","s","u","d","t","e","i","n","r","e","t","n","r","t","e","l","c","i","o","t","n","a","s","e","r","a","n","t","e","r","i"],"sources":["../src/compose.ts","../src/errors.ts","../../ripple/dist/devtools-hook.js","../../ripple/dist/errors.js","../../ripple/dist/tracking.js","../../ripple/dist/_error-utils.js","../../ripple/dist/_dev.js","../../ripple/dist/scheduling.js","../../ripple/dist/subscription.js","../../ripple/dist/symbols.js","../../ripple/dist/reactive-base.js","../../ripple/dist/computed.js","../../ripple/dist/signal.js","../src/_dev.ts","../src/ledger.ts"],"sourcesContent":["import type { Command } from './types';\n\n/**\n * Composes multiple commands into a single reversible command.\n *\n * `execute` runs all sub-commands in order. `rollback` runs them in reverse,\n * skipping any that have no rollback defined. The composed command counts as\n * one undo step.\n *\n * @example\n * await ledger.do(compose([\n * { execute: () => { node.x = newX; }, rollback: () => { node.x = oldX; } },\n * { execute: () => { node.y = newY; }, rollback: () => { node.y = oldY; } },\n * ], 'Move node'));\n */\nexport function compose<TData = unknown>(commands: Command<TData>[], label?: string): Command<TData> {\n const anyHasRollback = commands.some((c) => c.rollback != null);\n\n return {\n execute: async (signal) => {\n const done: Command<TData>[] = [];\n\n try {\n for (const c of commands) {\n await c.execute(signal);\n done.push(c);\n }\n } catch (err) {\n for (const c of [...done].reverse()) {\n try {\n await c.rollback?.(signal);\n } catch {\n // best-effort: suppress compensation errors\n }\n }\n\n throw err;\n }\n },\n label,\n rollback: anyHasRollback\n ? async (signal) => {\n let firstError: unknown;\n let hasError = false;\n\n for (const c of [...commands].reverse()) {\n try {\n await c.rollback?.(signal);\n } catch (err) {\n if (!hasError) {\n firstError = err;\n hasError = true;\n }\n }\n }\n\n if (hasError) throw firstError;\n }\n : undefined,\n };\n}\n","/** Base class for all ledger errors. Use `instanceof LedgerError` to catch any ledger-originated error. */\nexport class LedgerError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is LedgerError {\n return err instanceof LedgerError;\n }\n}\n\n/** Thrown when a method is called on a disposed ledger instance. */\nexport class LedgerDisposedError extends LedgerError {}\n\n/** Thrown when a command's `execute()` function throws. The original error is available via `.cause`. */\nexport class LedgerExecutionError extends LedgerError {}\n\n/** Passed to `onRollbackError` when a command's `rollback()` function throws during an undo operation. The original error is available via `.cause`. */\nexport class LedgerRollbackError extends LedgerError {}\n","//#region src/devtools-hook.ts\nvar e = null, t = () => e, n = (t) => {\n\te = t;\n};\n//#endregion\nexport { t as getDevToolsHook, n as setDevToolsHook };\n\n//# sourceMappingURL=devtools-hook.js.map","//#region src/errors.ts\nvar e = class e extends Error {\n\tconstructor(e, t) {\n\t\tsuper(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);\n\t}\n\tstatic is(t) {\n\t\treturn t instanceof e;\n\t}\n}, t = class extends e {}, n = class extends e {}, r = class extends e {}, i = class extends e {}, a = class extends e {}, o = class extends e {};\n//#endregion\nexport { t as RippleComputedCycleError, n as RippleDisposedScopeError, r as RippleEnvironmentError, e as RippleError, i as RippleInfiniteLoopError, a as RippleInvalidCleanupError, o as RippleInvalidStoreError };\n\n//# sourceMappingURL=errors.js.map","//#region src/tracking.ts\nvar e = 0, t = () => ++e, n = () => e, r = () => ({\n\tactiveDirty: \"a\",\n\tbatchDepth: 0,\n\tdirtyWithEffectSubsA: /* @__PURE__ */ new Set(),\n\tdirtyWithEffectSubsB: /* @__PURE__ */ new Set(),\n\tpendingSubscribers: /* @__PURE__ */ new Set()\n}), i = {\n\tscheduling: r(),\n\tscopeCleanups: null,\n\ttracking: null\n}, a = null, o = () => a === null ? i : a.get(), s = () => o().scheduling, c = () => a !== null, l = () => o().tracking, u = (e, t) => {\n\tif (a !== null) {\n\t\tlet n = a.get();\n\t\treturn a.run({\n\t\t\t...n,\n\t\t\ttracking: e\n\t\t}, t);\n\t}\n\tlet n = i;\n\ti = {\n\t\t...i,\n\t\ttracking: e\n\t};\n\ttry {\n\t\treturn t();\n\t} finally {\n\t\ti = n;\n\t}\n}, d = (e, t) => {\n\tif (a !== null) {\n\t\tlet n = a.get();\n\t\treturn a.run({\n\t\t\t...n,\n\t\t\tscopeCleanups: e\n\t\t}, t);\n\t}\n\tlet n = i;\n\ti = {\n\t\t...i,\n\t\tscopeCleanups: e\n\t};\n\ttry {\n\t\treturn t();\n\t} finally {\n\t\ti = n;\n\t}\n}, f = () => o().scopeCleanups, p = (e) => {\n\tlet t = l();\n\tt?.kind === \"effect\" ? t.cleanups.push(e) : f()?.push(e);\n}, m = (e) => {\n\tlet t = a;\n\treturn a = e, t;\n}, h = (e, t) => {\n\tlet n = l();\n\treturn n === null ? t() : u({\n\t\t...n,\n\t\tsourceObserver: e\n\t}, t);\n}, g = (e) => u(null, e), _ = (e) => {\n\tlet t = l();\n\tif (t !== null) {\n\t\tif (t.sourceObserver?.(e), t.kind === \"computed\") t.depCollector.push({\n\t\t\tsource: e,\n\t\t\tversion: e.version\n\t\t});\n\t\telse if (t.kind === \"effect\") {\n\t\t\tlet n = t.effect;\n\t\t\te.addEffectSub(n), t.subscriptions.add(() => e.removeEffectSub(n)), t.deps.set(e, e.version);\n\t\t}\n\t}\n};\n//#endregion\nexport { m as _installContextHook, p as autoRegisterDisposal, r as createSchedulingState, n as getRevision, s as getSchedulingState, f as getScopeCleanups, l as getTracking, c as hasContextHook, t as tickRevision, _ as trackSource, g as untrack, d as withScopeCleanups, h as withSourceObserver, u as withTracking };\n\n//# sourceMappingURL=tracking.js.map","//#region src/_error-utils.ts\nvar e = (e) => e instanceof Error ? e : /* @__PURE__ */ Error(`Non-Error thrown: ${String(e)}`), t = (t) => {\n\tlet n = [];\n\tfor (let r of t) try {\n\t\tr();\n\t} catch (t) {\n\t\tn.push(e(t));\n\t}\n\treturn n;\n}, n = (e, n) => {\n\tlet r = t(e);\n\tif (r.length === 1) throw r[0];\n\tif (r.length > 0) throw AggregateError(r, n);\n}, r = (t, n, r) => {\n\tthrow n.length === 0 ? t : AggregateError([e(t), ...n], r, { cause: e(t) });\n};\n//#endregion\nexport { t as collectErrors, e as ensureError, r as rethrowWith, n as runAll };\n\n//# sourceMappingURL=_error-utils.js.map","//#region src/_dev.ts\nvar e = !globalThis.__RIPPLE_PROD__;\nfunction t(t) {\n\te && console.warn(`[@vielzeug/ripple] ${t}`);\n}\n//#endregion\nexport { t as warn };\n\n//# sourceMappingURL=_dev.js.map","import { runAll as e } from \"./_error-utils.js\";\nimport { RippleInfiniteLoopError as t } from \"./errors.js\";\nimport { warn as n } from \"./_dev.js\";\nimport { getSchedulingState as r, hasContextHook as i } from \"./tracking.js\";\nvar a = !1, o = 0, s = [], c = (e) => e.activeDirty === \"a\" ? e.dirtyWithEffectSubsA : e.dirtyWithEffectSubsB, l = (e, t) => {\n\tlet n = ++o;\n\tfor (let n of t.effectSubs()) e.pendingSubscribers.add(n);\n\tfor (let e of t.computedSubs()) s.push(e);\n\ttry {\n\t\tfor (; s.length > 0;) {\n\t\t\tlet t = s.pop();\n\t\t\tif (t.lastPropEpoch_ !== n && (t.lastPropEpoch_ = n, t.markDirty())) {\n\t\t\t\tt.effectSubs().size > 0 && c(e).add(t);\n\t\t\t\tfor (let e of t.computedSubs()) s.push(e);\n\t\t\t}\n\t\t}\n\t} finally {\n\t\ts.length = 0;\n\t}\n}, u = (e) => {\n\tfor (; c(e).size > 0;) {\n\t\tlet t = c(e);\n\t\te.activeDirty = e.activeDirty === \"a\" ? \"b\" : \"a\", c(e).clear();\n\t\tfor (let n of t) if (n.hasSubscribers() && n.refreshIfDirty()) {\n\t\t\tfor (let t of n.effectSubs()) e.pendingSubscribers.add(t);\n\t\t\tfor (let t of n.computedSubs()) t.markDirty() && t.effectSubs().size > 0 && c(e).add(t);\n\t\t}\n\t\tt.clear();\n\t}\n}, d = (n) => {\n\tlet r = 0;\n\tfor (; n.pendingSubscribers.size > 0 || c(n).size > 0;) {\n\t\tif (++r > 100) throw new t(\"infinite flush loop (> 100 iterations)\");\n\t\tif (c(n).size > 0 && u(n), n.pendingSubscribers.size === 0) continue;\n\t\tlet i = [...n.pendingSubscribers];\n\t\tn.pendingSubscribers.clear(), e(i, \"subscriber errors\");\n\t}\n}, f = globalThis.process?.versions != null, p = (e) => {\n\tif (!e.hasSubscribers()) return;\n\t!a && f && !i() && (a = !0, n(\"Signal updated in a Node.js-like environment. The module-level flush queue is shared across concurrent requests — use per-request worker isolation or the @vielzeug/ripple/ssr sub-path for request-isolated scheduling.\"));\n\tlet t = r();\n\tl(t, e), t.batchDepth === 0 && d(t);\n}, m = (e) => {\n\tlet t = r();\n\tt.batchDepth++;\n\tlet n;\n\ttry {\n\t\tn = e();\n\t} catch (e) {\n\t\tthrow t.batchDepth--, t.batchDepth === 0 && (t.pendingSubscribers.clear(), t.dirtyWithEffectSubsA.clear(), t.dirtyWithEffectSubsB.clear()), e;\n\t}\n\treturn t.batchDepth--, t.batchDepth === 0 && d(t), n;\n};\n//#endregion\nexport { m as batch, p as notifyNodeChange };\n\n//# sourceMappingURL=scheduling.js.map","//#region src/subscription.ts\nvar e = class {\n\tfn_;\n\tdisposed_ = !1;\n\tconstructor(e) {\n\t\tthis.fn_ = e;\n\t}\n\tget disposed() {\n\t\treturn this.disposed_;\n\t}\n\tdispose() {\n\t\tif (this.disposed_) return;\n\t\tthis.disposed_ = !0;\n\t\tlet e = this.fn_;\n\t\tthis.fn_ = null, e();\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n}, t = class {\n\tawaitDone_;\n\tgetCurrentRun_;\n\tsyncStop_;\n\tasyncDisposePromise_ = null;\n\tconstructor(e, t, n) {\n\t\tthis.awaitDone_ = t, this.getCurrentRun_ = n, this.syncStop_ = e;\n\t}\n\tget disposed() {\n\t\treturn this.syncStop_.disposed;\n\t}\n\tdispose() {\n\t\tthis.syncStop_.dispose();\n\t}\n\trun() {\n\t\treturn this.getCurrentRun_() ?? Promise.resolve();\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n\t[Symbol.asyncDispose]() {\n\t\treturn this.asyncDisposePromise_ === null ? (this.dispose(), this.asyncDisposePromise_ = this.awaitDone_(), this.asyncDisposePromise_) : this.asyncDisposePromise_;\n\t}\n};\n//#endregion\nexport { t as AsyncSubscriptionImpl, e as SubscriptionImpl };\n\n//# sourceMappingURL=subscription.js.map","//#region src/symbols.ts\nvar e = Symbol(\"ripple.is-signal\"), t = Symbol(\"ripple.is-computed\"), n = Symbol(\"ripple.is-store\"), r = Symbol(\"ripple.uninitialized\");\n//#endregion\nexport { t as IS_COMPUTED, e as IS_SIGNAL, n as IS_STORE, r as UNINITIALIZED };\n\n//# sourceMappingURL=symbols.js.map","import { IS_COMPUTED as e, IS_SIGNAL as t } from \"./symbols.js\";\n//#region src/reactive-base.ts\nvar n = new FinalizationRegistry(({ key: e, map: t }) => {\n\tt.delete(e);\n}), r = class {\n\tversion = 0;\n\tname;\n\t[t] = !0;\n\tcomputedSubs_ = /* @__PURE__ */ new Map();\n\teffectSubs_ = /* @__PURE__ */ new Set();\n\tconstructor(e) {\n\t\tthis.name = e;\n\t}\n\taddComputedSub(e) {\n\t\tlet t = new WeakRef(e);\n\t\tthis.computedSubs_.set(e, t), n.register(e, {\n\t\t\tkey: e,\n\t\t\tmap: this.computedSubs_\n\t\t}, t);\n\t}\n\tremoveComputedSub(e) {\n\t\tlet t = this.computedSubs_.get(e);\n\t\tt !== void 0 && (this.computedSubs_.delete(e), n.unregister(t));\n\t}\n\taddEffectSub(e) {\n\t\tthis.effectSubs_.add(e);\n\t}\n\tremoveEffectSub(e) {\n\t\tthis.effectSubs_.delete(e);\n\t}\n\tclearSubscribers() {\n\t\tfor (let e of this.computedSubs_.values()) n.unregister(e);\n\t\tthis.computedSubs_.clear(), this.effectSubs_.clear();\n\t}\n\thasSubscribers() {\n\t\tif (this.effectSubs_.size > 0) return !0;\n\t\tfor (let e of this.computedSubs_.values()) if (e.deref() !== void 0) return !0;\n\t\treturn !1;\n\t}\n\t*computedSubs() {\n\t\tfor (let [e, t] of this.computedSubs_) {\n\t\t\tlet r = t.deref();\n\t\t\tr === void 0 ? (this.computedSubs_.delete(e), n.unregister(t)) : yield r;\n\t\t}\n\t}\n\teffectSubs() {\n\t\treturn this.effectSubs_;\n\t}\n}, i = class extends r {\n\t[e] = !0;\n\tlastPropEpoch_ = 0;\n};\n//#endregion\nexport { i as ComputedBase, r as ReactiveBase };\n\n//# sourceMappingURL=reactive-base.js.map","import { getDevToolsHook as e } from \"./devtools-hook.js\";\nimport { ensureError as t } from \"./_error-utils.js\";\nimport { RippleComputedCycleError as n } from \"./errors.js\";\nimport { autoRegisterDisposal as r, getRevision as i, trackSource as a, withTracking as o } from \"./tracking.js\";\nimport { SubscriptionImpl as s } from \"./subscription.js\";\nimport { UNINITIALIZED as c } from \"./symbols.js\";\nimport { ComputedBase as l } from \"./reactive-base.js\";\n//#region src/computed.ts\nvar u = class extends l {\n\tvalue_;\n\tdirty_;\n\tcomputing_;\n\tdisposed_;\n\tdeps_;\n\tcompute_;\n\tequals_;\n\tmaxRevision_;\n\tconstructor(e, t) {\n\t\tlet { equals: n, name: r } = t ?? {};\n\t\tsuper(r), this.value_ = c, this.dirty_ = !0, this.computing_ = !1, this.disposed_ = !1, this.deps_ = [], this.maxRevision_ = -1, this.compute_ = e, this.equals_ = n === void 0 ? Object.is : (e, t) => n(e, t);\n\t}\n\tmarkDirty() {\n\t\treturn this.disposed_ || this.dirty_ ? !1 : (this.dirty_ = !0, !0);\n\t}\n\trefreshIfDirty() {\n\t\tif (!this.dirty_) return !1;\n\t\tif (i() <= this.maxRevision_) return this.dirty_ = !1, !1;\n\t\tif (this.deps_.length > 0) {\n\t\t\tlet e = !0;\n\t\t\tfor (let t of this.deps_) {\n\t\t\t\tlet n = t.source;\n\t\t\t\tif (\"refreshIfDirty\" in n && n.refreshIfDirty(), n.version !== t.version) {\n\t\t\t\t\te = !1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (e) return this.dirty_ = !1, this.maxRevision_ = i(), !1;\n\t\t}\n\t\treturn this.recompute();\n\t}\n\trunCompute(e) {\n\t\ttry {\n\t\t\treturn o({\n\t\t\t\tcomputed: this,\n\t\t\t\tdepCollector: e,\n\t\t\t\tkind: \"computed\"\n\t\t\t}, this.compute_);\n\t\t} catch (e) {\n\t\t\tthrow t(e);\n\t\t}\n\t}\n\trecompute() {\n\t\tif (this.computing_) throw new n(`computed cycle detected${this.name ? ` \"${this.name}\"` : \"\"}`);\n\t\tthis.computing_ = !0;\n\t\ttry {\n\t\t\tlet t = [];\n\t\t\te()?.compute?.({ name: this.name });\n\t\t\tlet n = this.runCompute(t);\n\t\t\treturn this.dirty_ = !1, this.maxRevision_ = i(), this.updateDeps(t), this.value_ === c || !this.equals_(this.value_, n) ? (this.value_ = n, this.version++, !0) : !1;\n\t\t} finally {\n\t\t\tthis.computing_ = !1;\n\t\t}\n\t}\n\tupdateDeps(e) {\n\t\tlet t = this.deps_;\n\t\tif (t.length === e.length && t.every((t, n) => t.source === e[n].source)) {\n\t\t\tfor (let n = 0; n < e.length; n++) t[n].version = e[n].version;\n\t\t\treturn;\n\t\t}\n\t\tlet n = new Set(t.map((e) => e.source)), r = new Set(e.map((e) => e.source));\n\t\tfor (let e of t) r.has(e.source) || e.source.removeComputedSub(this);\n\t\tfor (let t of e) n.has(t.source) || t.source.addComputedSub(this);\n\t\tthis.deps_ = e;\n\t}\n\tget value() {\n\t\treturn this.disposed_ ? this.value_ === c ? void 0 : this.value_ : (this.refreshIfDirty(), a(this), this.value_);\n\t}\n\tpeek() {\n\t\treturn this.disposed_ ? this.value_ === c ? void 0 : this.value_ : (this.refreshIfDirty(), this.value_);\n\t}\n\tsubscribe = (e) => {\n\t\tif (this.disposed_) {\n\t\t\tlet e = new s(() => {});\n\t\t\treturn e.dispose(), e;\n\t\t}\n\t\treturn this.refreshIfDirty(), this.addEffectSub(e), new s(() => {\n\t\t\tthis.removeEffectSub(e);\n\t\t});\n\t};\n\tget disposed() {\n\t\treturn this.disposed_;\n\t}\n\tdispose() {\n\t\tif (!this.disposed_) {\n\t\t\tthis.disposed_ = !0;\n\t\t\tfor (let e of this.deps_) e.source.removeComputedSub(this);\n\t\t\tthis.deps_ = [], this.clearSubscribers(), e()?.dispose?.({\n\t\t\t\tkind: \"computed\",\n\t\t\t\tname: this.name\n\t\t\t});\n\t\t}\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n}, d = (e, t) => {\n\tlet n = new u(e, t);\n\treturn r(() => n.dispose()), n;\n};\n//#endregion\nexport { u as ComputedImpl, d as computed };\n\n//# sourceMappingURL=computed.js.map","import { getDevToolsHook as e } from \"./devtools-hook.js\";\nimport { tickRevision as t, trackSource as n } from \"./tracking.js\";\nimport { notifyNodeChange as r } from \"./scheduling.js\";\nimport { SubscriptionImpl as i } from \"./subscription.js\";\nimport { ReactiveBase as a } from \"./reactive-base.js\";\n//#region src/signal.ts\nvar o = class extends a {\n\tvalue_;\n\tequals_;\n\tdisposed_;\n\tconstructor(e, t, n) {\n\t\tsuper(n), this.value_ = e, this.equals_ = t ?? Object.is, this.disposed_ = !1;\n\t}\n\tget value() {\n\t\treturn this.disposed_ || n(this), this.value_;\n\t}\n\tset value(n) {\n\t\tif (this.disposed_ || this.equals_(this.value_, n)) return;\n\t\tlet i = this.value_;\n\t\tthis.value_ = n, this.version = t(), e()?.write?.({\n\t\t\tname: this.name,\n\t\t\tnewValue: n,\n\t\t\toldValue: i\n\t\t}), r(this);\n\t}\n\tpeek() {\n\t\treturn this.value_;\n\t}\n\tsubscribe = (e) => {\n\t\tif (this.disposed_) {\n\t\t\tlet e = new i(() => {});\n\t\t\treturn e.dispose(), e;\n\t\t}\n\t\treturn this.addEffectSub(e), new i(() => {\n\t\t\tthis.removeEffectSub(e);\n\t\t});\n\t};\n\tget disposed() {\n\t\treturn this.disposed_;\n\t}\n\tdispose() {\n\t\tthis.disposed_ || (this.disposed_ = !0, this.clearSubscribers(), e()?.dispose?.({\n\t\t\tkind: \"signal\",\n\t\t\tname: this.name\n\t\t}));\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n}, s = (e, t) => new o(e, t?.equals, t?.name);\n//#endregion\nexport { o as SignalImpl, s as signal };\n\n//# sourceMappingURL=signal.js.map","const isDev = !(globalThis as { __LEDGER_PROD__?: boolean }).__LEDGER_PROD__;\n\n/** @internal @security Messages may include user data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/ledger] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n","import { computed, signal } from '@vielzeug/ripple';\n\nimport type { Command, CommandMeta, Ledger, LedgerCallOptions, LedgerOptions } from './types';\n\nimport { warn } from './_dev';\nimport { LedgerDisposedError, LedgerExecutionError, LedgerRollbackError } from './errors';\n\nfunction toMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\ntype StackEntry<TData = unknown> = {\n execute: (signal?: AbortSignal) => Promise<void>;\n meta: CommandMeta<TData>;\n rollback?: (signal?: AbortSignal) => Promise<void>;\n};\n\nfunction entryFromCommand<TData>(command: Command<TData>): StackEntry<TData> {\n const { rollback } = command;\n\n return {\n execute: async (signal) => command.execute(signal),\n meta: { data: command.data, label: command.label },\n rollback: rollback != null ? async (signal) => rollback(signal) : undefined,\n };\n}\n\n/**\n * Creates an async undo/redo command history.\n *\n * Each command is `{ execute, rollback? }`. `rollback` is optional — commands\n * without one are still tracked in history but undo skips the reversal step.\n * Operations are serialised — concurrent calls queue behind each other.\n * All state signals are Ripple `Computed` values for zero-glue UI binding.\n *\n * `execute`/`rollback` receive an `AbortSignal` — merged from the ledger's own\n * `disposalSignal` and any `signal` passed to `do()`/`undo()`/`redo()` — so long-running\n * commands can observe cancellation or disposal.\n *\n * @example\n * const ledger = createLedger({ maxHistory: 50 });\n * await ledger.do({ execute: () => { item.name = next; }, rollback: () => { item.name = prev; } });\n * await ledger.undo();\n * await ledger.redo();\n * using ledger = createLedger();\n */\nexport function createLedger<TData = unknown>(options: LedgerOptions<TData> = {}): Ledger<TData> {\n const { maxHistory = 100, onRollbackError } = options;\n\n if (maxHistory < 1) warn('maxHistory must be >= 1; history tracking is disabled for this ledger.');\n\n const undoStack = signal<StackEntry<TData>[]>([], { name: 'ledger:undoStack' });\n const redoStack = signal<StackEntry<TData>[]>([], { name: 'ledger:redoStack' });\n const pending = signal(0, { name: 'ledger:pending' });\n const processing = signal(false, { name: 'ledger:processing' });\n\n const canUndo = computed(() => undoStack.value.length > 0, { name: 'ledger:canUndo' });\n const canRedo = computed(() => redoStack.value.length > 0, { name: 'ledger:canRedo' });\n const historySize = computed(() => undoStack.value.length, { name: 'ledger:historySize' });\n const isProcessing = computed(() => processing.value, { name: 'ledger:isProcessing' });\n const pendingCount = computed(() => pending.value, { name: 'ledger:pendingCount' });\n const historySnapshot = computed(\n (): readonly CommandMeta<TData>[] => [...undoStack.value].reverse().map((e) => e.meta),\n { name: 'ledger:historySnapshot' },\n );\n\n const disposables = [\n undoStack,\n redoStack,\n pending,\n processing,\n canUndo,\n canRedo,\n historySize,\n isProcessing,\n pendingCount,\n historySnapshot,\n ];\n\n let isDisposed = false;\n let queue = Promise.resolve();\n\n const ac = new AbortController();\n\n function operationSignal(external?: AbortSignal): AbortSignal {\n return external ? AbortSignal.any([external, ac.signal]) : ac.signal;\n }\n\n function enqueue(method: string, task: () => Promise<void>): Promise<void> {\n if (isDisposed) return Promise.reject(new LedgerDisposedError(`Cannot call ${method}() on a disposed ledger.`));\n\n pending.value++;\n\n const current = queue.then(task).finally(() => {\n if (!isDisposed) pending.value--;\n });\n\n queue = current.catch(() => {});\n\n return current;\n }\n\n async function withProcessing(fn: () => Promise<void>): Promise<void> {\n processing.value = true;\n\n try {\n await fn();\n } finally {\n if (!isDisposed) processing.value = false;\n }\n }\n\n async function runDo(entry: StackEntry<TData>, signal: AbortSignal): Promise<void> {\n await withProcessing(async () => {\n try {\n await entry.execute(signal);\n } catch (err) {\n throw new LedgerExecutionError(toMessage(err), { cause: err });\n }\n\n if (isDisposed) return;\n\n const next = [...undoStack.value, entry];\n\n if (next.length > maxHistory) next.shift();\n\n undoStack.value = next;\n redoStack.value = [];\n });\n }\n\n async function runUndo(signal: AbortSignal): Promise<void> {\n const stack = undoStack.value;\n\n if (stack.length === 0) return;\n\n const entry = stack[stack.length - 1];\n\n await withProcessing(async () => {\n if (entry.rollback) {\n try {\n await entry.rollback(signal);\n } catch (err) {\n warn(`rollback() threw for \"${entry.meta.label ?? '(unlabelled)'}\". Stack position unchanged.`);\n onRollbackError?.(new LedgerRollbackError(toMessage(err), { cause: err }), entry.meta);\n\n return;\n }\n }\n\n if (isDisposed) return;\n\n undoStack.value = stack.slice(0, -1);\n redoStack.value = [...redoStack.value, entry];\n });\n }\n\n async function runRedo(signal: AbortSignal): Promise<void> {\n const stack = redoStack.value;\n\n if (stack.length === 0) return;\n\n const entry = stack[stack.length - 1];\n\n await withProcessing(async () => {\n try {\n await entry.execute(signal);\n } catch (err) {\n throw new LedgerExecutionError(toMessage(err), { cause: err });\n }\n\n if (isDisposed) return;\n\n redoStack.value = stack.slice(0, -1);\n undoStack.value = [...undoStack.value, entry];\n });\n }\n\n function clear(): Promise<void> {\n return enqueue('clear', async () => {\n if (isDisposed) return;\n\n undoStack.value = [];\n redoStack.value = [];\n });\n }\n\n function dispose(): void {\n isDisposed = true;\n ac.abort();\n\n undoStack.value = [];\n redoStack.value = [];\n\n for (const d of disposables) d.dispose();\n }\n\n return {\n canRedo,\n canUndo,\n\n clear,\n\n get disposalSignal(): AbortSignal {\n return ac.signal;\n },\n dispose,\n get disposed(): boolean {\n return isDisposed;\n },\n\n do(command: Command<TData>, callOptions?: LedgerCallOptions): Promise<void> {\n return enqueue('do', () => runDo(entryFromCommand<TData>(command), operationSignal(callOptions?.signal)));\n },\n\n historySize,\n historySnapshot,\n isProcessing,\n pendingCount,\n\n redo(callOptions?: LedgerCallOptions): Promise<void> {\n return enqueue('redo', () => runRedo(operationSignal(callOptions?.signal)));\n },\n\n [Symbol.dispose](): void {\n dispose();\n },\n\n undo(callOptions?: LedgerCallOptions): Promise<void> {\n return enqueue('undo', () => runUndo(operationSignal(callOptions?.signal)));\n },\n };\n}\n"],"mappings":"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"}
package/dist/ledger.js ADDED
@@ -0,0 +1,2 @@
1
+ function e(e,t){return{execute:async t=>{let n=[];try{for(let r of e)await r.execute(t),n.push(r)}catch(e){for(let e of[...n].reverse())try{await e.rollback?.(t)}catch{}throw e}},label:t,rollback:e.some(e=>e.rollback!=null)?async t=>{let n,r=!1;for(let i of[...e].reverse())try{await i.rollback?.(t)}catch(e){r||=(n=e,!0)}if(r)throw n}:void 0}}var t=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},n=class extends t{},r=class extends t{},i=class extends t{},a=null,o=()=>a,s=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},c=class extends s{},l=class extends s{},u=0,d=()=>++u,f=()=>u,p={scheduling:{activeDirty:`a`,batchDepth:0,dirtyWithEffectSubsA:new Set,dirtyWithEffectSubsB:new Set,pendingSubscribers:new Set},scopeCleanups:null,tracking:null},m=null,h=()=>m===null?p:m.get(),g=()=>h().scheduling,_=()=>m!==null,v=()=>h().tracking,y=(e,t)=>{if(m!==null){let n=m.get();return m.run({...n,tracking:e},t)}let n=p;p={...p,tracking:e};try{return t()}finally{p=n}},b=()=>h().scopeCleanups,x=e=>{let t=v();t?.kind===`effect`?t.cleanups.push(e):b()?.push(e)},S=e=>{let t=v();if(t!==null){if(t.sourceObserver?.(e),t.kind===`computed`)t.depCollector.push({source:e,version:e.version});else if(t.kind===`effect`){let n=t.effect;e.addEffectSub(n),t.subscriptions.add(()=>e.removeEffectSub(n)),t.deps.set(e,e.version)}}},C=e=>e instanceof Error?e:Error(`Non-Error thrown: ${String(e)}`),w=e=>{let t=[];for(let n of e)try{n()}catch(e){t.push(C(e))}return t},T=(e,t)=>{let n=w(e);if(n.length===1)throw n[0];if(n.length>0)throw AggregateError(n,t)},E=!globalThis.__RIPPLE_PROD__;function D(e){E&&console.warn(`[@vielzeug/ripple] ${e}`)}var O=!1,k=0,A=[],j=e=>e.activeDirty===`a`?e.dirtyWithEffectSubsA:e.dirtyWithEffectSubsB,M=(e,t)=>{let n=++k;for(let n of t.effectSubs())e.pendingSubscribers.add(n);for(let e of t.computedSubs())A.push(e);try{for(;A.length>0;){let t=A.pop();if(t.lastPropEpoch_!==n&&(t.lastPropEpoch_=n,t.markDirty())){t.effectSubs().size>0&&j(e).add(t);for(let e of t.computedSubs())A.push(e)}}}finally{A.length=0}},N=e=>{for(;j(e).size>0;){let t=j(e);e.activeDirty=e.activeDirty===`a`?`b`:`a`,j(e).clear();for(let n of t)if(n.hasSubscribers()&&n.refreshIfDirty()){for(let t of n.effectSubs())e.pendingSubscribers.add(t);for(let t of n.computedSubs())t.markDirty()&&t.effectSubs().size>0&&j(e).add(t)}t.clear()}},P=e=>{let t=0;for(;e.pendingSubscribers.size>0||j(e).size>0;){if(++t>100)throw new l(`infinite flush loop (> 100 iterations)`);if(j(e).size>0&&N(e),e.pendingSubscribers.size===0)continue;let n=[...e.pendingSubscribers];e.pendingSubscribers.clear(),T(n,`subscriber errors`)}},F=globalThis.process?.versions!=null,I=e=>{if(!e.hasSubscribers())return;!O&&F&&!_()&&(O=!0,D(`Signal updated in a Node.js-like environment. The module-level flush queue is shared across concurrent requests — use per-request worker isolation or the @vielzeug/ripple/ssr sub-path for request-isolated scheduling.`));let t=g();M(t,e),t.batchDepth===0&&P(t)},L=class{fn_;disposed_=!1;constructor(e){this.fn_=e}get disposed(){return this.disposed_}dispose(){if(this.disposed_)return;this.disposed_=!0;let e=this.fn_;this.fn_=null,e()}[Symbol.dispose](){this.dispose()}},R=Symbol(`ripple.is-signal`),z=Symbol(`ripple.is-computed`),B=Symbol(`ripple.uninitialized`),V=new FinalizationRegistry(({key:e,map:t})=>{t.delete(e)}),H=class{version=0;name;[R]=!0;computedSubs_=new Map;effectSubs_=new Set;constructor(e){this.name=e}addComputedSub(e){let t=new WeakRef(e);this.computedSubs_.set(e,t),V.register(e,{key:e,map:this.computedSubs_},t)}removeComputedSub(e){let t=this.computedSubs_.get(e);t!==void 0&&(this.computedSubs_.delete(e),V.unregister(t))}addEffectSub(e){this.effectSubs_.add(e)}removeEffectSub(e){this.effectSubs_.delete(e)}clearSubscribers(){for(let e of this.computedSubs_.values())V.unregister(e);this.computedSubs_.clear(),this.effectSubs_.clear()}hasSubscribers(){if(this.effectSubs_.size>0)return!0;for(let e of this.computedSubs_.values())if(e.deref()!==void 0)return!0;return!1}*computedSubs(){for(let[e,t]of this.computedSubs_){let n=t.deref();n===void 0?(this.computedSubs_.delete(e),V.unregister(t)):yield n}}effectSubs(){return this.effectSubs_}},U=class extends H{[z]=!0;lastPropEpoch_=0},W=class extends U{value_;dirty_;computing_;disposed_;deps_;compute_;equals_;maxRevision_;constructor(e,t){let{equals:n,name:r}=t??{};super(r),this.value_=B,this.dirty_=!0,this.computing_=!1,this.disposed_=!1,this.deps_=[],this.maxRevision_=-1,this.compute_=e,this.equals_=n===void 0?Object.is:(e,t)=>n(e,t)}markDirty(){return this.disposed_||this.dirty_?!1:(this.dirty_=!0,!0)}refreshIfDirty(){if(!this.dirty_)return!1;if(f()<=this.maxRevision_)return this.dirty_=!1,!1;if(this.deps_.length>0){let e=!0;for(let t of this.deps_){let n=t.source;if(`refreshIfDirty`in n&&n.refreshIfDirty(),n.version!==t.version){e=!1;break}}if(e)return this.dirty_=!1,this.maxRevision_=f(),!1}return this.recompute()}runCompute(e){try{return y({computed:this,depCollector:e,kind:`computed`},this.compute_)}catch(e){throw C(e)}}recompute(){if(this.computing_)throw new c(`computed cycle detected${this.name?` "${this.name}"`:``}`);this.computing_=!0;try{let e=[];o()?.compute?.({name:this.name});let t=this.runCompute(e);return this.dirty_=!1,this.maxRevision_=f(),this.updateDeps(e),this.value_===B||!this.equals_(this.value_,t)?(this.value_=t,this.version++,!0):!1}finally{this.computing_=!1}}updateDeps(e){let t=this.deps_;if(t.length===e.length&&t.every((t,n)=>t.source===e[n].source)){for(let n=0;n<e.length;n++)t[n].version=e[n].version;return}let n=new Set(t.map(e=>e.source)),r=new Set(e.map(e=>e.source));for(let e of t)r.has(e.source)||e.source.removeComputedSub(this);for(let t of e)n.has(t.source)||t.source.addComputedSub(this);this.deps_=e}get value(){return this.disposed_?this.value_===B?void 0:this.value_:(this.refreshIfDirty(),S(this),this.value_)}peek(){return this.disposed_?this.value_===B?void 0:this.value_:(this.refreshIfDirty(),this.value_)}subscribe=e=>{if(this.disposed_){let e=new L(()=>{});return e.dispose(),e}return this.refreshIfDirty(),this.addEffectSub(e),new L(()=>{this.removeEffectSub(e)})};get disposed(){return this.disposed_}dispose(){if(!this.disposed_){this.disposed_=!0;for(let e of this.deps_)e.source.removeComputedSub(this);this.deps_=[],this.clearSubscribers(),o()?.dispose?.({kind:`computed`,name:this.name})}}[Symbol.dispose](){this.dispose()}},G=(e,t)=>{let n=new W(e,t);return x(()=>n.dispose()),n},K=class extends H{value_;equals_;disposed_;constructor(e,t,n){super(n),this.value_=e,this.equals_=t??Object.is,this.disposed_=!1}get value(){return this.disposed_||S(this),this.value_}set value(e){if(this.disposed_||this.equals_(this.value_,e))return;let t=this.value_;this.value_=e,this.version=d(),o()?.write?.({name:this.name,newValue:e,oldValue:t}),I(this)}peek(){return this.value_}subscribe=e=>{if(this.disposed_){let e=new L(()=>{});return e.dispose(),e}return this.addEffectSub(e),new L(()=>{this.removeEffectSub(e)})};get disposed(){return this.disposed_}dispose(){this.disposed_||(this.disposed_=!0,this.clearSubscribers(),o()?.dispose?.({kind:`signal`,name:this.name}))}[Symbol.dispose](){this.dispose()}},q=(e,t)=>new K(e,t?.equals,t?.name),J=!globalThis.__LEDGER_PROD__;function Y(e){J&&console.warn(`[@vielzeug/ledger] ${e}`)}function X(e){return e instanceof Error?e.message:String(e)}function Z(e){let{rollback:t}=e;return{execute:async t=>e.execute(t),meta:{data:e.data,label:e.label},rollback:t==null?void 0:async e=>t(e)}}function Q(e={}){let{maxHistory:t=100,onRollbackError:a}=e;t<1&&Y(`maxHistory must be >= 1; history tracking is disabled for this ledger.`);let o=q([],{name:`ledger:undoStack`}),s=q([],{name:`ledger:redoStack`}),c=q(0,{name:`ledger:pending`}),l=q(!1,{name:`ledger:processing`}),u=G(()=>o.value.length>0,{name:`ledger:canUndo`}),d=G(()=>s.value.length>0,{name:`ledger:canRedo`}),f=G(()=>o.value.length,{name:`ledger:historySize`}),p=G(()=>l.value,{name:`ledger:isProcessing`}),m=G(()=>c.value,{name:`ledger:pendingCount`}),h=G(()=>[...o.value].reverse().map(e=>e.meta),{name:`ledger:historySnapshot`}),g=[o,s,c,l,u,d,f,p,m,h],_=!1,v=Promise.resolve(),y=new AbortController;function b(e){return e?AbortSignal.any([e,y.signal]):y.signal}function x(e,t){if(_)return Promise.reject(new n(`Cannot call ${e}() on a disposed ledger.`));c.value++;let r=v.then(t).finally(()=>{_||c.value--});return v=r.catch(()=>{}),r}async function S(e){l.value=!0;try{await e()}finally{_||(l.value=!1)}}async function C(e,n){await S(async()=>{try{await e.execute(n)}catch(e){throw new r(X(e),{cause:e})}if(_)return;let i=[...o.value,e];i.length>t&&i.shift(),o.value=i,s.value=[]})}async function w(e){let t=o.value;if(t.length===0)return;let n=t[t.length-1];await S(async()=>{if(n.rollback)try{await n.rollback(e)}catch(e){Y(`rollback() threw for "${n.meta.label??`(unlabelled)`}". Stack position unchanged.`),a?.(new i(X(e),{cause:e}),n.meta);return}_||(o.value=t.slice(0,-1),s.value=[...s.value,n])})}async function T(e){let t=s.value;if(t.length===0)return;let n=t[t.length-1];await S(async()=>{try{await n.execute(e)}catch(e){throw new r(X(e),{cause:e})}_||(s.value=t.slice(0,-1),o.value=[...o.value,n])})}function E(){return x(`clear`,async()=>{_||(o.value=[],s.value=[])})}function D(){_=!0,y.abort(),o.value=[],s.value=[];for(let e of g)e.dispose()}return{canRedo:d,canUndo:u,clear:E,get disposalSignal(){return y.signal},dispose:D,get disposed(){return _},do(e,t){return x(`do`,()=>C(Z(e),b(t?.signal)))},historySize:f,historySnapshot:h,isProcessing:p,pendingCount:m,redo(e){return x(`redo`,()=>T(b(e?.signal)))},[Symbol.dispose](){D()},undo(e){return x(`undo`,()=>w(b(e?.signal)))}}}export{n as LedgerDisposedError,t as LedgerError,r as LedgerExecutionError,i as LedgerRollbackError,e as compose,Q as createLedger};
2
+ //# sourceMappingURL=ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.js","names":["e","t","n","e","t","n","r","i","a","o","e","t","n","r","i","a","o","s","c","l","u","d","f","p","m","e","t","n","r","e","t","o","s","u","d","t","e","i","n","r","e","t","n","r","t","e","l","c","i","o","t","n","a","s","e","r","a","n","t","e","r","i"],"sources":["../src/compose.ts","../src/errors.ts","../../ripple/dist/devtools-hook.js","../../ripple/dist/errors.js","../../ripple/dist/tracking.js","../../ripple/dist/_error-utils.js","../../ripple/dist/_dev.js","../../ripple/dist/scheduling.js","../../ripple/dist/subscription.js","../../ripple/dist/symbols.js","../../ripple/dist/reactive-base.js","../../ripple/dist/computed.js","../../ripple/dist/signal.js","../src/_dev.ts","../src/ledger.ts"],"sourcesContent":["import type { Command } from './types';\n\n/**\n * Composes multiple commands into a single reversible command.\n *\n * `execute` runs all sub-commands in order. `rollback` runs them in reverse,\n * skipping any that have no rollback defined. The composed command counts as\n * one undo step.\n *\n * @example\n * await ledger.do(compose([\n * { execute: () => { node.x = newX; }, rollback: () => { node.x = oldX; } },\n * { execute: () => { node.y = newY; }, rollback: () => { node.y = oldY; } },\n * ], 'Move node'));\n */\nexport function compose<TData = unknown>(commands: Command<TData>[], label?: string): Command<TData> {\n const anyHasRollback = commands.some((c) => c.rollback != null);\n\n return {\n execute: async (signal) => {\n const done: Command<TData>[] = [];\n\n try {\n for (const c of commands) {\n await c.execute(signal);\n done.push(c);\n }\n } catch (err) {\n for (const c of [...done].reverse()) {\n try {\n await c.rollback?.(signal);\n } catch {\n // best-effort: suppress compensation errors\n }\n }\n\n throw err;\n }\n },\n label,\n rollback: anyHasRollback\n ? async (signal) => {\n let firstError: unknown;\n let hasError = false;\n\n for (const c of [...commands].reverse()) {\n try {\n await c.rollback?.(signal);\n } catch (err) {\n if (!hasError) {\n firstError = err;\n hasError = true;\n }\n }\n }\n\n if (hasError) throw firstError;\n }\n : undefined,\n };\n}\n","/** Base class for all ledger errors. Use `instanceof LedgerError` to catch any ledger-originated error. */\nexport class LedgerError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is LedgerError {\n return err instanceof LedgerError;\n }\n}\n\n/** Thrown when a method is called on a disposed ledger instance. */\nexport class LedgerDisposedError extends LedgerError {}\n\n/** Thrown when a command's `execute()` function throws. The original error is available via `.cause`. */\nexport class LedgerExecutionError extends LedgerError {}\n\n/** Passed to `onRollbackError` when a command's `rollback()` function throws during an undo operation. The original error is available via `.cause`. */\nexport class LedgerRollbackError extends LedgerError {}\n","//#region src/devtools-hook.ts\nvar e = null, t = () => e, n = (t) => {\n\te = t;\n};\n//#endregion\nexport { t as getDevToolsHook, n as setDevToolsHook };\n\n//# sourceMappingURL=devtools-hook.js.map","//#region src/errors.ts\nvar e = class e extends Error {\n\tconstructor(e, t) {\n\t\tsuper(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);\n\t}\n\tstatic is(t) {\n\t\treturn t instanceof e;\n\t}\n}, t = class extends e {}, n = class extends e {}, r = class extends e {}, i = class extends e {}, a = class extends e {}, o = class extends e {};\n//#endregion\nexport { t as RippleComputedCycleError, n as RippleDisposedScopeError, r as RippleEnvironmentError, e as RippleError, i as RippleInfiniteLoopError, a as RippleInvalidCleanupError, o as RippleInvalidStoreError };\n\n//# sourceMappingURL=errors.js.map","//#region src/tracking.ts\nvar e = 0, t = () => ++e, n = () => e, r = () => ({\n\tactiveDirty: \"a\",\n\tbatchDepth: 0,\n\tdirtyWithEffectSubsA: /* @__PURE__ */ new Set(),\n\tdirtyWithEffectSubsB: /* @__PURE__ */ new Set(),\n\tpendingSubscribers: /* @__PURE__ */ new Set()\n}), i = {\n\tscheduling: r(),\n\tscopeCleanups: null,\n\ttracking: null\n}, a = null, o = () => a === null ? i : a.get(), s = () => o().scheduling, c = () => a !== null, l = () => o().tracking, u = (e, t) => {\n\tif (a !== null) {\n\t\tlet n = a.get();\n\t\treturn a.run({\n\t\t\t...n,\n\t\t\ttracking: e\n\t\t}, t);\n\t}\n\tlet n = i;\n\ti = {\n\t\t...i,\n\t\ttracking: e\n\t};\n\ttry {\n\t\treturn t();\n\t} finally {\n\t\ti = n;\n\t}\n}, d = (e, t) => {\n\tif (a !== null) {\n\t\tlet n = a.get();\n\t\treturn a.run({\n\t\t\t...n,\n\t\t\tscopeCleanups: e\n\t\t}, t);\n\t}\n\tlet n = i;\n\ti = {\n\t\t...i,\n\t\tscopeCleanups: e\n\t};\n\ttry {\n\t\treturn t();\n\t} finally {\n\t\ti = n;\n\t}\n}, f = () => o().scopeCleanups, p = (e) => {\n\tlet t = l();\n\tt?.kind === \"effect\" ? t.cleanups.push(e) : f()?.push(e);\n}, m = (e) => {\n\tlet t = a;\n\treturn a = e, t;\n}, h = (e, t) => {\n\tlet n = l();\n\treturn n === null ? t() : u({\n\t\t...n,\n\t\tsourceObserver: e\n\t}, t);\n}, g = (e) => u(null, e), _ = (e) => {\n\tlet t = l();\n\tif (t !== null) {\n\t\tif (t.sourceObserver?.(e), t.kind === \"computed\") t.depCollector.push({\n\t\t\tsource: e,\n\t\t\tversion: e.version\n\t\t});\n\t\telse if (t.kind === \"effect\") {\n\t\t\tlet n = t.effect;\n\t\t\te.addEffectSub(n), t.subscriptions.add(() => e.removeEffectSub(n)), t.deps.set(e, e.version);\n\t\t}\n\t}\n};\n//#endregion\nexport { m as _installContextHook, p as autoRegisterDisposal, r as createSchedulingState, n as getRevision, s as getSchedulingState, f as getScopeCleanups, l as getTracking, c as hasContextHook, t as tickRevision, _ as trackSource, g as untrack, d as withScopeCleanups, h as withSourceObserver, u as withTracking };\n\n//# sourceMappingURL=tracking.js.map","//#region src/_error-utils.ts\nvar e = (e) => e instanceof Error ? e : /* @__PURE__ */ Error(`Non-Error thrown: ${String(e)}`), t = (t) => {\n\tlet n = [];\n\tfor (let r of t) try {\n\t\tr();\n\t} catch (t) {\n\t\tn.push(e(t));\n\t}\n\treturn n;\n}, n = (e, n) => {\n\tlet r = t(e);\n\tif (r.length === 1) throw r[0];\n\tif (r.length > 0) throw AggregateError(r, n);\n}, r = (t, n, r) => {\n\tthrow n.length === 0 ? t : AggregateError([e(t), ...n], r, { cause: e(t) });\n};\n//#endregion\nexport { t as collectErrors, e as ensureError, r as rethrowWith, n as runAll };\n\n//# sourceMappingURL=_error-utils.js.map","//#region src/_dev.ts\nvar e = !globalThis.__RIPPLE_PROD__;\nfunction t(t) {\n\te && console.warn(`[@vielzeug/ripple] ${t}`);\n}\n//#endregion\nexport { t as warn };\n\n//# sourceMappingURL=_dev.js.map","import { runAll as e } from \"./_error-utils.js\";\nimport { RippleInfiniteLoopError as t } from \"./errors.js\";\nimport { warn as n } from \"./_dev.js\";\nimport { getSchedulingState as r, hasContextHook as i } from \"./tracking.js\";\nvar a = !1, o = 0, s = [], c = (e) => e.activeDirty === \"a\" ? e.dirtyWithEffectSubsA : e.dirtyWithEffectSubsB, l = (e, t) => {\n\tlet n = ++o;\n\tfor (let n of t.effectSubs()) e.pendingSubscribers.add(n);\n\tfor (let e of t.computedSubs()) s.push(e);\n\ttry {\n\t\tfor (; s.length > 0;) {\n\t\t\tlet t = s.pop();\n\t\t\tif (t.lastPropEpoch_ !== n && (t.lastPropEpoch_ = n, t.markDirty())) {\n\t\t\t\tt.effectSubs().size > 0 && c(e).add(t);\n\t\t\t\tfor (let e of t.computedSubs()) s.push(e);\n\t\t\t}\n\t\t}\n\t} finally {\n\t\ts.length = 0;\n\t}\n}, u = (e) => {\n\tfor (; c(e).size > 0;) {\n\t\tlet t = c(e);\n\t\te.activeDirty = e.activeDirty === \"a\" ? \"b\" : \"a\", c(e).clear();\n\t\tfor (let n of t) if (n.hasSubscribers() && n.refreshIfDirty()) {\n\t\t\tfor (let t of n.effectSubs()) e.pendingSubscribers.add(t);\n\t\t\tfor (let t of n.computedSubs()) t.markDirty() && t.effectSubs().size > 0 && c(e).add(t);\n\t\t}\n\t\tt.clear();\n\t}\n}, d = (n) => {\n\tlet r = 0;\n\tfor (; n.pendingSubscribers.size > 0 || c(n).size > 0;) {\n\t\tif (++r > 100) throw new t(\"infinite flush loop (> 100 iterations)\");\n\t\tif (c(n).size > 0 && u(n), n.pendingSubscribers.size === 0) continue;\n\t\tlet i = [...n.pendingSubscribers];\n\t\tn.pendingSubscribers.clear(), e(i, \"subscriber errors\");\n\t}\n}, f = globalThis.process?.versions != null, p = (e) => {\n\tif (!e.hasSubscribers()) return;\n\t!a && f && !i() && (a = !0, n(\"Signal updated in a Node.js-like environment. The module-level flush queue is shared across concurrent requests — use per-request worker isolation or the @vielzeug/ripple/ssr sub-path for request-isolated scheduling.\"));\n\tlet t = r();\n\tl(t, e), t.batchDepth === 0 && d(t);\n}, m = (e) => {\n\tlet t = r();\n\tt.batchDepth++;\n\tlet n;\n\ttry {\n\t\tn = e();\n\t} catch (e) {\n\t\tthrow t.batchDepth--, t.batchDepth === 0 && (t.pendingSubscribers.clear(), t.dirtyWithEffectSubsA.clear(), t.dirtyWithEffectSubsB.clear()), e;\n\t}\n\treturn t.batchDepth--, t.batchDepth === 0 && d(t), n;\n};\n//#endregion\nexport { m as batch, p as notifyNodeChange };\n\n//# sourceMappingURL=scheduling.js.map","//#region src/subscription.ts\nvar e = class {\n\tfn_;\n\tdisposed_ = !1;\n\tconstructor(e) {\n\t\tthis.fn_ = e;\n\t}\n\tget disposed() {\n\t\treturn this.disposed_;\n\t}\n\tdispose() {\n\t\tif (this.disposed_) return;\n\t\tthis.disposed_ = !0;\n\t\tlet e = this.fn_;\n\t\tthis.fn_ = null, e();\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n}, t = class {\n\tawaitDone_;\n\tgetCurrentRun_;\n\tsyncStop_;\n\tasyncDisposePromise_ = null;\n\tconstructor(e, t, n) {\n\t\tthis.awaitDone_ = t, this.getCurrentRun_ = n, this.syncStop_ = e;\n\t}\n\tget disposed() {\n\t\treturn this.syncStop_.disposed;\n\t}\n\tdispose() {\n\t\tthis.syncStop_.dispose();\n\t}\n\trun() {\n\t\treturn this.getCurrentRun_() ?? Promise.resolve();\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n\t[Symbol.asyncDispose]() {\n\t\treturn this.asyncDisposePromise_ === null ? (this.dispose(), this.asyncDisposePromise_ = this.awaitDone_(), this.asyncDisposePromise_) : this.asyncDisposePromise_;\n\t}\n};\n//#endregion\nexport { t as AsyncSubscriptionImpl, e as SubscriptionImpl };\n\n//# sourceMappingURL=subscription.js.map","//#region src/symbols.ts\nvar e = Symbol(\"ripple.is-signal\"), t = Symbol(\"ripple.is-computed\"), n = Symbol(\"ripple.is-store\"), r = Symbol(\"ripple.uninitialized\");\n//#endregion\nexport { t as IS_COMPUTED, e as IS_SIGNAL, n as IS_STORE, r as UNINITIALIZED };\n\n//# sourceMappingURL=symbols.js.map","import { IS_COMPUTED as e, IS_SIGNAL as t } from \"./symbols.js\";\n//#region src/reactive-base.ts\nvar n = new FinalizationRegistry(({ key: e, map: t }) => {\n\tt.delete(e);\n}), r = class {\n\tversion = 0;\n\tname;\n\t[t] = !0;\n\tcomputedSubs_ = /* @__PURE__ */ new Map();\n\teffectSubs_ = /* @__PURE__ */ new Set();\n\tconstructor(e) {\n\t\tthis.name = e;\n\t}\n\taddComputedSub(e) {\n\t\tlet t = new WeakRef(e);\n\t\tthis.computedSubs_.set(e, t), n.register(e, {\n\t\t\tkey: e,\n\t\t\tmap: this.computedSubs_\n\t\t}, t);\n\t}\n\tremoveComputedSub(e) {\n\t\tlet t = this.computedSubs_.get(e);\n\t\tt !== void 0 && (this.computedSubs_.delete(e), n.unregister(t));\n\t}\n\taddEffectSub(e) {\n\t\tthis.effectSubs_.add(e);\n\t}\n\tremoveEffectSub(e) {\n\t\tthis.effectSubs_.delete(e);\n\t}\n\tclearSubscribers() {\n\t\tfor (let e of this.computedSubs_.values()) n.unregister(e);\n\t\tthis.computedSubs_.clear(), this.effectSubs_.clear();\n\t}\n\thasSubscribers() {\n\t\tif (this.effectSubs_.size > 0) return !0;\n\t\tfor (let e of this.computedSubs_.values()) if (e.deref() !== void 0) return !0;\n\t\treturn !1;\n\t}\n\t*computedSubs() {\n\t\tfor (let [e, t] of this.computedSubs_) {\n\t\t\tlet r = t.deref();\n\t\t\tr === void 0 ? (this.computedSubs_.delete(e), n.unregister(t)) : yield r;\n\t\t}\n\t}\n\teffectSubs() {\n\t\treturn this.effectSubs_;\n\t}\n}, i = class extends r {\n\t[e] = !0;\n\tlastPropEpoch_ = 0;\n};\n//#endregion\nexport { i as ComputedBase, r as ReactiveBase };\n\n//# sourceMappingURL=reactive-base.js.map","import { getDevToolsHook as e } from \"./devtools-hook.js\";\nimport { ensureError as t } from \"./_error-utils.js\";\nimport { RippleComputedCycleError as n } from \"./errors.js\";\nimport { autoRegisterDisposal as r, getRevision as i, trackSource as a, withTracking as o } from \"./tracking.js\";\nimport { SubscriptionImpl as s } from \"./subscription.js\";\nimport { UNINITIALIZED as c } from \"./symbols.js\";\nimport { ComputedBase as l } from \"./reactive-base.js\";\n//#region src/computed.ts\nvar u = class extends l {\n\tvalue_;\n\tdirty_;\n\tcomputing_;\n\tdisposed_;\n\tdeps_;\n\tcompute_;\n\tequals_;\n\tmaxRevision_;\n\tconstructor(e, t) {\n\t\tlet { equals: n, name: r } = t ?? {};\n\t\tsuper(r), this.value_ = c, this.dirty_ = !0, this.computing_ = !1, this.disposed_ = !1, this.deps_ = [], this.maxRevision_ = -1, this.compute_ = e, this.equals_ = n === void 0 ? Object.is : (e, t) => n(e, t);\n\t}\n\tmarkDirty() {\n\t\treturn this.disposed_ || this.dirty_ ? !1 : (this.dirty_ = !0, !0);\n\t}\n\trefreshIfDirty() {\n\t\tif (!this.dirty_) return !1;\n\t\tif (i() <= this.maxRevision_) return this.dirty_ = !1, !1;\n\t\tif (this.deps_.length > 0) {\n\t\t\tlet e = !0;\n\t\t\tfor (let t of this.deps_) {\n\t\t\t\tlet n = t.source;\n\t\t\t\tif (\"refreshIfDirty\" in n && n.refreshIfDirty(), n.version !== t.version) {\n\t\t\t\t\te = !1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (e) return this.dirty_ = !1, this.maxRevision_ = i(), !1;\n\t\t}\n\t\treturn this.recompute();\n\t}\n\trunCompute(e) {\n\t\ttry {\n\t\t\treturn o({\n\t\t\t\tcomputed: this,\n\t\t\t\tdepCollector: e,\n\t\t\t\tkind: \"computed\"\n\t\t\t}, this.compute_);\n\t\t} catch (e) {\n\t\t\tthrow t(e);\n\t\t}\n\t}\n\trecompute() {\n\t\tif (this.computing_) throw new n(`computed cycle detected${this.name ? ` \"${this.name}\"` : \"\"}`);\n\t\tthis.computing_ = !0;\n\t\ttry {\n\t\t\tlet t = [];\n\t\t\te()?.compute?.({ name: this.name });\n\t\t\tlet n = this.runCompute(t);\n\t\t\treturn this.dirty_ = !1, this.maxRevision_ = i(), this.updateDeps(t), this.value_ === c || !this.equals_(this.value_, n) ? (this.value_ = n, this.version++, !0) : !1;\n\t\t} finally {\n\t\t\tthis.computing_ = !1;\n\t\t}\n\t}\n\tupdateDeps(e) {\n\t\tlet t = this.deps_;\n\t\tif (t.length === e.length && t.every((t, n) => t.source === e[n].source)) {\n\t\t\tfor (let n = 0; n < e.length; n++) t[n].version = e[n].version;\n\t\t\treturn;\n\t\t}\n\t\tlet n = new Set(t.map((e) => e.source)), r = new Set(e.map((e) => e.source));\n\t\tfor (let e of t) r.has(e.source) || e.source.removeComputedSub(this);\n\t\tfor (let t of e) n.has(t.source) || t.source.addComputedSub(this);\n\t\tthis.deps_ = e;\n\t}\n\tget value() {\n\t\treturn this.disposed_ ? this.value_ === c ? void 0 : this.value_ : (this.refreshIfDirty(), a(this), this.value_);\n\t}\n\tpeek() {\n\t\treturn this.disposed_ ? this.value_ === c ? void 0 : this.value_ : (this.refreshIfDirty(), this.value_);\n\t}\n\tsubscribe = (e) => {\n\t\tif (this.disposed_) {\n\t\t\tlet e = new s(() => {});\n\t\t\treturn e.dispose(), e;\n\t\t}\n\t\treturn this.refreshIfDirty(), this.addEffectSub(e), new s(() => {\n\t\t\tthis.removeEffectSub(e);\n\t\t});\n\t};\n\tget disposed() {\n\t\treturn this.disposed_;\n\t}\n\tdispose() {\n\t\tif (!this.disposed_) {\n\t\t\tthis.disposed_ = !0;\n\t\t\tfor (let e of this.deps_) e.source.removeComputedSub(this);\n\t\t\tthis.deps_ = [], this.clearSubscribers(), e()?.dispose?.({\n\t\t\t\tkind: \"computed\",\n\t\t\t\tname: this.name\n\t\t\t});\n\t\t}\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n}, d = (e, t) => {\n\tlet n = new u(e, t);\n\treturn r(() => n.dispose()), n;\n};\n//#endregion\nexport { u as ComputedImpl, d as computed };\n\n//# sourceMappingURL=computed.js.map","import { getDevToolsHook as e } from \"./devtools-hook.js\";\nimport { tickRevision as t, trackSource as n } from \"./tracking.js\";\nimport { notifyNodeChange as r } from \"./scheduling.js\";\nimport { SubscriptionImpl as i } from \"./subscription.js\";\nimport { ReactiveBase as a } from \"./reactive-base.js\";\n//#region src/signal.ts\nvar o = class extends a {\n\tvalue_;\n\tequals_;\n\tdisposed_;\n\tconstructor(e, t, n) {\n\t\tsuper(n), this.value_ = e, this.equals_ = t ?? Object.is, this.disposed_ = !1;\n\t}\n\tget value() {\n\t\treturn this.disposed_ || n(this), this.value_;\n\t}\n\tset value(n) {\n\t\tif (this.disposed_ || this.equals_(this.value_, n)) return;\n\t\tlet i = this.value_;\n\t\tthis.value_ = n, this.version = t(), e()?.write?.({\n\t\t\tname: this.name,\n\t\t\tnewValue: n,\n\t\t\toldValue: i\n\t\t}), r(this);\n\t}\n\tpeek() {\n\t\treturn this.value_;\n\t}\n\tsubscribe = (e) => {\n\t\tif (this.disposed_) {\n\t\t\tlet e = new i(() => {});\n\t\t\treturn e.dispose(), e;\n\t\t}\n\t\treturn this.addEffectSub(e), new i(() => {\n\t\t\tthis.removeEffectSub(e);\n\t\t});\n\t};\n\tget disposed() {\n\t\treturn this.disposed_;\n\t}\n\tdispose() {\n\t\tthis.disposed_ || (this.disposed_ = !0, this.clearSubscribers(), e()?.dispose?.({\n\t\t\tkind: \"signal\",\n\t\t\tname: this.name\n\t\t}));\n\t}\n\t[Symbol.dispose]() {\n\t\tthis.dispose();\n\t}\n}, s = (e, t) => new o(e, t?.equals, t?.name);\n//#endregion\nexport { o as SignalImpl, s as signal };\n\n//# sourceMappingURL=signal.js.map","const isDev = !(globalThis as { __LEDGER_PROD__?: boolean }).__LEDGER_PROD__;\n\n/** @internal @security Messages may include user data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/ledger] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n","import { computed, signal } from '@vielzeug/ripple';\n\nimport type { Command, CommandMeta, Ledger, LedgerCallOptions, LedgerOptions } from './types';\n\nimport { warn } from './_dev';\nimport { LedgerDisposedError, LedgerExecutionError, LedgerRollbackError } from './errors';\n\nfunction toMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\ntype StackEntry<TData = unknown> = {\n execute: (signal?: AbortSignal) => Promise<void>;\n meta: CommandMeta<TData>;\n rollback?: (signal?: AbortSignal) => Promise<void>;\n};\n\nfunction entryFromCommand<TData>(command: Command<TData>): StackEntry<TData> {\n const { rollback } = command;\n\n return {\n execute: async (signal) => command.execute(signal),\n meta: { data: command.data, label: command.label },\n rollback: rollback != null ? async (signal) => rollback(signal) : undefined,\n };\n}\n\n/**\n * Creates an async undo/redo command history.\n *\n * Each command is `{ execute, rollback? }`. `rollback` is optional — commands\n * without one are still tracked in history but undo skips the reversal step.\n * Operations are serialised — concurrent calls queue behind each other.\n * All state signals are Ripple `Computed` values for zero-glue UI binding.\n *\n * `execute`/`rollback` receive an `AbortSignal` — merged from the ledger's own\n * `disposalSignal` and any `signal` passed to `do()`/`undo()`/`redo()` — so long-running\n * commands can observe cancellation or disposal.\n *\n * @example\n * const ledger = createLedger({ maxHistory: 50 });\n * await ledger.do({ execute: () => { item.name = next; }, rollback: () => { item.name = prev; } });\n * await ledger.undo();\n * await ledger.redo();\n * using ledger = createLedger();\n */\nexport function createLedger<TData = unknown>(options: LedgerOptions<TData> = {}): Ledger<TData> {\n const { maxHistory = 100, onRollbackError } = options;\n\n if (maxHistory < 1) warn('maxHistory must be >= 1; history tracking is disabled for this ledger.');\n\n const undoStack = signal<StackEntry<TData>[]>([], { name: 'ledger:undoStack' });\n const redoStack = signal<StackEntry<TData>[]>([], { name: 'ledger:redoStack' });\n const pending = signal(0, { name: 'ledger:pending' });\n const processing = signal(false, { name: 'ledger:processing' });\n\n const canUndo = computed(() => undoStack.value.length > 0, { name: 'ledger:canUndo' });\n const canRedo = computed(() => redoStack.value.length > 0, { name: 'ledger:canRedo' });\n const historySize = computed(() => undoStack.value.length, { name: 'ledger:historySize' });\n const isProcessing = computed(() => processing.value, { name: 'ledger:isProcessing' });\n const pendingCount = computed(() => pending.value, { name: 'ledger:pendingCount' });\n const historySnapshot = computed(\n (): readonly CommandMeta<TData>[] => [...undoStack.value].reverse().map((e) => e.meta),\n { name: 'ledger:historySnapshot' },\n );\n\n const disposables = [\n undoStack,\n redoStack,\n pending,\n processing,\n canUndo,\n canRedo,\n historySize,\n isProcessing,\n pendingCount,\n historySnapshot,\n ];\n\n let isDisposed = false;\n let queue = Promise.resolve();\n\n const ac = new AbortController();\n\n function operationSignal(external?: AbortSignal): AbortSignal {\n return external ? AbortSignal.any([external, ac.signal]) : ac.signal;\n }\n\n function enqueue(method: string, task: () => Promise<void>): Promise<void> {\n if (isDisposed) return Promise.reject(new LedgerDisposedError(`Cannot call ${method}() on a disposed ledger.`));\n\n pending.value++;\n\n const current = queue.then(task).finally(() => {\n if (!isDisposed) pending.value--;\n });\n\n queue = current.catch(() => {});\n\n return current;\n }\n\n async function withProcessing(fn: () => Promise<void>): Promise<void> {\n processing.value = true;\n\n try {\n await fn();\n } finally {\n if (!isDisposed) processing.value = false;\n }\n }\n\n async function runDo(entry: StackEntry<TData>, signal: AbortSignal): Promise<void> {\n await withProcessing(async () => {\n try {\n await entry.execute(signal);\n } catch (err) {\n throw new LedgerExecutionError(toMessage(err), { cause: err });\n }\n\n if (isDisposed) return;\n\n const next = [...undoStack.value, entry];\n\n if (next.length > maxHistory) next.shift();\n\n undoStack.value = next;\n redoStack.value = [];\n });\n }\n\n async function runUndo(signal: AbortSignal): Promise<void> {\n const stack = undoStack.value;\n\n if (stack.length === 0) return;\n\n const entry = stack[stack.length - 1];\n\n await withProcessing(async () => {\n if (entry.rollback) {\n try {\n await entry.rollback(signal);\n } catch (err) {\n warn(`rollback() threw for \"${entry.meta.label ?? '(unlabelled)'}\". Stack position unchanged.`);\n onRollbackError?.(new LedgerRollbackError(toMessage(err), { cause: err }), entry.meta);\n\n return;\n }\n }\n\n if (isDisposed) return;\n\n undoStack.value = stack.slice(0, -1);\n redoStack.value = [...redoStack.value, entry];\n });\n }\n\n async function runRedo(signal: AbortSignal): Promise<void> {\n const stack = redoStack.value;\n\n if (stack.length === 0) return;\n\n const entry = stack[stack.length - 1];\n\n await withProcessing(async () => {\n try {\n await entry.execute(signal);\n } catch (err) {\n throw new LedgerExecutionError(toMessage(err), { cause: err });\n }\n\n if (isDisposed) return;\n\n redoStack.value = stack.slice(0, -1);\n undoStack.value = [...undoStack.value, entry];\n });\n }\n\n function clear(): Promise<void> {\n return enqueue('clear', async () => {\n if (isDisposed) return;\n\n undoStack.value = [];\n redoStack.value = [];\n });\n }\n\n function dispose(): void {\n isDisposed = true;\n ac.abort();\n\n undoStack.value = [];\n redoStack.value = [];\n\n for (const d of disposables) d.dispose();\n }\n\n return {\n canRedo,\n canUndo,\n\n clear,\n\n get disposalSignal(): AbortSignal {\n return ac.signal;\n },\n dispose,\n get disposed(): boolean {\n return isDisposed;\n },\n\n do(command: Command<TData>, callOptions?: LedgerCallOptions): Promise<void> {\n return enqueue('do', () => runDo(entryFromCommand<TData>(command), operationSignal(callOptions?.signal)));\n },\n\n historySize,\n historySnapshot,\n isProcessing,\n pendingCount,\n\n redo(callOptions?: LedgerCallOptions): Promise<void> {\n return enqueue('redo', () => runRedo(operationSignal(callOptions?.signal)));\n },\n\n [Symbol.dispose](): void {\n dispose();\n },\n\n undo(callOptions?: LedgerCallOptions): Promise<void> {\n return enqueue('undo', () => runUndo(operationSignal(callOptions?.signal)));\n },\n };\n}\n"],"mappings":"AAeA,SAAgB,EAAyB,EAA4B,EAAgC,CAGnG,MAAO,CACL,QAAS,KAAO,IAAW,CACzB,IAAM,EAAyB,CAAC,EAEhC,GAAI,CACF,IAAK,IAAM,KAAK,EACd,MAAM,EAAE,QAAQ,CAAM,EACtB,EAAK,KAAK,CAAC,CAEf,OAAS,EAAK,CACZ,IAAK,IAAM,IAAK,CAAC,GAAG,CAAI,CAAC,CAAC,QAAQ,EAChC,GAAI,CACF,MAAM,EAAE,WAAW,CAAM,CAC3B,MAAQ,CAER,CAGF,MAAM,CACR,CACF,EACA,QACA,SAxBqB,EAAS,KAAM,GAAM,EAAE,UAAY,IAwB9C,EACN,KAAO,IAAW,CAChB,IAAI,EACA,EAAW,GAEf,IAAK,IAAM,IAAK,CAAC,GAAG,CAAQ,CAAC,CAAC,QAAQ,EACpC,GAAI,CACF,MAAM,EAAE,WAAW,CAAM,CAC3B,OAAS,EAAK,CACZ,AAEE,KADA,EAAa,EACF,GAEf,CAGF,GAAI,EAAU,MAAM,CACtB,EACA,IAAA,EACN,CACF,CC3DA,IAAa,EAAb,MAAa,UAAoB,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,IAAI,OAAO,KACvB,OAAO,eAAe,KAAM,IAAI,OAAO,SAAS,CAClD,CAEA,OAAO,GAAG,EAAkC,CAC1C,OAAO,aAAe,CACxB,CACF,EAGa,EAAb,cAAyC,CAAY,CAAC,EAGzC,EAAb,cAA0C,CAAY,CAAC,EAG1C,EAAb,cAAyC,CAAY,CAAC,ECnBlDA,EAAI,KAAMC,MAAUD,ECApBG,EAAI,MAAM,UAAU,KAAM,CAC7B,YAAY,EAAG,EAAG,CACjB,MAAM,EAAG,CAAC,EAAG,KAAK,KAAO,IAAI,OAAO,KAAM,OAAO,eAAe,KAAM,IAAI,OAAO,SAAS,CAC3F,CACA,OAAO,GAAG,EAAG,CACZ,OAAO,aAAa,CACrB,CACD,EAAGC,EAAI,cAAcD,CAAE,CAAC,EAAmDI,EAAI,cAAcJ,CAAE,CAAC,ECP5FO,EAAI,EAAGC,MAAU,EAAED,EAAGE,MAAUF,EAMhCI,EAAI,CACP,WAPiD,CACjD,YAAa,IACb,WAAY,EACZ,qBAAsC,IAAI,IAC1C,qBAAsC,IAAI,IAC1C,mBAAoC,IAAI,GACzC,EAEC,cAAe,KACf,SAAU,IACX,EAAGC,EAAI,KAAMC,MAAUD,IAAM,KAAOD,EAAIC,EAAE,IAAI,EAAGE,MAAUD,EAAE,CAAC,CAAC,WAAYE,MAAUH,IAAM,KAAMI,MAAUH,EAAE,CAAC,CAAC,SAAUI,GAAK,EAAG,IAAM,CACtI,GAAIL,IAAM,KAAM,CACf,IAAI,EAAIA,EAAE,IAAI,EACd,OAAOA,EAAE,IAAI,CACZ,GAAG,EACH,SAAU,CACX,EAAG,CAAC,CACL,CACA,IAAI,EAAID,EACR,EAAI,CACH,GAAGA,EACH,SAAU,CACX,EACA,GAAI,CACH,OAAO,EAAE,CACV,QAAU,CACT,EAAI,CACL,CACD,EAkBGQ,MAAUN,EAAE,CAAC,CAAC,cAAeO,EAAK,GAAM,CAC1C,IAAI,EAAIJ,EAAE,EACV,GAAG,OAAS,SAAW,EAAE,SAAS,KAAK,CAAC,EAAIG,EAAE,CAAC,EAAE,KAAK,CAAC,CACxD,EAS0B,EAAK,GAAM,CACpC,IAAI,EAAIH,EAAE,EACV,GAAI,IAAM,SACL,EAAE,iBAAiB,CAAC,EAAG,EAAE,OAAS,WAAY,EAAE,aAAa,KAAK,CACrE,OAAQ,EACR,QAAS,EAAE,OACZ,CAAC,OACI,GAAI,EAAE,OAAS,SAAU,CAC7B,IAAI,EAAI,EAAE,OACV,EAAE,aAAa,CAAC,EAAG,EAAE,cAAc,QAAU,EAAE,gBAAgB,CAAC,CAAC,EAAG,EAAE,KAAK,IAAI,EAAG,EAAE,OAAO,CAC5F,EAEF,ECtEIM,EAAK,GAAM,aAAa,MAAQ,EAAoB,MAAM,qBAAqB,OAAO,CAAC,GAAG,EAAGC,EAAK,GAAM,CAC3G,IAAI,EAAI,CAAC,EACT,IAAK,IAAI,KAAK,EAAG,GAAI,CACpB,EAAE,CACH,OAAS,EAAG,CACX,EAAE,KAAKD,EAAE,CAAC,CAAC,CACZ,CACA,OAAO,CACR,EAAGE,GAAK,EAAG,IAAM,CAChB,IAAI,EAAID,EAAE,CAAC,EACX,GAAI,EAAE,SAAW,EAAG,MAAM,EAAE,GAC5B,GAAI,EAAE,OAAS,EAAG,MAAM,eAAe,EAAG,CAAC,CAC5C,ECZIG,EAAI,CAAC,WAAW,gBACpB,SAASC,EAAE,EAAG,CACb,GAAK,QAAQ,KAAK,sBAAsB,GAAG,CAC5C,CCAA,IAAI,EAAI,CAAC,EAAGC,EAAI,EAAGC,EAAI,CAAC,EAAG,EAAK,GAAM,EAAE,cAAgB,IAAM,EAAE,qBAAuB,EAAE,qBAAsB,GAAK,EAAG,IAAM,CAC5H,IAAI,EAAI,EAAED,EACV,IAAK,IAAI,KAAK,EAAE,WAAW,EAAG,EAAE,mBAAmB,IAAI,CAAC,EACxD,IAAK,IAAI,KAAK,EAAE,aAAa,EAAG,EAAE,KAAK,CAAC,EACxC,GAAI,CACH,KAAOC,EAAE,OAAS,GAAI,CACrB,IAAI,EAAIA,EAAE,IAAI,EACd,GAAI,EAAE,iBAAmB,IAAM,EAAE,eAAiB,EAAG,EAAE,UAAU,GAAI,CACpE,EAAE,WAAW,CAAC,CAAC,KAAO,GAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EACrC,IAAK,IAAI,KAAK,EAAE,aAAa,EAAG,EAAE,KAAK,CAAC,CACzC,CACD,CACD,QAAU,CACT,EAAE,OAAS,CACZ,CACD,EAAGC,EAAK,GAAM,CACb,KAAO,EAAE,CAAC,CAAC,CAAC,KAAO,GAAI,CACtB,IAAI,EAAI,EAAE,CAAC,EACX,EAAE,YAAc,EAAE,cAAgB,IAAM,IAAM,IAAK,EAAE,CAAC,CAAC,CAAC,MAAM,EAC9D,IAAK,IAAI,KAAK,EAAG,GAAI,EAAE,eAAe,GAAK,EAAE,eAAe,EAAG,CAC9D,IAAK,IAAI,KAAK,EAAE,WAAW,EAAG,EAAE,mBAAmB,IAAI,CAAC,EACxD,IAAK,IAAI,KAAK,EAAE,aAAa,EAAG,EAAE,UAAU,GAAK,EAAE,WAAW,CAAC,CAAC,KAAO,GAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACvF,CACA,EAAE,MAAM,CACT,CACD,EAAGC,EAAK,GAAM,CACb,IAAI,EAAI,EACR,KAAO,EAAE,mBAAmB,KAAO,GAAK,EAAE,CAAC,CAAC,CAAC,KAAO,GAAI,CACvD,GAAI,EAAE,EAAI,IAAK,MAAM,IAAIC,EAAE,wCAAwC,EACnE,GAAI,EAAE,CAAC,CAAC,CAAC,KAAO,GAAKF,EAAE,CAAC,EAAG,EAAE,mBAAmB,OAAS,EAAG,SAC5D,IAAI,EAAI,CAAC,GAAG,EAAE,kBAAkB,EAChC,EAAE,mBAAmB,MAAM,EAAGG,EAAE,EAAG,mBAAmB,CACvD,CACD,EAAG,EAAI,WAAW,SAAS,UAAY,KAAM,EAAK,GAAM,CACvD,GAAI,CAAC,EAAE,eAAe,EAAG,OACzB,CAAC,GAAK,GAAK,CAACC,EAAE,IAAM,EAAI,CAAC,EAAGC,EAAE,0NAA0N,GACxP,IAAI,EAAIC,EAAE,EACV,EAAE,EAAG,CAAC,EAAG,EAAE,aAAe,GAAKL,EAAE,CAAC,CACnC,ECzCIM,EAAI,KAAM,CACb,IACA,UAAY,CAAC,EACb,YAAY,EAAG,CACd,KAAK,IAAM,CACZ,CACA,IAAI,UAAW,CACd,OAAO,KAAK,SACb,CACA,SAAU,CACT,GAAI,KAAK,UAAW,OACpB,KAAK,UAAY,CAAC,EAClB,IAAI,EAAI,KAAK,IACb,KAAK,IAAM,KAAM,EAAE,CACpB,CACA,CAAC,OAAO,UAAW,CAClB,KAAK,QAAQ,CACd,CACD,EClBI,EAAI,OAAO,kBAAkB,EAAG,EAAI,OAAO,oBAAoB,EAAkCG,EAAI,OAAO,sBAAsB,ECClI,EAAI,IAAI,sBAAsB,CAAE,IAAK,EAAG,IAAK,KAAQ,CACxD,EAAE,OAAO,CAAC,CACX,CAAC,EAAG,EAAI,KAAM,CACb,QAAU,EACV,KACA,CAACC,GAAK,CAAC,EACP,cAAgC,IAAI,IACpC,YAA8B,IAAI,IAClC,YAAY,EAAG,CACd,KAAK,KAAO,CACb,CACA,eAAe,EAAG,CACjB,IAAI,EAAI,IAAI,QAAQ,CAAC,EACrB,KAAK,cAAc,IAAI,EAAG,CAAC,EAAG,EAAE,SAAS,EAAG,CAC3C,IAAK,EACL,IAAK,KAAK,aACX,EAAG,CAAC,CACL,CACA,kBAAkB,EAAG,CACpB,IAAI,EAAI,KAAK,cAAc,IAAI,CAAC,EAChC,IAAM,IAAK,KAAM,KAAK,cAAc,OAAO,CAAC,EAAG,EAAE,WAAW,CAAC,EAC9D,CACA,aAAa,EAAG,CACf,KAAK,YAAY,IAAI,CAAC,CACvB,CACA,gBAAgB,EAAG,CAClB,KAAK,YAAY,OAAO,CAAC,CAC1B,CACA,kBAAmB,CAClB,IAAK,IAAI,KAAK,KAAK,cAAc,OAAO,EAAG,EAAE,WAAW,CAAC,EACzD,KAAK,cAAc,MAAM,EAAG,KAAK,YAAY,MAAM,CACpD,CACA,gBAAiB,CAChB,GAAI,KAAK,YAAY,KAAO,EAAG,MAAO,CAAC,EACvC,IAAK,IAAI,KAAK,KAAK,cAAc,OAAO,EAAG,GAAI,EAAE,MAAM,IAAM,IAAK,GAAG,MAAO,CAAC,EAC7E,MAAO,CAAC,CACT,CACA,CAAC,cAAe,CACf,IAAK,GAAI,CAAC,EAAG,KAAM,KAAK,cAAe,CACtC,IAAI,EAAI,EAAE,MAAM,EAChB,IAAM,IAAK,IAAK,KAAK,cAAc,OAAO,CAAC,EAAG,EAAE,WAAW,CAAC,GAAK,MAAM,CACxE,CACD,CACA,YAAa,CACZ,OAAO,KAAK,WACb,CACD,EAAG,EAAI,cAAc,CAAE,CACtB,CAACC,GAAK,CAAC,EACP,eAAiB,CAClB,EC3CI,EAAI,cAAcC,CAAE,CACvB,OACA,OACA,WACA,UACA,MACA,SACA,QACA,aACA,YAAY,EAAG,EAAG,CACjB,GAAI,CAAE,OAAQ,EAAG,KAAM,GAAM,GAAK,CAAC,EACnC,MAAM,CAAC,EAAG,KAAK,OAASC,EAAG,KAAK,OAAS,CAAC,EAAG,KAAK,WAAa,CAAC,EAAG,KAAK,UAAY,CAAC,EAAG,KAAK,MAAQ,CAAC,EAAG,KAAK,aAAe,GAAI,KAAK,SAAW,EAAG,KAAK,QAAU,IAAM,IAAK,GAAI,OAAO,IAAM,EAAG,IAAM,EAAE,EAAG,CAAC,CAC/M,CACA,WAAY,CACX,OAAO,KAAK,WAAa,KAAK,OAAS,CAAC,GAAK,KAAK,OAAS,CAAC,EAAG,CAAC,EACjE,CACA,gBAAiB,CAChB,GAAI,CAAC,KAAK,OAAQ,MAAO,CAAC,EAC1B,GAAIC,EAAE,GAAK,KAAK,aAAc,MAAO,MAAK,OAAS,CAAC,EAAG,CAAC,EACxD,GAAI,KAAK,MAAM,OAAS,EAAG,CAC1B,IAAI,EAAI,CAAC,EACT,IAAK,IAAI,KAAK,KAAK,MAAO,CACzB,IAAI,EAAI,EAAE,OACV,GAAI,mBAAoB,GAAK,EAAE,eAAe,EAAG,EAAE,UAAY,EAAE,QAAS,CACzE,EAAI,CAAC,EACL,KACD,CACD,CACA,GAAI,EAAG,MAAO,MAAK,OAAS,CAAC,EAAG,KAAK,aAAeA,EAAE,EAAG,CAAC,CAC3D,CACA,OAAO,KAAK,UAAU,CACvB,CACA,WAAW,EAAG,CACb,GAAI,CACH,OAAOC,EAAE,CACR,SAAU,KACV,aAAc,EACd,KAAM,UACP,EAAG,KAAK,QAAQ,CACjB,OAAS,EAAG,CACX,MAAMC,EAAE,CAAC,CACV,CACD,CACA,WAAY,CACX,GAAI,KAAK,WAAY,MAAM,IAAIC,EAAE,0BAA0B,KAAK,KAAO,KAAK,KAAK,KAAK,GAAK,IAAI,EAC/F,KAAK,WAAa,CAAC,EACnB,GAAI,CACH,IAAI,EAAI,CAAC,EACT,EAAE,CAAC,EAAE,UAAU,CAAE,KAAM,KAAK,IAAK,CAAC,EAClC,IAAI,EAAI,KAAK,WAAW,CAAC,EACzB,MAAO,MAAK,OAAS,CAAC,EAAG,KAAK,aAAeH,EAAE,EAAG,KAAK,WAAW,CAAC,EAAG,KAAK,SAAWD,GAAK,CAAC,KAAK,QAAQ,KAAK,OAAQ,CAAC,GAAK,KAAK,OAAS,EAAG,KAAK,UAAW,CAAC,GAAK,CAAC,CACrK,QAAU,CACT,KAAK,WAAa,CAAC,CACpB,CACD,CACA,WAAW,EAAG,CACb,IAAI,EAAI,KAAK,MACb,GAAI,EAAE,SAAW,EAAE,QAAU,EAAE,OAAO,EAAG,IAAM,EAAE,SAAW,EAAE,EAAE,CAAC,MAAM,EAAG,CACzE,IAAK,IAAI,EAAI,EAAG,EAAI,EAAE,OAAQ,IAAK,EAAE,EAAE,CAAC,QAAU,EAAE,EAAE,CAAC,QACvD,MACD,CACA,IAAI,EAAI,IAAI,IAAI,EAAE,IAAK,GAAM,EAAE,MAAM,CAAC,EAAG,EAAI,IAAI,IAAI,EAAE,IAAK,GAAM,EAAE,MAAM,CAAC,EAC3E,IAAK,IAAI,KAAK,EAAG,EAAE,IAAI,EAAE,MAAM,GAAK,EAAE,OAAO,kBAAkB,IAAI,EACnE,IAAK,IAAI,KAAK,EAAG,EAAE,IAAI,EAAE,MAAM,GAAK,EAAE,OAAO,eAAe,IAAI,EAChE,KAAK,MAAQ,CACd,CACA,IAAI,OAAQ,CACX,OAAO,KAAK,UAAY,KAAK,SAAWA,EAAI,IAAK,GAAI,KAAK,QAAU,KAAK,eAAe,EAAGK,EAAE,IAAI,EAAG,KAAK,OAC1G,CACA,MAAO,CACN,OAAO,KAAK,UAAY,KAAK,SAAWL,EAAI,IAAK,GAAI,KAAK,QAAU,KAAK,eAAe,EAAG,KAAK,OACjG,CACA,UAAa,GAAM,CAClB,GAAI,KAAK,UAAW,CACnB,IAAI,EAAI,IAAIM,MAAQ,CAAC,CAAC,EACtB,OAAO,EAAE,QAAQ,EAAG,CACrB,CACA,OAAO,KAAK,eAAe,EAAG,KAAK,aAAa,CAAC,EAAG,IAAIA,MAAQ,CAC/D,KAAK,gBAAgB,CAAC,CACvB,CAAC,CACF,EACA,IAAI,UAAW,CACd,OAAO,KAAK,SACb,CACA,SAAU,CACT,GAAI,CAAC,KAAK,UAAW,CACpB,KAAK,UAAY,CAAC,EAClB,IAAK,IAAI,KAAK,KAAK,MAAO,EAAE,OAAO,kBAAkB,IAAI,EACzD,KAAK,MAAQ,CAAC,EAAG,KAAK,iBAAiB,EAAGC,EAAE,CAAC,EAAE,UAAU,CACxD,KAAM,WACN,KAAM,KAAK,IACZ,CAAC,CACF,CACD,CACA,CAAC,OAAO,UAAW,CAClB,KAAK,QAAQ,CACd,CACD,EAAG,GAAK,EAAG,IAAM,CAChB,IAAI,EAAI,IAAI,EAAE,EAAG,CAAC,EAClB,OAAOC,MAAQ,EAAE,QAAQ,CAAC,EAAG,CAC9B,ECtGI,EAAI,cAAcC,CAAE,CACvB,OACA,QACA,UACA,YAAY,EAAG,EAAG,EAAG,CACpB,MAAM,CAAC,EAAG,KAAK,OAAS,EAAG,KAAK,QAAU,GAAK,OAAO,GAAI,KAAK,UAAY,CAAC,CAC7E,CACA,IAAI,OAAQ,CACX,OAAO,KAAK,WAAaC,EAAE,IAAI,EAAG,KAAK,MACxC,CACA,IAAI,MAAM,EAAG,CACZ,GAAI,KAAK,WAAa,KAAK,QAAQ,KAAK,OAAQ,CAAC,EAAG,OACpD,IAAI,EAAI,KAAK,OACb,KAAK,OAAS,EAAG,KAAK,QAAUC,EAAE,EAAGC,EAAE,CAAC,EAAE,QAAQ,CACjD,KAAM,KAAK,KACX,SAAU,EACV,SAAU,CACX,CAAC,EAAGC,EAAE,IAAI,CACX,CACA,MAAO,CACN,OAAO,KAAK,MACb,CACA,UAAa,GAAM,CAClB,GAAI,KAAK,UAAW,CACnB,IAAI,EAAI,IAAIC,MAAQ,CAAC,CAAC,EACtB,OAAO,EAAE,QAAQ,EAAG,CACrB,CACA,OAAO,KAAK,aAAa,CAAC,EAAG,IAAIA,MAAQ,CACxC,KAAK,gBAAgB,CAAC,CACvB,CAAC,CACF,EACA,IAAI,UAAW,CACd,OAAO,KAAK,SACb,CACA,SAAU,CACT,KAAK,YAAc,KAAK,UAAY,CAAC,EAAG,KAAK,iBAAiB,EAAGF,EAAE,CAAC,EAAE,UAAU,CAC/E,KAAM,SACN,KAAM,KAAK,IACZ,CAAC,EACF,CACA,CAAC,OAAO,UAAW,CAClB,KAAK,QAAQ,CACd,CACD,EAAG,GAAK,EAAG,IAAM,IAAI,EAAE,EAAG,GAAG,OAAQ,GAAG,IAAI,ECjDtC,EAAQ,CAAE,WAA6C,gBAG7D,SAAgB,EAAK,EAAmB,CAClC,GAAO,QAAQ,KAAK,sBAAsB,GAAK,CACrD,CCEA,SAAS,EAAU,EAAsB,CACvC,OAAO,aAAe,MAAQ,EAAI,QAAU,OAAO,CAAG,CACxD,CAQA,SAAS,EAAwB,EAA4C,CAC3E,GAAM,CAAE,YAAa,EAErB,MAAO,CACL,QAAS,KAAO,IAAW,EAAQ,QAAQ,CAAM,EACjD,KAAM,CAAE,KAAM,EAAQ,KAAM,MAAO,EAAQ,KAAM,EACjD,SAAU,GAAY,KAA4C,IAAA,GAArC,KAAO,IAAW,EAAS,CAAM,CAChE,CACF,CAqBA,SAAgB,EAA8B,EAAgC,CAAC,EAAkB,CAC/F,GAAM,CAAE,aAAa,IAAK,mBAAoB,EAE1C,EAAa,GAAG,EAAK,wEAAwE,EAEjG,IAAM,EAAY,EAA4B,CAAC,EAAG,CAAE,KAAM,kBAAmB,CAAC,EACxE,EAAY,EAA4B,CAAC,EAAG,CAAE,KAAM,kBAAmB,CAAC,EACxE,EAAU,EAAO,EAAG,CAAE,KAAM,gBAAiB,CAAC,EAC9C,EAAa,EAAO,GAAO,CAAE,KAAM,mBAAoB,CAAC,EAExD,EAAU,MAAe,EAAU,MAAM,OAAS,EAAG,CAAE,KAAM,gBAAiB,CAAC,EAC/E,EAAU,MAAe,EAAU,MAAM,OAAS,EAAG,CAAE,KAAM,gBAAiB,CAAC,EAC/E,EAAc,MAAe,EAAU,MAAM,OAAQ,CAAE,KAAM,oBAAqB,CAAC,EACnF,EAAe,MAAe,EAAW,MAAO,CAAE,KAAM,qBAAsB,CAAC,EAC/E,EAAe,MAAe,EAAQ,MAAO,CAAE,KAAM,qBAAsB,CAAC,EAC5E,EAAkB,MACe,CAAC,GAAG,EAAU,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAK,GAAM,EAAE,IAAI,EACrF,CAAE,KAAM,wBAAyB,CACnC,EAEM,EAAc,CAClB,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,CACF,EAEI,EAAa,GACb,EAAQ,QAAQ,QAAQ,EAEtB,EAAK,IAAI,gBAEf,SAAS,EAAgB,EAAqC,CAC5D,OAAO,EAAW,YAAY,IAAI,CAAC,EAAU,EAAG,MAAM,CAAC,EAAI,EAAG,MAChE,CAEA,SAAS,EAAQ,EAAgB,EAA0C,CACzE,GAAI,EAAY,OAAO,QAAQ,OAAO,IAAI,EAAoB,eAAe,EAAO,yBAAyB,CAAC,EAE9G,EAAQ,QAER,IAAM,EAAU,EAAM,KAAK,CAAI,CAAC,CAAC,YAAc,CACxC,GAAY,EAAQ,OAC3B,CAAC,EAID,MAFA,GAAQ,EAAQ,UAAY,CAAC,CAAC,EAEvB,CACT,CAEA,eAAe,EAAe,EAAwC,CACpE,EAAW,MAAQ,GAEnB,GAAI,CACF,MAAM,EAAG,CACX,QAAU,CACH,IAAY,EAAW,MAAQ,GACtC,CACF,CAEA,eAAe,EAAM,EAA0B,EAAoC,CACjF,MAAM,EAAe,SAAY,CAC/B,GAAI,CACF,MAAM,EAAM,QAAQ,CAAM,CAC5B,OAAS,EAAK,CACZ,MAAM,IAAI,EAAqB,EAAU,CAAG,EAAG,CAAE,MAAO,CAAI,CAAC,CAC/D,CAEA,GAAI,EAAY,OAEhB,IAAM,EAAO,CAAC,GAAG,EAAU,MAAO,CAAK,EAEnC,EAAK,OAAS,GAAY,EAAK,MAAM,EAEzC,EAAU,MAAQ,EAClB,EAAU,MAAQ,CAAC,CACrB,CAAC,CACH,CAEA,eAAe,EAAQ,EAAoC,CACzD,IAAM,EAAQ,EAAU,MAExB,GAAI,EAAM,SAAW,EAAG,OAExB,IAAM,EAAQ,EAAM,EAAM,OAAS,GAEnC,MAAM,EAAe,SAAY,CAC/B,GAAI,EAAM,SACR,GAAI,CACF,MAAM,EAAM,SAAS,CAAM,CAC7B,OAAS,EAAK,CACZ,EAAK,yBAAyB,EAAM,KAAK,OAAS,eAAe,6BAA6B,EAC9F,IAAkB,IAAI,EAAoB,EAAU,CAAG,EAAG,CAAE,MAAO,CAAI,CAAC,EAAG,EAAM,IAAI,EAErF,MACF,CAGE,IAEJ,EAAU,MAAQ,EAAM,MAAM,EAAG,EAAE,EACnC,EAAU,MAAQ,CAAC,GAAG,EAAU,MAAO,CAAK,EAC9C,CAAC,CACH,CAEA,eAAe,EAAQ,EAAoC,CACzD,IAAM,EAAQ,EAAU,MAExB,GAAI,EAAM,SAAW,EAAG,OAExB,IAAM,EAAQ,EAAM,EAAM,OAAS,GAEnC,MAAM,EAAe,SAAY,CAC/B,GAAI,CACF,MAAM,EAAM,QAAQ,CAAM,CAC5B,OAAS,EAAK,CACZ,MAAM,IAAI,EAAqB,EAAU,CAAG,EAAG,CAAE,MAAO,CAAI,CAAC,CAC/D,CAEI,IAEJ,EAAU,MAAQ,EAAM,MAAM,EAAG,EAAE,EACnC,EAAU,MAAQ,CAAC,GAAG,EAAU,MAAO,CAAK,EAC9C,CAAC,CACH,CAEA,SAAS,GAAuB,CAC9B,OAAO,EAAQ,QAAS,SAAY,CAC9B,IAEJ,EAAU,MAAQ,CAAC,EACnB,EAAU,MAAQ,CAAC,EACrB,CAAC,CACH,CAEA,SAAS,GAAgB,CACvB,EAAa,GACb,EAAG,MAAM,EAET,EAAU,MAAQ,CAAC,EACnB,EAAU,MAAQ,CAAC,EAEnB,IAAK,IAAM,KAAK,EAAa,EAAE,QAAQ,CACzC,CAEA,MAAO,CACL,UACA,UAEA,QAEA,IAAI,gBAA8B,CAChC,OAAO,EAAG,MACZ,EACA,UACA,IAAI,UAAoB,CACtB,OAAO,CACT,EAEA,GAAG,EAAyB,EAAgD,CAC1E,OAAO,EAAQ,SAAY,EAAM,EAAwB,CAAO,EAAG,EAAgB,GAAa,MAAM,CAAC,CAAC,CAC1G,EAEA,cACA,kBACA,eACA,eAEA,KAAK,EAAgD,CACnD,OAAO,EAAQ,WAAc,EAAQ,EAAgB,GAAa,MAAM,CAAC,CAAC,CAC5E,EAEA,CAAC,OAAO,UAAiB,CACvB,EAAQ,CACV,EAEA,KAAK,EAAgD,CACnD,OAAO,EAAQ,WAAc,EAAQ,EAAgB,GAAa,MAAM,CAAC,CAAC,CAC5E,CACF,CACF"}
@@ -0,0 +1,37 @@
1
+ import type { Computed } from '@vielzeug/ripple';
2
+ export interface Command<TData = unknown> {
3
+ data?: TData;
4
+ execute: (signal?: AbortSignal) => Promise<void> | void;
5
+ label?: string;
6
+ rollback?: (signal?: AbortSignal) => Promise<void> | void;
7
+ }
8
+ export interface CommandMeta<TData = unknown> {
9
+ data: TData | undefined;
10
+ label: string | undefined;
11
+ }
12
+ /** Options accepted by `do()`/`undo()`/`redo()`. */
13
+ export interface LedgerCallOptions {
14
+ /** Merged with the ledger's own `disposalSignal` and passed to `execute`/`rollback`. */
15
+ signal?: AbortSignal;
16
+ }
17
+ export interface LedgerOptions<TData = unknown> {
18
+ maxHistory?: number;
19
+ onRollbackError?: (err: unknown, meta: CommandMeta<TData>) => void;
20
+ }
21
+ export interface Ledger<TData = unknown> {
22
+ readonly canRedo: Computed<boolean>;
23
+ readonly canUndo: Computed<boolean>;
24
+ readonly historySize: Computed<number>;
25
+ readonly historySnapshot: Computed<readonly CommandMeta<TData>[]>;
26
+ readonly isProcessing: Computed<boolean>;
27
+ readonly pendingCount: Computed<number>;
28
+ clear(): Promise<void>;
29
+ readonly disposalSignal: AbortSignal;
30
+ dispose(): void;
31
+ readonly disposed: boolean;
32
+ do(command: Command<TData>, options?: LedgerCallOptions): Promise<void>;
33
+ redo(options?: LedgerCallOptions): Promise<void>;
34
+ undo(options?: LedgerCallOptions): Promise<void>;
35
+ [Symbol.dispose](): void;
36
+ }
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,OAAO,CAAC,KAAK,GAAG,OAAO;IACtC,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC3D;AAED,MAAM,WAAW,WAAW,CAAC,KAAK,GAAG,OAAO;IAC1C,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,oDAAoD;AACpD,MAAM,WAAW,iBAAiB;IAChC,wFAAwF;IACxF,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,OAAO;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;CACpE;AAED,MAAM,WAAW,MAAM,CAAC,KAAK,GAAG,OAAO;IACrC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,SAAS,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClE,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAExC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC;IACrC,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@vielzeug/ledger",
3
+ "version": "1.1.1",
4
+ "description": "Async undo/redo command history with Ripple signals for reactive canUndo/canRedo state",
5
+ "type": "module",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "main": "./dist/index.cjs",
10
+ "module": "./dist/index.js",
11
+ "types": "dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "source": "./src/index.ts",
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "require": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "scripts": {
21
+ "build": "vite build && pnpm run build:bundle && pnpm run build:types",
22
+ "build:bundle": "vite build --config vite.bundle.config.ts",
23
+ "build:types": "tsc -p tsconfig.declarations.json",
24
+ "fix": "eslint --fix src",
25
+ "lint": "eslint src",
26
+ "prepublishOnly": "pnpm run build",
27
+ "test": "vitest"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public",
31
+ "registry": "https://registry.npmjs.org/"
32
+ },
33
+ "dependencies": {
34
+ "@vielzeug/ripple": "workspace:*"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^26.1.0",
38
+ "typescript": "~6.0.3",
39
+ "vite": "^8.1.3",
40
+ "vitest": "^4.1.9"
41
+ }
42
+ }