Skip to content

API Overview

SymbolPurposeExecution modeCommon gotcha
createLedger()Create reversible async historySyncdispose() seals the owner
compose()Combine reversible commandsSyncEvery child must revert
LedgerHistory handleAsync methodsCatch operation failures
ReversibleCommandApply/revert state transitionSync or asyncIrreversible work is outside Ledger
LedgerCancelledErrorCancellation resultSyncDifferent from execution failure

Package Entry Point

ImportPurpose
@vielzeug/ledgerRoot entry for Ledger functions, errors, and public types.

Core Functions

createLedger()

ts
function createLedger<TMeta = undefined>(options?: LedgerOptions): Ledger<TMeta>;

Creates a serialized owner for reversible commands.

ParameterTypeDescription
optionsLedgerOptionsHistory-cap configuration.

Returns: Ledger<TMeta>.

ts
import { createLedger } from '@vielzeug/ledger';

let value = 'before';
const ledger = createLedger();

await ledger.do({
  apply: () => { value = 'after'; },
  revert: () => { value = 'before'; },
});

await ledger.undo();
ledger.dispose();

compose()

ts
function compose<TMeta = undefined>(
  commands: readonly ReversibleCommand<TMeta>[],
  label?: string,
): ReversibleCommand<TMeta>;

Snapshots reversible children and returns one reversible command.

ParameterTypeDescription
commandsreadonly ReversibleCommand<TMeta>[]Commands to apply in order and revert in reverse order.
labelstringOptional history label.

Returns: ReversibleCommand<TMeta>.

ts
import { compose } from '@vielzeug/ledger';

const move = compose([
  { apply: moveX, revert: restoreX },
  { apply: moveY, revert: restoreY },
], 'Move node');

If apply and compensation both fail, the resulting LedgerExecutionError.cause is an AggregateError containing every failure.

Ledger

ts
interface Ledger<TMeta = undefined> {
  clear(): Promise<void>;
  readonly disposalSignal: AbortSignal;
  dispose(): void;
  readonly disposed: boolean;
  do(command: ReversibleCommand<TMeta>, options?: LedgerCallOptions): Promise<void>;
  redo(options?: LedgerCallOptions): Promise<void>;
  readonly state: Readable<LedgerState<TMeta>>;
  undo(options?: LedgerCallOptions): Promise<void>;
  whenIdle(): Promise<void>;
  [Symbol.dispose](): void;
}
MemberReturnContract
do()Promise<void>Applies and records a command.
undo()Promise<void>Reverts latest undo entry.
redo()Promise<void>Reapplies latest redo entry.
clear()Promise<void>Clears retained undo and redo history.
whenIdle()Promise<void>Resolves when queued and running counts are zero.
dispose()voidSeals owner, aborts active contexts, rejects unstarted work.
stateReadable<LedgerState<TMeta>>Atomic lifecycle and history snapshot.

Types

CommandContext

ts
interface CommandContext {
  readonly signal: AbortSignal;
}

Context passed to apply and revert. Active work must observe signal cooperatively.

ReversibleCommand

ts
interface ReversibleCommand<TMeta = undefined> {
  readonly apply: (context: CommandContext) => Promise<void> | void;
  readonly label?: string;
  readonly meta?: TMeta;
  readonly revert: (context: CommandContext) => Promise<void> | void;
}

HistoryEntry

ts
interface HistoryEntry<TMeta = undefined> {
  readonly label: string | undefined;
  readonly meta: TMeta | undefined;
}

LedgerState

ts
interface LedgerState<TMeta = undefined> {
  readonly accepting: boolean;
  readonly queued: number;
  readonly redo: readonly HistoryEntry<TMeta>[];
  readonly running: number;
  readonly undo: readonly HistoryEntry<TMeta>[];
}

LedgerOptions

ts
interface LedgerOptions {
  maxHistory?: number;
}

maxHistory defaults to 100, accepts non-negative safe integers, and uses 0 for no retained history.

LedgerCallOptions

ts
interface LedgerCallOptions {
  signal?: AbortSignal;
}

An already-aborted signal rejects before user code starts. Active commands receive a merged signal.

Errors

ErrorTriggerNotable properties
LedgerCancelledErrorOperation cancels before start or cooperatively stopsMay carry original abort cause
LedgerDisposedErrorOperation submitted to sealed ledgerQueued work rejects without starting
LedgerExecutionErrorapply() failsOriginal failure in .cause
LedgerRollbackErrorrevert() failsEntry remains in undo history
LedgerErrorBase classinstanceof LedgerError narrows all Ledger errors