@directive-run/core 0.4.2 → 0.7.0

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.
@@ -680,8 +680,10 @@ interface CreateSystemOptionsNamed<Modules extends ModulesMap> {
680
680
  modules: Modules;
681
681
  /** Plugins to register */
682
682
  plugins?: Array<Plugin<ModuleSchema>>;
683
- /** Debug configuration */
684
- debug?: DebugConfig;
683
+ /** History configuration for snapshot-based state history */
684
+ history?: HistoryOption;
685
+ /** Trace: per-run reconciliation changelog */
686
+ trace?: TraceOption;
685
687
  /** Error boundary configuration */
686
688
  errorBoundary?: ErrorBoundaryConfig;
687
689
  /**
@@ -727,18 +729,20 @@ interface NamespacedSystem<Modules extends ModulesMap> {
727
729
  readonly _mode: "namespaced";
728
730
  /** Namespaced facts accessor: system.facts.auth.token */
729
731
  readonly facts: MutableNamespacedFacts<Modules>;
730
- /** Time-travel debugging API (if enabled) */
731
- readonly debug: TimeTravelAPI | null;
732
+ /** History API for undo/redo, rollback, audit trails (if enabled) */
733
+ readonly history: HistoryAPI | null;
732
734
  /** Namespaced derivations accessor: system.derive.auth.status */
733
- readonly derive: NamespacedDerivations<Modules>;
735
+ readonly derive: NamespacedDerivations<Modules> & DerivationsControl;
734
736
  /** Events accessor (union of all module events) */
735
737
  readonly events: NamespacedEventsAccessor<Modules>;
736
- /** Runtime control for constraints (disable/enable/isDisabled) */
738
+ /** Runtime control for constraints (disable/enable/isDisabled + dynamic CRUD) */
737
739
  readonly constraints: ConstraintsControl;
738
- /** Runtime control for effects (disable/enable/isEnabled) */
740
+ /** Runtime control for effects (disable/enable/isEnabled + dynamic CRUD) */
739
741
  readonly effects: EffectsControl;
740
- /** Per-run changelog entries (null if debug.runHistory is not enabled) */
741
- readonly runHistory: RunChangelogEntry[] | null;
742
+ /** Runtime control for resolvers (dynamic CRUD) */
743
+ readonly resolvers: ResolversControl;
744
+ /** Per-run trace entries (null if trace is not enabled) */
745
+ readonly trace: TraceEntry[] | null;
742
746
  /** Initialize facts and derivations without starting reconciliation. Safe for SSR. */
743
747
  initialize(): void;
744
748
  /** Start the system (initialize modules, begin reconciliation) */
@@ -786,8 +790,8 @@ interface NamespacedSystem<Modules extends ModulesMap> {
786
790
  * (resolver starts/completes, reconcile starts/ends).
787
791
  */
788
792
  onSettledChange(listener: () => void): () => void;
789
- /** Subscribe to time-travel state changes (snapshot taken, navigation). */
790
- onTimeTravelChange(listener: () => void): () => void;
793
+ /** Subscribe to history state changes (snapshot taken, navigation). */
794
+ onHistoryChange(listener: () => void): () => void;
791
795
  /**
792
796
  * Read a derivation value by namespaced key.
793
797
  * Accepts "namespace.key" format (e.g., "auth.status").
@@ -931,8 +935,10 @@ interface CreateSystemOptionsSingle<S extends ModuleSchema> {
931
935
  module: ModuleDef<S>;
932
936
  /** Plugins to register */
933
937
  plugins?: Array<Plugin<ModuleSchema>>;
934
- /** Debug configuration */
935
- debug?: DebugConfig;
938
+ /** History configuration for snapshot-based state history */
939
+ history?: HistoryOption;
940
+ /** Trace: per-run reconciliation changelog */
941
+ trace?: TraceOption;
936
942
  /** Error boundary configuration */
937
943
  errorBoundary?: ErrorBoundaryConfig;
938
944
  /** Tick interval for time-based systems (ms) */
@@ -954,18 +960,20 @@ interface SingleModuleSystem<S extends ModuleSchema> {
954
960
  readonly _mode: "single";
955
961
  /** Direct facts accessor: system.facts.count */
956
962
  readonly facts: Facts<S["facts"]>;
957
- /** Time-travel debugging API (if enabled) */
958
- readonly debug: TimeTravelAPI | null;
963
+ /** History API for undo/redo, rollback, audit trails (if enabled) */
964
+ readonly history: HistoryAPI | null;
959
965
  /** Direct derivations accessor: system.derive.doubled */
960
- readonly derive: InferDerivations<S>;
966
+ readonly derive: InferDerivations<S> & DerivationsControl<S>;
961
967
  /** Direct events accessor: system.events.increment() */
962
968
  readonly events: SingleModuleEvents<S>;
963
969
  /** Runtime control for constraints (disable/enable/isDisabled) */
964
- readonly constraints: ConstraintsControl;
970
+ readonly constraints: ConstraintsControl<S>;
965
971
  /** Runtime control for effects (disable/enable/isEnabled) */
966
- readonly effects: EffectsControl;
967
- /** Per-run changelog entries (null if debug.runHistory is not enabled) */
968
- readonly runHistory: RunChangelogEntry[] | null;
972
+ readonly effects: EffectsControl<S>;
973
+ /** Runtime control for resolvers (register/assign/unregister/call) */
974
+ readonly resolvers: ResolversControl<S>;
975
+ /** Per-run trace entries (null if trace is not enabled) */
976
+ readonly trace: TraceEntry[] | null;
969
977
  /** Initialize facts and derivations without starting reconciliation. Safe for SSR. */
970
978
  initialize(): void;
971
979
  /** Start the system (initialize modules, begin reconciliation) */
@@ -998,8 +1006,8 @@ interface SingleModuleSystem<S extends ModuleSchema> {
998
1006
  * (resolver starts/completes, reconcile starts/ends).
999
1007
  */
1000
1008
  onSettledChange(listener: () => void): () => void;
1001
- /** Subscribe to time-travel state changes (snapshot taken, navigation). */
1002
- onTimeTravelChange(listener: () => void): () => void;
1009
+ /** Subscribe to history state changes (snapshot taken, navigation). */
1010
+ onHistoryChange(listener: () => void): () => void;
1003
1011
  /**
1004
1012
  * Read a derivation value by key.
1005
1013
  * @example system.read("doubled")
@@ -1165,7 +1173,7 @@ type GetRequirementsSchema<M extends ModuleSchema> = M["requirements"] extends R
1165
1173
  * The derive accessor is typed from schema.derivations.
1166
1174
  * Supports both t.*() builders and type assertion {} as {} patterns.
1167
1175
  */
1168
- type TypedDerivationFn<M extends ModuleSchema, K extends keyof GetDerivationsSchema<M>> = (facts: Facts<M["facts"]>, derive: InferDerivations<M>) => InferSchemaType<GetDerivationsSchema<M>[K]>;
1176
+ type TypedDerivationFn<M extends ModuleSchema, K extends keyof GetDerivationsSchema<M>> = (facts: Facts<M["facts"]>, derived: InferDerivations<M>) => InferSchemaType<GetDerivationsSchema<M>[K]>;
1169
1177
  /**
1170
1178
  * Typed derivations definition using the module schema.
1171
1179
  * Each derivation key must match schema.derivations and return the declared type.
@@ -1286,7 +1294,7 @@ type CrossModuleEffectsDef<M extends ModuleSchema, Deps extends CrossModuleDeps>
1286
1294
  * - `facts.self.*` for own module's facts
1287
1295
  * - `facts.{dep}.*` for cross-module facts (read-only)
1288
1296
  */
1289
- type CrossModuleDerivationFn<M extends ModuleSchema, Deps extends CrossModuleDeps, K extends keyof GetDerivationsSchema<M>> = (facts: CrossModuleFactsWithSelf<M, Deps>, derive: InferDerivations<M>) => InferSchemaType<GetDerivationsSchema<M>[K]>;
1297
+ type CrossModuleDerivationFn<M extends ModuleSchema, Deps extends CrossModuleDeps, K extends keyof GetDerivationsSchema<M>> = (facts: CrossModuleFactsWithSelf<M, Deps>, derived: InferDerivations<M>) => InferSchemaType<GetDerivationsSchema<M>[K]>;
1290
1298
  /**
1291
1299
  * Cross-module derivations definition.
1292
1300
  */
@@ -1356,11 +1364,17 @@ interface ModuleDef<M extends ModuleSchema = ModuleSchema> {
1356
1364
  resolvers?: TypedResolversDef<M>;
1357
1365
  hooks?: ModuleHooks<M>;
1358
1366
  /**
1359
- * Events that create time-travel snapshots.
1360
- * If omitted, ALL events create snapshots (default).
1361
- * If provided, only listed events create snapshots for undo/redo.
1367
+ * History configuration for this module.
1368
+ * Controls which events create snapshots for undo/redo.
1362
1369
  */
1363
- snapshotEvents?: Array<keyof GetEventsSchema<M> & string>;
1370
+ history?: {
1371
+ /**
1372
+ * Events that create history snapshots.
1373
+ * If omitted, ALL events create snapshots (default).
1374
+ * If provided, only listed events create snapshots for undo/redo.
1375
+ */
1376
+ snapshotEvents?: Array<keyof GetEventsSchema<M> & string>;
1377
+ };
1364
1378
  /**
1365
1379
  * Cross-module dependencies (runtime marker).
1366
1380
  * When present, constraints/effects receive `facts.self.*` + `facts.{dep}.*`.
@@ -1401,19 +1415,24 @@ type ObservableKeys<M extends ModuleSchema> = FactKeys<M> | DerivationKeys<M>;
1401
1415
  * Events accessor from module schema.
1402
1416
  */
1403
1417
  type EventsAccessor<M extends ModuleSchema> = EventsAccessorFromSchema<M>;
1404
- /** Debug configuration */
1405
- interface DebugConfig {
1406
- timeTravel?: boolean;
1418
+ /** History configuration for snapshot-based state history (undo/redo, rollback, audit trails) */
1419
+ interface HistoryConfig {
1420
+ /** Maximum number of snapshots in the ring buffer (default 100) */
1407
1421
  maxSnapshots?: number;
1408
1422
  /** Only snapshot events from these modules. Omit to snapshot all modules. Multi-module only. */
1409
1423
  snapshotModules?: string[];
1410
- /** Enable per-run changelog (default false) */
1411
- runHistory?: boolean;
1412
- /** Ring buffer cap for run history (default 100) */
1424
+ }
1425
+ /** History option: boolean shorthand or full config (presence implies enabled) */
1426
+ type HistoryOption = boolean | HistoryConfig;
1427
+ /** Trace configuration for per-run reconciliation changelogs */
1428
+ interface TraceConfig {
1429
+ /** Ring buffer cap for trace entries (default 100) */
1413
1430
  maxRuns?: number;
1414
1431
  }
1415
- /** Time-travel API */
1416
- interface TimeTravelAPI {
1432
+ /** Trace option: boolean shorthand or full config (presence implies enabled) */
1433
+ type TraceOption = boolean | TraceConfig;
1434
+ /** History API for snapshot navigation, changesets, and export/import */
1435
+ interface HistoryAPI {
1417
1436
  readonly snapshots: Snapshot[];
1418
1437
  readonly currentIndex: number;
1419
1438
  readonly isPaused: boolean;
@@ -1434,19 +1453,17 @@ interface SnapshotMeta {
1434
1453
  timestamp: number;
1435
1454
  trigger: string;
1436
1455
  }
1437
- /** Reactive time-travel state for framework hooks */
1438
- interface TimeTravelState {
1439
- canUndo: boolean;
1440
- canRedo: boolean;
1441
- undo: () => void;
1442
- redo: () => void;
1456
+ /** Reactive history state for framework hooks */
1457
+ interface HistoryState {
1458
+ canGoBack: boolean;
1459
+ canGoForward: boolean;
1443
1460
  currentIndex: number;
1444
1461
  totalSnapshots: number;
1445
1462
  snapshots: SnapshotMeta[];
1446
1463
  getSnapshotFacts: (id: number) => Record<string, unknown> | null;
1447
1464
  goTo: (snapshotId: number) => void;
1448
- goBack: (steps: number) => void;
1449
- goForward: (steps: number) => void;
1465
+ goBack: (steps?: number) => void;
1466
+ goForward: (steps?: number) => void;
1450
1467
  replay: () => void;
1451
1468
  exportSession: () => string;
1452
1469
  importSession: (json: string) => void;
@@ -1456,8 +1473,8 @@ interface TimeTravelState {
1456
1473
  pause: () => void;
1457
1474
  resume: () => void;
1458
1475
  }
1459
- /** A structured record of one reconciliation run — from facts through resolvers and effects. */
1460
- interface RunChangelogEntry {
1476
+ /** A structured record of one reconciliation run — fact changes, derivation recomputes, constraints hit, resolvers, effects. */
1477
+ interface TraceEntry {
1461
1478
  /** Monotonic run ID */
1462
1479
  id: number;
1463
1480
  /** When the reconcile started */
@@ -1551,10 +1568,10 @@ interface SystemInspection {
1551
1568
  id: string;
1552
1569
  requirement: string;
1553
1570
  }>;
1554
- /** Whether debug.runHistory is enabled on this system */
1555
- runHistoryEnabled: boolean;
1556
- /** Per-run changelog entries (only present if debug.runHistory is enabled) */
1557
- runHistory?: RunChangelogEntry[];
1571
+ /** Whether trace is enabled on this system */
1572
+ traceEnabled: boolean;
1573
+ /** Per-run trace entries (only present if trace is enabled) */
1574
+ trace?: TraceEntry[];
1558
1575
  }
1559
1576
  /** Explanation of why a requirement exists */
1560
1577
  interface RequirementExplanation {
@@ -1628,32 +1645,210 @@ interface DistributableSnapshot<T = Record<string, unknown>> {
1628
1645
  * Provides full type inference for facts, derivations, events, and dispatch.
1629
1646
  */
1630
1647
  /** Runtime control for constraints */
1631
- interface ConstraintsControl {
1648
+ interface ConstraintsControl<M extends ModuleSchema = ModuleSchema> {
1632
1649
  /** Disable a constraint by ID — it will be excluded from evaluation */
1633
1650
  disable(id: string): void;
1634
1651
  /** Enable a previously disabled constraint — it will be re-evaluated on the next cycle */
1635
1652
  enable(id: string): void;
1636
1653
  /** Check if a constraint is currently disabled */
1637
1654
  isDisabled(id: string): boolean;
1655
+ /**
1656
+ * Register a new constraint at runtime.
1657
+ * @throws If a constraint with this ID already exists (use `assign` to override)
1658
+ * @remarks During reconciliation, the registration is deferred and applied after the current cycle completes.
1659
+ */
1660
+ register(id: string, def: DynamicConstraintDef<M>): void;
1661
+ /**
1662
+ * Override an existing constraint (static or dynamic).
1663
+ * Stores the original definition for potential inspection.
1664
+ * @throws If no constraint with this ID exists (use `register` to create)
1665
+ * @remarks During reconciliation, the assignment is deferred and applied after the current cycle completes.
1666
+ */
1667
+ assign(id: string, def: DynamicConstraintDef<M>): void;
1668
+ /**
1669
+ * Remove a dynamically registered constraint.
1670
+ * Static (module-defined) constraints cannot be unregistered — logs a dev warning and no-ops.
1671
+ * @remarks During reconciliation, the unregistration is deferred and applied after the current cycle completes.
1672
+ */
1673
+ unregister(id: string): void;
1674
+ /**
1675
+ * Invoke a constraint's `when()` predicate. If true, evaluates its `require()` and returns the requirements
1676
+ * (with optional props merged). The requirements are returned for inspection but NOT automatically dispatched
1677
+ * to the resolver system.
1678
+ * @throws If no constraint with this ID exists
1679
+ */
1680
+ call(id: string, props?: Record<string, unknown>): Promise<Record<string, unknown>[]>;
1681
+ /** Check if a constraint was dynamically registered (not from a module definition) */
1682
+ isDynamic(id: string): boolean;
1683
+ /** List all dynamically registered constraint IDs */
1684
+ listDynamic(): string[];
1638
1685
  }
1639
1686
  /** Runtime control for effects */
1640
- interface EffectsControl {
1687
+ interface EffectsControl<M extends ModuleSchema = ModuleSchema> {
1641
1688
  /** Disable an effect by ID — it will be skipped during reconciliation */
1642
1689
  disable(id: string): void;
1643
1690
  /** Enable a previously disabled effect */
1644
1691
  enable(id: string): void;
1645
1692
  /** Check if an effect is currently enabled */
1646
1693
  isEnabled(id: string): boolean;
1694
+ /**
1695
+ * Register a new effect at runtime.
1696
+ * @throws If an effect with this ID already exists (use `assign` to override)
1697
+ * @remarks During reconciliation, the registration is deferred and applied after the current cycle completes.
1698
+ */
1699
+ register(id: string, def: DynamicEffectDef<M>): void;
1700
+ /**
1701
+ * Override an existing effect (static or dynamic).
1702
+ * Runs cleanup of the old effect before replacing.
1703
+ * @throws If no effect with this ID exists (use `register` to create)
1704
+ * @remarks During reconciliation, the assignment is deferred and applied after the current cycle completes.
1705
+ */
1706
+ assign(id: string, def: DynamicEffectDef<M>): void;
1707
+ /**
1708
+ * Remove a dynamically registered effect.
1709
+ * Static (module-defined) effects cannot be unregistered — logs a dev warning and no-ops.
1710
+ * @remarks During reconciliation, the unregistration is deferred and applied after the current cycle completes.
1711
+ */
1712
+ unregister(id: string): void;
1713
+ /**
1714
+ * Execute an effect's `run()` function immediately.
1715
+ * @throws If no effect with this ID exists
1716
+ */
1717
+ call(id: string): Promise<void>;
1718
+ /** Check if an effect was dynamically registered (not from a module definition) */
1719
+ isDynamic(id: string): boolean;
1720
+ /** List all dynamically registered effect IDs */
1721
+ listDynamic(): string[];
1722
+ }
1723
+ /** Runtime control for derivations (dynamic registration + value access) */
1724
+ interface DerivationsControl<M extends ModuleSchema = ModuleSchema> {
1725
+ /**
1726
+ * Register a new derivation at runtime.
1727
+ * @throws If a derivation with this ID already exists (use `assign` to override)
1728
+ * @remarks During reconciliation, the registration is deferred and applied after the current cycle completes.
1729
+ */
1730
+ register(id: string, fn: (facts: Readonly<InferSchema<M["facts"]>>, derived: Readonly<InferDerivations<M>>) => unknown): void;
1731
+ /**
1732
+ * Override an existing derivation (static or dynamic).
1733
+ * @throws If no derivation with this ID exists (use `register` to create)
1734
+ * @remarks During reconciliation, the assignment is deferred and applied after the current cycle completes.
1735
+ */
1736
+ assign(id: string, fn: (facts: Readonly<InferSchema<M["facts"]>>, derived: Readonly<InferDerivations<M>>) => unknown): void;
1737
+ /**
1738
+ * Remove a dynamically registered derivation.
1739
+ * Static (module-defined) derivations cannot be unregistered — logs a dev warning and no-ops.
1740
+ * @remarks During reconciliation, the unregistration is deferred and applied after the current cycle completes.
1741
+ */
1742
+ unregister(id: string): void;
1743
+ /**
1744
+ * Recompute and return a derivation's current value.
1745
+ * Use the type parameter to specify the return type: `call<number>("id")`.
1746
+ * @throws If no derivation with this ID exists
1747
+ */
1748
+ call<T = unknown>(id: string): T;
1749
+ /** Check if a derivation was dynamically registered (not from a module definition) */
1750
+ isDynamic(id: string): boolean;
1751
+ /** List all dynamically registered derivation IDs */
1752
+ listDynamic(): string[];
1753
+ }
1754
+ /** Runtime control for resolvers */
1755
+ interface ResolversControl<M extends ModuleSchema = ModuleSchema> {
1756
+ /**
1757
+ * Register a new resolver at runtime.
1758
+ * @throws If a resolver with this ID already exists (use `assign` to override)
1759
+ * @remarks During reconciliation, the registration is deferred and applied after the current cycle completes.
1760
+ */
1761
+ register(id: string, def: DynamicResolverDef<M>): void;
1762
+ /**
1763
+ * Override an existing resolver (static or dynamic).
1764
+ * Clears the resolver-by-type cache.
1765
+ * @throws If no resolver with this ID exists (use `register` to create)
1766
+ * @remarks During reconciliation, the assignment is deferred and applied after the current cycle completes.
1767
+ */
1768
+ assign(id: string, def: DynamicResolverDef<M>): void;
1769
+ /**
1770
+ * Remove a dynamically registered resolver.
1771
+ * Static (module-defined) resolvers cannot be unregistered — logs a dev warning and no-ops.
1772
+ * @remarks During reconciliation, the unregistration is deferred and applied after the current cycle completes.
1773
+ */
1774
+ unregister(id: string): void;
1775
+ /**
1776
+ * Execute a resolver's `resolve()` with a requirement object.
1777
+ * @throws If no resolver with this ID exists
1778
+ */
1779
+ call(id: string, requirement: {
1780
+ type: string;
1781
+ [key: string]: unknown;
1782
+ }): Promise<void>;
1783
+ /** Check if a resolver was dynamically registered (not from a module definition) */
1784
+ isDynamic(id: string): boolean;
1785
+ /** List all dynamically registered resolver IDs */
1786
+ listDynamic(): string[];
1787
+ }
1788
+ /** Constraint definition for dynamic registration — typed facts, relaxed requirements */
1789
+ interface DynamicConstraintDef<M extends ModuleSchema = ModuleSchema> {
1790
+ priority?: number;
1791
+ async?: boolean;
1792
+ when: (facts: Readonly<InferSchema<M["facts"]>>) => boolean | Promise<boolean>;
1793
+ require: {
1794
+ type: string;
1795
+ [key: string]: unknown;
1796
+ } | {
1797
+ type: string;
1798
+ [key: string]: unknown;
1799
+ }[] | null | ((facts: Readonly<InferSchema<M["facts"]>>) => {
1800
+ type: string;
1801
+ [key: string]: unknown;
1802
+ } | {
1803
+ type: string;
1804
+ [key: string]: unknown;
1805
+ }[] | null);
1806
+ timeout?: number;
1807
+ after?: string[];
1808
+ deps?: string[];
1809
+ }
1810
+ /** Effect definition for dynamic registration — typed facts */
1811
+ interface DynamicEffectDef<M extends ModuleSchema = ModuleSchema> {
1812
+ run: (facts: Readonly<InferSchema<M["facts"]>>, prev: InferSchema<M["facts"]> | null) => void | (() => void) | Promise<void | (() => void)>;
1813
+ deps?: Array<string & keyof InferSchema<M["facts"]>>;
1814
+ }
1815
+ /** Resolver definition for dynamic registration — typed context.facts, relaxed requirement */
1816
+ interface DynamicResolverDef<M extends ModuleSchema = ModuleSchema> {
1817
+ requirement: string;
1818
+ key?: (req: {
1819
+ type: string;
1820
+ [key: string]: unknown;
1821
+ }) => string;
1822
+ retry?: RetryPolicy;
1823
+ timeout?: number;
1824
+ batch?: BatchConfig;
1825
+ resolve?: (req: {
1826
+ type: string;
1827
+ [key: string]: unknown;
1828
+ }, context: {
1829
+ facts: InferSchema<M["facts"]>;
1830
+ signal: AbortSignal;
1831
+ snapshot: () => InferSchema<M["facts"]>;
1832
+ }) => Promise<void>;
1833
+ resolveBatch?: (reqs: {
1834
+ type: string;
1835
+ [key: string]: unknown;
1836
+ }[], context: {
1837
+ facts: InferSchema<M["facts"]>;
1838
+ signal: AbortSignal;
1839
+ snapshot: () => InferSchema<M["facts"]>;
1840
+ }) => Promise<void>;
1647
1841
  }
1648
1842
  interface System<M extends ModuleSchema = ModuleSchema> {
1649
1843
  readonly facts: Facts<M["facts"]>;
1650
- readonly debug: TimeTravelAPI | null;
1651
- readonly derive: InferDerivations<M>;
1844
+ readonly history: HistoryAPI | null;
1845
+ readonly derive: InferDerivations<M> & DerivationsControl<M>;
1652
1846
  readonly events: EventsAccessorFromSchema<M>;
1653
- readonly constraints: ConstraintsControl;
1654
- readonly effects: EffectsControl;
1655
- /** Per-run changelog entries (null if debug.runHistory is not enabled) */
1656
- readonly runHistory: RunChangelogEntry[] | null;
1847
+ readonly constraints: ConstraintsControl<M>;
1848
+ readonly effects: EffectsControl<M>;
1849
+ readonly resolvers: ResolversControl<M>;
1850
+ /** Per-run trace entries (null if trace is not enabled) */
1851
+ readonly trace: TraceEntry[] | null;
1657
1852
  /** Initialize facts and derivations without starting reconciliation. Safe for SSR. */
1658
1853
  initialize(): void;
1659
1854
  start(): void;
@@ -1677,13 +1872,14 @@ interface System<M extends ModuleSchema = ModuleSchema> {
1677
1872
  */
1678
1873
  onSettledChange(listener: () => void): () => void;
1679
1874
  /**
1680
- * Subscribe to time-travel state changes.
1681
- * Called whenever a snapshot is taken or time-travel navigation occurs.
1875
+ * Subscribe to history state changes.
1876
+ * Called whenever a snapshot is taken or history navigation occurs.
1682
1877
  * Returns an unsubscribe function.
1683
1878
  */
1684
- onTimeTravelChange(listener: () => void): () => void;
1685
- read<K extends DerivationKeys<M>>(derivationId: K): DerivationReturnType<M, K>;
1686
- read<T = unknown>(derivationId: string): T;
1879
+ onHistoryChange(listener: () => void): () => void;
1880
+ read<K extends DerivationKeys<M>>(id: K): DerivationReturnType<M, K>;
1881
+ read<K extends FactKeys<M>>(id: K): FactReturnType<M, K>;
1882
+ read<T = unknown>(id: string): T;
1687
1883
  /**
1688
1884
  * Subscribe to fact or derivation changes.
1689
1885
  * Keys are auto-detected -- pass any mix of fact keys and derivation keys.
@@ -1724,6 +1920,17 @@ interface System<M extends ModuleSchema = ModuleSchema> {
1724
1920
  explain(requirementId: string): string | null;
1725
1921
  getSnapshot(): SystemSnapshot;
1726
1922
  restore(snapshot: SystemSnapshot): void;
1923
+ /**
1924
+ * Get the original definition that was overridden by `assign()`.
1925
+ * Returns undefined if no original exists for this type/id.
1926
+ */
1927
+ getOriginal(type: "constraint" | "resolver" | "derivation" | "effect", id: string): unknown | undefined;
1928
+ /**
1929
+ * Restore the original definition that was overridden by `assign()`.
1930
+ * Re-assigns the original definition and removes the override tracking.
1931
+ * Returns true if restoration succeeded, false if no original exists.
1932
+ */
1933
+ restoreOriginal(type: "constraint" | "resolver" | "derivation" | "effect", id: string): boolean;
1727
1934
  /**
1728
1935
  * Get a distributable snapshot of computed derivations.
1729
1936
  * This creates a serializable object that can be stored in Redis, JWT, etc.
@@ -1764,7 +1971,8 @@ interface System<M extends ModuleSchema = ModuleSchema> {
1764
1971
  interface SystemConfig<M extends ModuleSchema = ModuleSchema> {
1765
1972
  modules: Array<ModuleDef<M>>;
1766
1973
  plugins?: Array<Plugin<any>>;
1767
- debug?: DebugConfig;
1974
+ history?: HistoryOption;
1975
+ trace?: TraceOption;
1768
1976
  errorBoundary?: ErrorBoundaryConfig;
1769
1977
  /**
1770
1978
  * Callback invoked after module inits but before first reconcile.
@@ -1953,16 +2161,16 @@ interface Plugin<M extends ModuleSchema = ModuleSchema> {
1953
2161
  */
1954
2162
  onEffectError?: (id: string, error: unknown) => void;
1955
2163
  /**
1956
- * Called when a time-travel snapshot is taken.
2164
+ * Called when a history snapshot is taken.
1957
2165
  * @param snapshot - The snapshot that was captured
1958
2166
  */
1959
2167
  onSnapshot?: (snapshot: Snapshot) => void;
1960
2168
  /**
1961
- * Called when time-travel navigation occurs.
2169
+ * Called when history navigation occurs (undo/redo/goTo).
1962
2170
  * @param from - The index we navigated from
1963
2171
  * @param to - The index we navigated to
1964
2172
  */
1965
- onTimeTravel?: (from: number, to: number) => void;
2173
+ onHistoryNavigate?: (from: number, to: number) => void;
1966
2174
  /**
1967
2175
  * Called when any error occurs in the system.
1968
2176
  * @param error - The DirectiveError with source and context
@@ -1975,11 +2183,39 @@ interface Plugin<M extends ModuleSchema = ModuleSchema> {
1975
2183
  */
1976
2184
  onErrorRecovery?: (error: DirectiveError, strategy: RecoveryStrategy) => void;
1977
2185
  /**
1978
- * Called when a run finalizes (all resolvers settled or no resolvers started).
1979
- * Only fires when debug.runHistory is enabled.
1980
- * @param run - The complete run changelog entry
2186
+ * Called when a definition is dynamically registered at runtime.
2187
+ * @param type - The definition type: "constraint", "resolver", "derivation", or "effect"
2188
+ * @param id - The definition ID
2189
+ * @param def - The definition object
2190
+ */
2191
+ onDefinitionRegister?: (type: string, id: string, def: unknown) => void;
2192
+ /**
2193
+ * Called when a definition is assigned (overridden) at runtime.
2194
+ * @param type - The definition type: "constraint", "resolver", "derivation", or "effect"
2195
+ * @param id - The definition ID
2196
+ * @param def - The new definition object
2197
+ * @param original - The previous definition that was overridden
2198
+ */
2199
+ onDefinitionAssign?: (type: string, id: string, def: unknown, original: unknown) => void;
2200
+ /**
2201
+ * Called when a dynamically registered definition is removed.
2202
+ * @param type - The definition type: "constraint", "resolver", "derivation", or "effect"
2203
+ * @param id - The definition ID
2204
+ */
2205
+ onDefinitionUnregister?: (type: string, id: string) => void;
2206
+ /**
2207
+ * Called when a definition is manually invoked via `call()`.
2208
+ * @param type - The definition type: "constraint", "resolver", "derivation", or "effect"
2209
+ * @param id - The definition ID
2210
+ * @param props - Optional props passed to the call
2211
+ */
2212
+ onDefinitionCall?: (type: string, id: string, props?: unknown) => void;
2213
+ /**
2214
+ * Called when a trace entry finalizes (all resolvers settled or no resolvers started).
2215
+ * Only fires when trace is enabled.
2216
+ * @param entry - The complete trace entry
1981
2217
  */
1982
- onRunComplete?: (run: RunChangelogEntry) => void;
2218
+ onTraceComplete?: (entry: TraceEntry) => void;
1983
2219
  }
1984
2220
 
1985
- export { type AnySystem as $, type ConstraintState as A, type BatchConfig as B, type CrossModuleDeps as C, type DerivationsSchema as D, type EffectsDef as E, type Facts as F, type ResolversDef as G, type ResolverStatus as H, type InferRequirements as I, type System as J, type FactChange as K, type FactsSnapshot as L, type ModuleSchema as M, type NamespacedSystem as N, type ReconcileResult as O, type Plugin as P, type Snapshot as Q, type Requirement as R, type Schema as S, type TypedDerivationsDef as T, DirectiveError as U, type RecoveryStrategy as V, type RunChangelogEntry as W, type ErrorSource as X, type RetryLaterConfig as Y, type TimeTravelAPI as Z, type SystemConfig as _, type RequirementOutput$1 as a, type BatchItemResult as a0, type BatchResolveResults as a1, type CrossModuleConstraintDef as a2, type CrossModuleDerivationFn as a3, type CrossModuleEffectDef as a4, type CrossModuleFactsWithSelf as a5, type DerivationKeys as a6, type DerivationReturnType as a7, type DeriveAccessor as a8, type DispatchEventsFromSchema as a9, type RequirementsSchema as aA, type SnapshotMeta as aB, type SystemEvent as aC, type SystemInspection as aD, type SystemMode as aE, type SystemSnapshot as aF, type TimeTravelState as aG, type TypedResolverContext as aH, type TypedResolverDef as aI, type UnionEvents as aJ, isNamespacedSystem as aK, isSingleModuleSystem as aL, type DistributableSnapshot as aa, type DistributableSnapshotOptions as ab, type EffectCleanup as ac, type EventPayloadSchema as ad, type EventsAccessor as ae, type EventsAccessorFromSchema as af, type EventsDef as ag, type EventsSchema as ah, type FactKeys as ai, type FactReturnType as aj, type FlexibleEventHandler as ak, type InferDerivations as al, type InferEventPayloadFromSchema as am, type InferEvents as an, type InferRequirementPayloadFromSchema as ao, type InferRequirementTypes as ap, type InferSchema as aq, type InferSchemaType as ar, type InferSelectorState as as, type MutableNamespacedFacts as at, type NamespacedDerivations as au, type NamespacedEventsAccessor as av, type NamespacedFacts as aw, type ObservableKeys as ax, type RequirementExplanation as ay, type RequirementPayloadSchema$1 as az, type RetryPolicy as b, type ResolverContext as c, type SchemaType as d, type FactsStore as e, type TypedEventsDef as f, type TypedConstraintsDef as g, type TypedResolversDef as h, type ModuleHooks as i, type CrossModuleDerivationsDef as j, type CrossModuleEffectsDef as k, type CrossModuleConstraintsDef as l, type ModuleDef as m, type CreateSystemOptionsSingle as n, type SingleModuleSystem as o, type ModulesMap as p, type CreateSystemOptionsNamed as q, type TypedConstraintDef as r, type RequirementOutput as s, type DebugConfig as t, type ErrorBoundaryConfig as u, type InferFacts as v, type ExtractSchema as w, type RequirementWithId as x, type RequirementKeyFn as y, type ConstraintsDef as z };
2221
+ export { type CrossModuleDerivationFn as $, type FactChange as A, type BatchConfig as B, type CrossModuleDeps as C, type FactsSnapshot as D, type EffectsDef as E, type Facts as F, type ReconcileResult as G, type Snapshot as H, DirectiveError as I, type RecoveryStrategy as J, type TraceEntry as K, type ErrorSource as L, type ModuleSchema as M, type NamespacedSystem as N, type RetryLaterConfig as O, type Plugin as P, type HistoryAPI as Q, type Requirement as R, type Schema as S, type TypedDerivationsDef as T, type HistoryOption as U, type SystemConfig as V, type AnySystem as W, type BatchItemResult as X, type BatchResolveResults as Y, type ConstraintsControl as Z, type CrossModuleConstraintDef as _, type RequirementOutput$1 as a, type CrossModuleEffectDef as a0, type CrossModuleFactsWithSelf as a1, type DerivationKeys as a2, type DerivationReturnType as a3, type DerivationsControl as a4, type DerivationsSchema as a5, type DeriveAccessor as a6, type DispatchEventsFromSchema as a7, type DistributableSnapshot as a8, type DistributableSnapshotOptions as a9, type NamespacedDerivations as aA, type NamespacedEventsAccessor as aB, type NamespacedFacts as aC, type ObservableKeys as aD, type RequirementExplanation as aE, type RequirementOutput as aF, type RequirementPayloadSchema$1 as aG, type RequirementsSchema as aH, type ResolversControl as aI, type SnapshotMeta as aJ, type SystemEvent as aK, type SystemInspection as aL, type SystemMode as aM, type SystemSnapshot as aN, type TraceConfig as aO, type TypedConstraintDef as aP, type TypedResolverContext as aQ, type TypedResolverDef as aR, type UnionEvents as aS, isNamespacedSystem as aT, isSingleModuleSystem as aU, type DynamicConstraintDef as aa, type DynamicEffectDef as ab, type DynamicResolverDef as ac, type EffectCleanup as ad, type EffectsControl as ae, type EventPayloadSchema as af, type EventsAccessor as ag, type EventsAccessorFromSchema as ah, type EventsDef as ai, type EventsSchema as aj, type FactKeys as ak, type FactReturnType as al, type FlexibleEventHandler as am, type HistoryConfig as an, type HistoryState as ao, type InferDerivations as ap, type InferEventPayloadFromSchema as aq, type InferEvents as ar, type InferFacts as as, type InferRequirementPayloadFromSchema as at, type InferRequirementTypes as au, type InferRequirements as av, type InferSchema as aw, type InferSchemaType as ax, type InferSelectorState as ay, type MutableNamespacedFacts as az, type RetryPolicy as b, type ResolverContext as c, type SchemaType as d, type TypedEventsDef as e, type TypedConstraintsDef as f, type TypedResolversDef as g, type ModuleHooks as h, type CrossModuleDerivationsDef as i, type CrossModuleEffectsDef as j, type CrossModuleConstraintsDef as k, type ModuleDef as l, type CreateSystemOptionsSingle as m, type SingleModuleSystem as n, type ModulesMap as o, type CreateSystemOptionsNamed as p, type TraceOption as q, type ErrorBoundaryConfig as r, type RequirementWithId as s, type RequirementKeyFn as t, type FactsStore as u, type ConstraintsDef as v, type ConstraintState as w, type ResolversDef as x, type ResolverStatus as y, type System as z };