sia-reactor 0.0.19 → 0.0.21

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.
Files changed (38) hide show
  1. package/README.md +102 -58
  2. package/dist/TimeTravelOverlay-CJv-S_Km.d.cts +41 -0
  3. package/dist/TimeTravelOverlay-DxqJL0Zk.d.ts +41 -0
  4. package/dist/adapters/react.cjs +308 -92
  5. package/dist/adapters/react.d.cts +68 -10
  6. package/dist/adapters/react.d.ts +68 -10
  7. package/dist/adapters/react.js +80 -29
  8. package/dist/adapters/vanilla.cjs +957 -10
  9. package/dist/adapters/vanilla.d.cts +4 -2
  10. package/dist/adapters/vanilla.d.ts +4 -2
  11. package/dist/adapters/vanilla.js +8 -12
  12. package/dist/{chunk-Q2AKMIHN.js → chunk-2WBPGSRL.js} +106 -48
  13. package/dist/chunk-5A44QFT6.js +93 -0
  14. package/dist/{chunk-4MJUBEI7.js → chunk-DP74DVRT.js} +4 -2
  15. package/dist/{chunk-UQIMMJTY.js → chunk-P37ADJMM.js} +3 -3
  16. package/dist/chunk-TFLYCXK4.js +251 -0
  17. package/dist/{index-C2hyIh0K.d.cts → index-Oie9hhE8.d.cts} +14 -10
  18. package/dist/{index-C2hyIh0K.d.ts → index-Oie9hhE8.d.ts} +14 -10
  19. package/dist/index.cjs +45 -52
  20. package/dist/index.d.cts +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +4 -6
  23. package/dist/plugins.cjs +72 -73
  24. package/dist/plugins.d.cts +4 -75
  25. package/dist/plugins.d.ts +4 -75
  26. package/dist/plugins.js +27 -22
  27. package/dist/styles/time-travel-overlay.css +189 -0
  28. package/dist/super.d.ts +79 -26
  29. package/dist/super.global.js +200 -105
  30. package/dist/timeTravel-B1vedDQc.d.ts +76 -0
  31. package/dist/timeTravel-WpgWmKu-.d.cts +76 -0
  32. package/dist/utils.cjs +34 -7
  33. package/dist/utils.d.cts +9 -2
  34. package/dist/utils.d.ts +9 -2
  35. package/dist/utils.js +17 -65
  36. package/package.json +3 -2
  37. package/dist/chunk-FGUCKMLH.js +0 -154
  38. package/dist/chunk-KIQP7G7W.js +0 -80
package/dist/plugins.js CHANGED
@@ -1,13 +1,12 @@
1
1
  import {
2
2
  reactive
3
- } from "./chunk-KIQP7G7W.js";
3
+ } from "./chunk-2WBPGSRL.js";
4
4
  import {
5
5
  clamp,
6
6
  guardAllMethods,
7
7
  guardMethod,
8
8
  setTimeout
9
- } from "./chunk-UQIMMJTY.js";
10
- import "./chunk-Q2AKMIHN.js";
9
+ } from "./chunk-P37ADJMM.js";
11
10
  import {
12
11
  NOOP,
13
12
  deepClone,
@@ -17,9 +16,9 @@ import {
17
16
  isPOJO,
18
17
  mergeObjs,
19
18
  setAny
20
- } from "./chunk-4MJUBEI7.js";
19
+ } from "./chunk-DP74DVRT.js";
21
20
 
22
- // src/plugins/base.ts
21
+ // src/ts/plugins/base.ts
23
22
  var BaseReactorPlugin = class {
24
23
  static plugName;
25
24
  get name() {
@@ -57,7 +56,7 @@ var BaseReactorPlugin = class {
57
56
  // `()=>{}`: needs to be bounded even before initialization
58
57
  };
59
58
 
60
- // src/utils/store.ts
59
+ // src/ts/utils/store.ts
61
60
  var BaseStorageAdapter = class {
62
61
  static name;
63
62
  config;
@@ -191,7 +190,7 @@ var IndexedDBAdapter = class extends AsyncStorageAdapter {
191
190
  };
192
191
  var INDEXED_DB_ADAPTER_BUILD = { dbName: "REACTOR_IDB", stores: ["VAULT"], version: 1, onidb: NOOP, onupgradeneeded: NOOP, onversionchange: NOOP, onsuccess: NOOP, onerror: NOOP, onblocked: NOOP };
193
192
 
194
- // src/plugins/persist.ts
193
+ // src/ts/plugins/persist.ts
195
194
  var PersistPlugin = class extends BaseReactorPlugin {
196
195
  static plugName = "persist";
197
196
  adapter;
@@ -244,12 +243,13 @@ var PersistPlugin = class extends BaseReactorPlugin {
244
243
  };
245
244
  var PERSIST_PLUGIN_BUILD = { disabled: false, key: "REACTOR_STORE", throttle: 2500, useSnapshot: false };
246
245
 
247
- // src/plugins/timeTravel.ts
246
+ // src/ts/plugins/timeTravel.ts
248
247
  var TimeTravelPlugin = class extends BaseReactorPlugin {
249
248
  static plugName = "timeTravel";
249
+ lastTimestamp = 0;
250
250
  playbackTimeoutId = -1;
251
251
  constructor(config, rtr) {
252
- super({ ...TIME_TRAVEL_PLUGIN_BUILD, ...config }, rtr, { history: [], initialState: null, currentFrame: 0, paused: true });
252
+ super({ ...TIME_TRAVEL_PLUGIN_BUILD, ...config }, rtr, { initialState: null, history: [], currentFrame: 0, paused: true });
253
253
  }
254
254
  // ===========================================================================
255
255
  // THE FOUNDATION & WIRETAP (Passive Recording)
@@ -257,6 +257,7 @@ var TimeTravelPlugin = class extends BaseReactorPlugin {
257
257
  wire() {
258
258
  this.rtr.config.referenceTracking = this.rtr.config.smartCloning = this.rtr.config.eventTimeStamps = true;
259
259
  if (!this.state.history.length || this.state.initialState == null) this.state.initialState = this.rtr.snapshot();
260
+ this.lastTimestamp = performance.now();
260
261
  this.state.set("currentFrame", (v = 0) => clamp(0, v, this.state.history.length), { signal: this.signal, immediate: true });
261
262
  this.config.on("paths", this.handlePathsState, { signal: this.signal, immediate: true });
262
263
  !this.state.paused && this.play();
@@ -270,16 +271,17 @@ var TimeTravelPlugin = class extends BaseReactorPlugin {
270
271
  if (!this.state.paused) return;
271
272
  if (this.state.currentFrame < this.state.history.length) this.state.history = this.state.history.slice(0, this.state.currentFrame);
272
273
  if (this.state.history.length >= this.config.maxHistoryLength) this.state.history = this.state.history.slice(1);
273
- this.state.history.push({ timestamp: e.timestamp ?? performance.now(), path: e.target.path, type: e.staticType, value: this.rtr.snapshot(false, e.target.value), oldValue: this.rtr.snapshot(false, e.target.oldValue), keyExisted: e.target.keyExisted, rejected: e.rejected });
274
+ this.state.history.push({ path: e.target.path, value: this.rtr.snapshot(false, e.target.value), oldValue: this.rtr.snapshot(false, e.target.oldValue), type: e.staticType, rejected: e.rejected, timedelta: e.timestamp - this.lastTimestamp, hadKey: e.target.hadKey });
274
275
  this.state.currentFrame = this.state.history.length;
276
+ this.lastTimestamp = e.timestamp;
275
277
  }
276
278
  /** Clears timeline history and resets playhead/genesis to the current reactor state. */
277
279
  clear() {
278
280
  this.pause();
279
281
  this.playbackTimeoutId = -1;
280
- this.state.history = [];
281
- this.state.currentFrame = 0;
282
+ this.state.history.length = this.state.currentFrame = 0;
282
283
  this.state.initialState = this.rtr.snapshot();
284
+ this.lastTimestamp = performance.now();
283
285
  }
284
286
  // ===========================================================================
285
287
  // THE TIME MACHINE (Manual Controls)
@@ -292,7 +294,7 @@ var TimeTravelPlugin = class extends BaseReactorPlugin {
292
294
  const e = this.state.history[forward ? this.state.currentFrame : this.state.currentFrame - 1];
293
295
  if (!e) break;
294
296
  if (forward) e.type === "delete" ? deleteAny(this.rtr.core, e.path) : setAny(this.rtr.core, e.path, deepClone(e.value, this.rtr.config));
295
- else !e.keyExisted ? deleteAny(this.rtr.core, e.path) : setAny(this.rtr.core, e.path, deepClone(e.oldValue, this.rtr.config));
297
+ else !e.hadKey ? deleteAny(this.rtr.core, e.path) : setAny(this.rtr.core, e.path, deepClone(e.oldValue, this.rtr.config));
296
298
  forward ? this.state.currentFrame++ : this.state.currentFrame--;
297
299
  if (e.rejected) this.rtr.log(`[Reactor ${this.name} Plug] ${forward ? "Replaying" : "Reversing"} REJECTED intent at "${e.path}"`);
298
300
  }
@@ -315,9 +317,9 @@ var TimeTravelPlugin = class extends BaseReactorPlugin {
315
317
  async automove(forward = true) {
316
318
  this.state.paused = false;
317
319
  while ((forward ? this.state.currentFrame < this.state.history.length : this.state.currentFrame > 0) && !this.state.paused) {
318
- const currIndex = forward ? this.state.currentFrame : this.state.currentFrame - 1, e = this.state.history[currIndex], nextE = this.state.history[forward ? currIndex + 1 : currIndex - 1], delay = nextE && e ? Math.abs(nextE.timestamp - e.timestamp) : 0;
320
+ const currIndex = forward ? this.state.currentFrame : this.state.currentFrame - 1, e = this.state.history[forward ? currIndex + 1 : currIndex - 1];
319
321
  this.jumpTo(this.state.currentFrame + (forward ? 1 : -1), true);
320
- if (delay > 0) await new Promise((res) => this.playbackTimeoutId = setTimeout(() => res(0), clamp(0, delay, this.config.maxPlaybackDelay), this.signal));
322
+ if (e?.timedelta > 0) await new Promise((res) => this.playbackTimeoutId = setTimeout(() => res(0), Math.min(e.timedelta, this.config.maxPlaybackDelay), this.signal));
321
323
  }
322
324
  this.state.paused = true;
323
325
  }
@@ -331,21 +333,24 @@ var TimeTravelPlugin = class extends BaseReactorPlugin {
331
333
  // TELEMETRY & I/O (Session Import/Export)
332
334
  // ===========================================================================
333
335
  /** Exports the current session as a JSON string. */
334
- export() {
335
- return JSON.stringify(this.state);
336
+ export(replacer, space) {
337
+ try {
338
+ return JSON.stringify(this.state, replacer, space);
339
+ } catch (e) {
340
+ return this.rtr.log(`[Reactor ${this.name} Plug] Failed to export session`), "";
341
+ }
336
342
  }
337
343
  /** Imports a session from a JSON string, allowing you to replay or analyze past states. */
338
344
  import(json) {
339
345
  try {
340
346
  setAny(this.state, "*", JSON.parse(json));
347
+ this.lastTimestamp = performance.now();
341
348
  const resume = !this.state.paused, target = this.state.currentFrame;
342
349
  this.state.paused = false;
343
- setAny(this.rtr.core, "*", deepClone(this.state.initialState, this.rtr.config));
344
- this.rtr.tick();
345
- this.state.currentFrame = 0;
346
- this.jumpTo(target), resume && this.play();
350
+ setAny(this.rtr.core, "*", deepClone(this.state.initialState, this.rtr.config)), this.rtr.tick();
351
+ this.state.currentFrame = 0, this.jumpTo(target), resume && this.play();
347
352
  } catch (e) {
348
- this.rtr.log(`[Reactor ${this.name} Plug] Failed to load session`, "error");
353
+ this.rtr.log(`[Reactor ${this.name} Plug] Failed to load session`);
349
354
  }
350
355
  }
351
356
  };
@@ -0,0 +1,189 @@
1
+ .tt-overlay-host {
2
+ --sia-tt-color: #e26e02;
3
+ --sia-tt-bg: rgb(from var(--sia-tt-color) calc((r * 0.09) + 6) calc((g * 0.08) + 7) calc((b * 0.1) + 10) / 0.66);
4
+ --sia-tt-bg-soft: rgb(from var(--sia-tt-color) calc((r * 0.11) + 9) calc((g * 0.1) + 9) calc((b * 0.12) + 12) / 0.64);
5
+ --sia-tt-line: hsl(from var(--sia-tt-color) h calc(s * 0.1) 24% / 0.6);
6
+ --sia-tt-text: rgb(from var(--sia-tt-color) calc((r * 0.2) + 218) calc((g * 0.11) + 214) calc((b * 0.09) + 214));
7
+ --sia-tt-muted: rgb(from var(--sia-tt-color) calc((r * 0.24) + 150) calc((g * 0.14) + 146) calc((b * 0.12) + 146));
8
+ --sia-tt-input-bg: rgb(from var(--sia-tt-color) calc((r * 0.08) + 8) calc((g * 0.07) + 8) calc((b * 0.09) + 10) / 0.66);
9
+ position: relative;
10
+ }
11
+
12
+ :where(.tt-overlay-host) *::selection {
13
+ color: currentColor;
14
+ background-color: var(--sia-tt-color);
15
+ }
16
+ .tt-overlay-host :is(*:focus-visible, #o#o#o#o#o) {
17
+ outline: 1.5px dashed var(--sia-tt-color);
18
+ outline-offset: 1px;
19
+ transition: none;
20
+ }
21
+ .tt-overlay input[type="range"]:focus-visible {
22
+ outline-offset: 1px;
23
+ }
24
+
25
+ .tt-overlay-layer {
26
+ inset: 0;
27
+ z-index: 60;
28
+ pointer-events: none;
29
+ }
30
+
31
+ .tt-overlay-dock {
32
+ position: absolute;
33
+ right: 18px;
34
+ bottom: 18px;
35
+ display: flex;
36
+ gap: 8px;
37
+ justify-content: flex-end;
38
+ pointer-events: auto;
39
+ }
40
+
41
+ .tt-overlay-toggle {
42
+ position: relative;
43
+ z-index: 1;
44
+ color: var(--sia-tt-text);
45
+ background: var(--sia-tt-bg-soft);
46
+ border: 1px solid var(--sia-tt-line);
47
+ border-radius: 8px;
48
+ font-size: 0.75rem;
49
+ line-height: 1.1;
50
+ padding: 5px 8px;
51
+ cursor: pointer;
52
+ pointer-events: auto;
53
+ }
54
+
55
+ .tt-overlay {
56
+ position: absolute;
57
+ right: 0;
58
+ bottom: calc(100% + 8px);
59
+ width: min(360px, calc(100vw - 50px));
60
+ background: var(--sia-tt-bg);
61
+ border: 1px solid var(--sia-tt-line);
62
+ border-radius: 12px;
63
+ padding: 12px;
64
+ display: grid;
65
+ gap: 8px;
66
+ z-index: 39;
67
+ color: var(--sia-tt-text);
68
+ -webkit-backdrop-filter: blur(6px);
69
+ backdrop-filter: blur(6px);
70
+ pointer-events: auto;
71
+ opacity: 1;
72
+ transform: translateY(0) scale(1);
73
+ transform-origin: right bottom;
74
+ visibility: visible;
75
+ transition: opacity 160ms ease, transform 180ms ease, visibility 0ms linear;
76
+ }
77
+
78
+ .tt-overlay[hidden] {
79
+ opacity: 0;
80
+ transform: translateY(6px) scale(0.985);
81
+ visibility: hidden;
82
+ pointer-events: none;
83
+ transition: opacity 140ms ease, transform 160ms ease, visibility 0ms linear 160ms;
84
+ }
85
+
86
+ @media (prefers-reduced-motion: reduce) {
87
+ .tt-overlay,
88
+ .tt-overlay[hidden] {
89
+ transition: none;
90
+ }
91
+ }
92
+
93
+ .tt-overlay .title {
94
+ color: var(--sia-tt-color);
95
+ font-weight: bold;
96
+ }
97
+
98
+ .tt-overlay button {
99
+ border: 1px solid var(--sia-tt-line);
100
+ background: var(--sia-tt-bg-soft);
101
+ color: var(--sia-tt-text);
102
+ border-radius: 8px;
103
+ padding: 5px 8px;
104
+ font-size: 0.75rem;
105
+ line-height: 1.1;
106
+ cursor: pointer;
107
+ }
108
+
109
+ .tt-overlay button:hover {
110
+ border-color: hsl(from var(--sia-tt-color) h calc(s * 0.35) 40% / 0.9);
111
+ }
112
+
113
+ .tt-overlay button:disabled {
114
+ opacity: 0.7;
115
+ cursor: not-allowed;
116
+ color: var(--sia-tt-muted);
117
+ }
118
+
119
+ .tt-status-row {
120
+ display: flex;
121
+ align-items: flex-start;
122
+ gap: 8px;
123
+ justify-content: space-between;
124
+ }
125
+
126
+ .tt-status-row > button {
127
+ white-space: nowrap;
128
+ }
129
+
130
+ .tt-status-box {
131
+ display: grid;
132
+ gap: 4px;
133
+ flex: 1;
134
+ min-width: 0;
135
+ }
136
+
137
+ .tt-status-box .muted {
138
+ margin: 0;
139
+ font-size: 0.75rem;
140
+ }
141
+
142
+ .tt-row {
143
+ display: flex;
144
+ gap: 8px;
145
+ justify-content: center;
146
+ }
147
+
148
+ .tt-overlay input[type="range"] {
149
+ width: 100%;
150
+ height: 5px;
151
+ accent-color: var(--sia-tt-color);
152
+ border-radius: 8px;
153
+ }
154
+
155
+ .tt-io {
156
+ min-height: 84px;
157
+ max-height: calc((100vh - 318px) / 2);
158
+ resize: vertical;
159
+ border: 1px solid var(--sia-tt-line);
160
+ background: var(--sia-tt-input-bg);
161
+ color: var(--sia-tt-text);
162
+ font-size: 0.75rem;
163
+ border-radius: 8px;
164
+ padding: 8px;
165
+ scrollbar-width: thin;
166
+ scrollbar-color: var(--sia-tt-color) var(--sia-tt-bg-soft);
167
+ }
168
+
169
+ .tt-io::placeholder {
170
+ color: var(--sia-tt-muted);
171
+ }
172
+
173
+ .tt-footnote {
174
+ margin: 2px 2px 0;
175
+ font-size: 0.72rem;
176
+ line-height: 1.35;
177
+ color: var(--sia-tt-muted);
178
+ text-align: right;
179
+ }
180
+
181
+ .tt-footnote a {
182
+ color: var(--sia-tt-color);
183
+ text-decoration: none;
184
+ border-bottom: 1px solid var(--sia-tt-line);
185
+ }
186
+
187
+ .tt-footnote a:hover {
188
+ text-decoration: underline;
189
+ }
package/dist/super.d.ts CHANGED
@@ -172,7 +172,7 @@ type RDepth = 10; // current limit for state trees, observed ts max - 19; limit
172
172
  type RPrev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
173
173
 
174
174
  /** Reactor method names exposed on objects returned by {@link reactive}. */
175
- declare const methods: readonly ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "cascade", "snapshot", "reset", "destroy"];
175
+ declare const methods: readonly ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "snapshot", "cascade", "plugIn", "reset", "destroy"];
176
176
  type Method = (typeof methods)[number];
177
177
  type Prefix<P extends ReactivePreferences | undefined> = P extends {
178
178
  prefix?: infer X extends string;
@@ -203,6 +203,7 @@ type Reactive<T extends object, P extends ReactivePreferences | undefined = unde
203
203
  };
204
204
  /**
205
205
  * Attaches Reactor APIs to a state object and returns its reactive proxy.
206
+ * If an existing `reactive()` return value is passed, it is re-returned ignoring change in preferences.
206
207
  * @param target Source state object or an existing Reactor instance.
207
208
  * @param build Reactor initial configuration.
208
209
  * @param preferences Method naming preferences for exposed APIs.
@@ -326,7 +327,7 @@ interface Target<T, P extends WildPaths<T> = WildPaths<T>> {
326
327
  * Whether the key for the value existed on the parent object.
327
328
  * For accuracy on if `key` was in the `object` rather than checking `oldValue` against undefined
328
329
  */
329
- keyExisted: boolean;
330
+ hadKey: boolean;
330
331
  /** Parent-branch value for the path. */
331
332
  object: PathBranchValue<T, P>;
332
333
  }
@@ -363,7 +364,7 @@ interface UpdatePayload<T, P extends WildPaths<T> = WildPaths<T>> extends BasePa
363
364
  }
364
365
 
365
366
  /** Event union with payload-aware overrides for `type`, `path`, and value fields (Creates the IDE magic). */
366
- type REvent<T, P extends WildPaths<T> = WildPaths<T>> =
367
+ type REvent<T extends object, P extends WildPaths<T> = WildPaths<T>> =
367
368
  | (Omit<ReactorEvent<T, P>, OverrideEvtProp> &
368
369
  DirectPayload<T, P> &
369
370
  OverrideEvtPart<DirectPayload<T, P>>)
@@ -726,7 +727,7 @@ declare abstract class BaseReactorPlugin<T extends object = any, Config = any, S
726
727
  readonly signal: AbortSignal;
727
728
  rtr: Reactor<T>;
728
729
  config: Config extends object ? Reactive<Config> : Config;
729
- state: State extends object ? Reactive<State> : State;
730
+ readonly state: State extends object ? Reactive<State> : State;
730
731
  constructor(config?: Config, rtr?: Reactor<T>, state?: State);
731
732
  /** Entry point called to initialize plugin wiring. */
732
733
  setup(rtr?: Reactor<T>): void;
@@ -768,13 +769,13 @@ declare class Reactor<T extends object> {
768
769
  protected listeners?: Map<WildPaths<T>, Array<ListenerRecord<T>>>;
769
770
  /**
770
771
  * Creates a new Reactor instance.
771
- * @param object Initial state object.
772
+ * @param target Initial state target.
772
773
  * @param build Reactor bootstrap/build configuration.
773
774
  * @example
774
775
  * const rtr = new Reactor({ count: 0 });
775
776
  */
776
- constructor(object?: T, build?: ReactorBuild<T>);
777
- proxied<O extends object>(obj: O, rejectable?: boolean, indiffable?: boolean, parent?: object, key?: string, path?: string): O;
777
+ constructor(target?: T, build?: ReactorBuild<T>);
778
+ proxied<O extends object>(target: O, rejectable?: boolean, indiffable?: boolean, parent?: object, key?: string, path?: string): O;
778
779
  trace(target: object, path: string, paths?: string[], seen?: WeakSet<object>): Paths<T>[];
779
780
  protected link(target: any, parent: object, key: string, typecheck?: boolean, es?: (object | string)[]): boolean;
780
781
  protected unlink(target: any, parent: object, key: string): void;
@@ -814,7 +815,7 @@ declare class Reactor<T extends object> {
814
815
  getDepth(path: string, depth?: number): number;
815
816
  protected getContext<P extends WildPaths<T>>(path: P): Target<T, P>;
816
817
  protected bindSignal<Cb>(cord: GetterRecord<T> | SetterRecord<T> | DeleterRecord<T> | WatcherRecord<T> | ListenerRecord<T>, sig?: AbortSignal): Cb;
817
- protected cloned(obj: any, raw: boolean, seen?: WeakMap<WeakKey, any>): any;
818
+ protected cloned<O>(target: O, raw: boolean, seen?: WeakMap<WeakKey, any>): O;
818
819
  protected syncAdd<P extends WildPaths<T>>(key: "get" | "set" | "delete" | "watch", path: P, cb: any, opts: SyncOptions | undefined, onImmediate?: (immediate: boolean | "auto") => void): () => boolean | undefined;
819
820
  protected syncDrop<P extends WildPaths<T>>(store: Map<WildPaths<T>, any[]> | undefined, path: P, cb: any): boolean | undefined;
820
821
  /**
@@ -930,7 +931,8 @@ declare class Reactor<T extends object> {
930
931
  * @example
931
932
  * const snap = rtr.snapshot(false, rtr.core.history.past);
932
933
  */
933
- snapshot(raw?: boolean, branch?: T): T;
934
+ snapshot(raw?: boolean): T;
935
+ snapshot<B>(raw?: boolean, branch?: B): B;
934
936
  /**
935
937
  * Cascades object updates into direct child paths.
936
938
  * @param payload Event or payload source.
@@ -1032,6 +1034,8 @@ declare function withTracker<T>(tracker: Autotracker<any>, run: () => T, rtr?: R
1032
1034
 
1033
1035
  /** Global context object for sharing state across the reactor runtime. */
1034
1036
  declare const CTX: {
1037
+ /** Flag indicating whether the application is running in development mode. */
1038
+ isDevEnv: boolean;
1035
1039
  /** active `Autotracker` instance, override for automatic dependency collection on `Reactor` traps. */
1036
1040
  autotracker: Autotracker<any> | null;
1037
1041
  };
@@ -1233,11 +1237,20 @@ declare function formatKeyShortcutsForDisplay(keyShortcuts: Record<string, strin
1233
1237
  */
1234
1238
  declare function parseForARIAKS(s: string | string[], formatted?: boolean): string;
1235
1239
 
1240
+ type Dataset = Record<string, string | number>;
1241
+ type Style = Partial<CSSStyleDeclaration>;
1242
+ declare function createEl<K extends keyof HTMLElementTagNameMap>(tag: K, props?: Partial<HTMLElementTagNameMap[K]>, dataset?: Dataset, styles?: Style): HTMLElementTagNameMap[K];
1243
+ declare function createEl(tag: string, props?: Partial<HTMLElement>, dataset?: Dataset, styles?: Style): HTMLElement | null;
1244
+ declare function assignEl<K extends keyof HTMLElementTagNameMap>(el?: HTMLElementTagNameMap[K], props?: Partial<HTMLElementTagNameMap[K]>, dataset?: Dataset, styles?: Style): void;
1245
+ declare function assignEl(el?: HTMLElement | null, props?: Partial<HTMLElement>, dataset?: Dataset, styles?: Style): void;
1246
+
1236
1247
  type utils_KeyStruct = KeyStruct;
1248
+ declare const utils_assignEl: typeof assignEl;
1237
1249
  declare const utils_bindAllMethods: typeof bindAllMethods;
1238
1250
  declare const utils_canHandle: typeof canHandle;
1239
1251
  declare const utils_clamp: typeof clamp;
1240
1252
  declare const utils_cleanKeyCombo: typeof cleanKeyCombo;
1253
+ declare const utils_createEl: typeof createEl;
1241
1254
  declare const utils_deepClone: typeof deepClone;
1242
1255
  declare const utils_deleteAny: typeof deleteAny;
1243
1256
  declare const utils_formatKeyForDisplay: typeof formatKeyForDisplay;
@@ -1266,7 +1279,7 @@ declare const utils_setInterval: typeof setInterval;
1266
1279
  declare const utils_setTimeout: typeof setTimeout;
1267
1280
  declare const utils_stringifyKeyEvent: typeof stringifyKeyEvent;
1268
1281
  declare namespace utils {
1269
- export { type utils_KeyStruct as KeyStruct, utils_bindAllMethods as bindAllMethods, utils_canHandle as canHandle, utils_clamp as clamp, utils_cleanKeyCombo as cleanKeyCombo, utils_deepClone as deepClone, utils_deleteAny as deleteAny, utils_formatKeyForDisplay as formatKeyForDisplay, utils_formatKeyShortcutsForDisplay as formatKeyShortcutsForDisplay, utils_getAny as getAny, utils_getTermsForKey as getTermsForKey, utils_getTrailRecords as getTrailRecords, utils_guardAllMethods as guardAllMethods, utils_guardMethod as guardMethod, utils_inAny as inAny, utils_isObj as isObj, utils_isPOJO as isPOJO, utils_keyEventAllowed as keyEventAllowed, type utils_keysSettings as keysSettings, utils_matchKeys as matchKeys, utils_mergeObjs as mergeObjs, utils_nuke as nuke, utils_onAllMethods as onAllMethods, utils_parseAnyObj as parseAnyObj, utils_parseEvtOpts as parseEvtOpts, utils_parseForARIAKS as parseForARIAKS, utils_parseKeyCombo as parseKeyCombo, utils_requestAnimationFrame as requestAnimationFrame, utils_setAny as setAny, utils_setInterval as setInterval, utils_setTimeout as setTimeout, utils_stringifyKeyEvent as stringifyKeyEvent };
1282
+ export { type utils_KeyStruct as KeyStruct, utils_assignEl as assignEl, utils_bindAllMethods as bindAllMethods, utils_canHandle as canHandle, utils_clamp as clamp, utils_cleanKeyCombo as cleanKeyCombo, utils_createEl as createEl, utils_deepClone as deepClone, utils_deleteAny as deleteAny, utils_formatKeyForDisplay as formatKeyForDisplay, utils_formatKeyShortcutsForDisplay as formatKeyShortcutsForDisplay, utils_getAny as getAny, utils_getTermsForKey as getTermsForKey, utils_getTrailRecords as getTrailRecords, utils_guardAllMethods as guardAllMethods, utils_guardMethod as guardMethod, utils_inAny as inAny, utils_isObj as isObj, utils_isPOJO as isPOJO, utils_keyEventAllowed as keyEventAllowed, type utils_keysSettings as keysSettings, utils_matchKeys as matchKeys, utils_mergeObjs as mergeObjs, utils_nuke as nuke, utils_onAllMethods as onAllMethods, utils_parseAnyObj as parseAnyObj, utils_parseEvtOpts as parseEvtOpts, utils_parseForARIAKS as parseForARIAKS, utils_parseKeyCombo as parseKeyCombo, utils_requestAnimationFrame as requestAnimationFrame, utils_setAny as setAny, utils_setInterval as setInterval, utils_setTimeout as setTimeout, utils_stringifyKeyEvent as stringifyKeyEvent };
1270
1283
  }
1271
1284
 
1272
1285
  interface StorageAdapterConfig {
@@ -1378,22 +1391,22 @@ declare const PERSIST_PLUGIN_BUILD: Partial<PersistConfig<any>>;
1378
1391
 
1379
1392
  /** The DNA of a specific moment in time, Records the 'Desire' (Intent) or the 'Fact' (State). */
1380
1393
  interface HistoryEntry {
1381
- /** Was it a 'set' or a 'delete' surgery? */
1382
- type: REvent<any, any>["staticType"];
1383
1394
  /** The surgical address in the Reactor */
1384
1395
  path: string;
1385
1396
  /** The data payload at that moment */
1386
1397
  value: any;
1387
1398
  /** The "Undo" antidote (Previous value), if applicable */
1388
1399
  oldValue: any;
1389
- /** Did the key for the value exist on its parent object? */
1390
- keyExisted: boolean;
1400
+ /** Was it a 'set' or a 'delete' surgery? */
1401
+ type: REvent<any, any>["staticType"];
1391
1402
  /** Did the Power Line disapprove?; why? */
1392
1403
  rejected: string;
1393
1404
  /** For chronological re-enactment */
1394
- timestamp: number;
1405
+ timedelta: number;
1406
+ /** Did the key for the value exist on its parent object? */
1407
+ hadKey: boolean;
1395
1408
  }
1396
- interface TimeTravelConfig<T extends object = any> {
1409
+ interface TimeTravelConfig$1<T extends object = any> {
1397
1410
  /** Specific paths only, no "*"; instead don't pass anything */
1398
1411
  paths?: Paths<T>[];
1399
1412
  /** Maximum number of history entries to keep (Memory Cap), you lose replaying Sessions or the Genesis */
@@ -1402,10 +1415,10 @@ interface TimeTravelConfig<T extends object = any> {
1402
1415
  maxPlaybackDelay: number;
1403
1416
  }
1404
1417
  interface TimeTravelState {
1405
- /** The "Timeline" of mutations (Chronological Log) */
1406
- history: HistoryEntry[];
1407
1418
  /** The "Genesis" snapshot (Raw Data) */
1408
1419
  initialState: any;
1420
+ /** The "Timeline" of mutations (Chronological Log) */
1421
+ history: HistoryEntry[];
1409
1422
  /** The manual playhead (Index in the Timeline) */
1410
1423
  currentFrame: number;
1411
1424
  /** Whether playback is currently paused (Automatic Replay) */
@@ -1415,12 +1428,13 @@ interface TimeTravelState {
1415
1428
  * The Flight Recorder (Black Box).
1416
1429
  * - Implements S.I.A. logic to allow playback, teleportation, redos and undos.
1417
1430
  */
1418
- declare class TimeTravelPlugin<T extends object = any> extends BaseReactorPlugin<T, TimeTravelConfig<T>, TimeTravelState> {
1431
+ declare class TimeTravelPlugin<T extends object = any> extends BaseReactorPlugin<T, TimeTravelConfig$1<T>, TimeTravelState> {
1419
1432
  static readonly plugName = "timeTravel";
1433
+ protected lastTimestamp: number;
1420
1434
  protected playbackTimeoutId: number;
1421
- constructor(config?: Partial<TimeTravelConfig<T>>, rtr?: Reactor<T>);
1435
+ constructor(config?: Partial<TimeTravelConfig$1<T>>, rtr?: Reactor<T>);
1422
1436
  wire(): void;
1423
- protected handlePathsState({ value: paths, oldValue: prevs }: REvent<TimeTravelConfig<T>, "paths">): void;
1437
+ protected handlePathsState({ value: paths, oldValue: prevs }: REvent<TimeTravelConfig$1<T>, "paths">): void;
1424
1438
  /** Chronicling the lifecycle of the system, Captures the essence of every mutation wave that bubbles up. */
1425
1439
  protected record(e: REvent<T, any>): void;
1426
1440
  /** Clears timeline history and resets playhead/genesis to the current reactor state. */
@@ -1442,11 +1456,11 @@ declare class TimeTravelPlugin<T extends object = any> extends BaseReactorPlugin
1442
1456
  /** Pauses the live VCR playback. */
1443
1457
  pause: () => void;
1444
1458
  /** Exports the current session as a JSON string. */
1445
- export(): string;
1459
+ export(replacer?: ((this: any, key: string, value: any) => any) | (number | string)[] | null, space?: string | number): string;
1446
1460
  /** Imports a session from a JSON string, allowing you to replay or analyze past states. */
1447
1461
  import(json: string): void;
1448
1462
  }
1449
- declare const TIME_TRAVEL_PLUGIN_BUILD: Partial<TimeTravelConfig>;
1463
+ declare const TIME_TRAVEL_PLUGIN_BUILD: Partial<TimeTravelConfig$1>;
1450
1464
 
1451
1465
  type plugins_AsyncStorageAdapterConstructor<Config extends StorageAdapterConfig = StorageAdapterConfig> = AsyncStorageAdapterConstructor<Config>;
1452
1466
  type plugins_BaseReactorPlugin<T extends object = any, Config = any, State = any> = BaseReactorPlugin<T, Config, State>;
@@ -1473,12 +1487,11 @@ declare const plugins_StorageAdapter: typeof StorageAdapter;
1473
1487
  type plugins_StorageAdapterConfig = StorageAdapterConfig;
1474
1488
  type plugins_StorageAdapterConstructor<Config extends StorageAdapterConfig = StorageAdapterConfig> = StorageAdapterConstructor<Config>;
1475
1489
  declare const plugins_TIME_TRAVEL_PLUGIN_BUILD: typeof TIME_TRAVEL_PLUGIN_BUILD;
1476
- type plugins_TimeTravelConfig<T extends object = any> = TimeTravelConfig<T>;
1477
1490
  type plugins_TimeTravelPlugin<T extends object = any> = TimeTravelPlugin<T>;
1478
1491
  declare const plugins_TimeTravelPlugin: typeof TimeTravelPlugin;
1479
1492
  type plugins_TimeTravelState = TimeTravelState;
1480
1493
  declare namespace plugins {
1481
- export { type plugins_AsyncStorageAdapterConstructor as AsyncStorageAdapterConstructor, plugins_BaseReactorPlugin as BaseReactorPlugin, plugins_BaseStorageAdapter as BaseStorageAdapter, type plugins_HistoryEntry as HistoryEntry, plugins_INDEXED_DB_ADAPTER_BUILD as INDEXED_DB_ADAPTER_BUILD, plugins_IndexedDBAdapter as IndexedDBAdapter, type plugins_IndexedDBAdapterConfig as IndexedDBAdapterConfig, plugins_LocalStorageAdapter as LocalStorageAdapter, plugins_MemoryStorageAdapter as MemoryStorageAdapter, type plugins_MemoryStorageAdapterConfig as MemoryStorageAdapterConfig, plugins_PERSIST_PLUGIN_BUILD as PERSIST_PLUGIN_BUILD, type plugins_PersistConfig as PersistConfig, plugins_PersistPlugin as PersistPlugin, type plugins_ReactorPluginConstructor as ReactorPluginConstructor, plugins_StorageAdapter as StorageAdapter, type plugins_StorageAdapterConfig as StorageAdapterConfig, type plugins_StorageAdapterConstructor as StorageAdapterConstructor, plugins_TIME_TRAVEL_PLUGIN_BUILD as TIME_TRAVEL_PLUGIN_BUILD, type plugins_TimeTravelConfig as TimeTravelConfig, plugins_TimeTravelPlugin as TimeTravelPlugin, type plugins_TimeTravelState as TimeTravelState };
1494
+ export { type plugins_AsyncStorageAdapterConstructor as AsyncStorageAdapterConstructor, plugins_BaseReactorPlugin as BaseReactorPlugin, plugins_BaseStorageAdapter as BaseStorageAdapter, type plugins_HistoryEntry as HistoryEntry, plugins_INDEXED_DB_ADAPTER_BUILD as INDEXED_DB_ADAPTER_BUILD, plugins_IndexedDBAdapter as IndexedDBAdapter, type plugins_IndexedDBAdapterConfig as IndexedDBAdapterConfig, plugins_LocalStorageAdapter as LocalStorageAdapter, plugins_MemoryStorageAdapter as MemoryStorageAdapter, type plugins_MemoryStorageAdapterConfig as MemoryStorageAdapterConfig, plugins_PERSIST_PLUGIN_BUILD as PERSIST_PLUGIN_BUILD, type plugins_PersistConfig as PersistConfig, plugins_PersistPlugin as PersistPlugin, type plugins_ReactorPluginConstructor as ReactorPluginConstructor, plugins_StorageAdapter as StorageAdapter, type plugins_StorageAdapterConfig as StorageAdapterConfig, type plugins_StorageAdapterConstructor as StorageAdapterConstructor, plugins_TIME_TRAVEL_PLUGIN_BUILD as TIME_TRAVEL_PLUGIN_BUILD, type TimeTravelConfig$1 as TimeTravelConfig, plugins_TimeTravelPlugin as TimeTravelPlugin, type plugins_TimeTravelState as TimeTravelState };
1482
1495
  }
1483
1496
 
1484
1497
  /**
@@ -1493,12 +1506,52 @@ declare namespace plugins {
1493
1506
  */
1494
1507
  declare function effect(callback: () => void, options?: EffectOptions): () => void;
1495
1508
 
1509
+ /** Reactive options for the TimeTravel overlay instance. */
1510
+ interface TimeTravelConfig {
1511
+ /** Header text shown at the top of the overlay panel. */
1512
+ title: string;
1513
+ /** Accent color used to derive panel theme variables. */
1514
+ color: string;
1515
+ /** Shows the overlay only in development when true. */
1516
+ devOnly: boolean;
1517
+ /** Initial open state applied when the overlay is created. */
1518
+ startOpen: boolean;
1519
+ /** Container element that owns the overlay layer and dock. */
1520
+ container: HTMLElement;
1521
+ }
1522
+ /** Vanilla overlay controller for visual time-travel controls and timeline I/O.
1523
+ * Mounts a docked HUD into the configured container, syncs its UI with plugin state, and forwards keyboard/button actions to the TimeTravelPlugin.
1524
+ * Supports reactive `config` updates (title/color/container/devOnly) and maintains local overlay UI state (`open` and `import` payload text).
1525
+ */
1526
+ declare class TimeTravelOverlay {
1527
+ static count: number;
1528
+ index: number;
1529
+ config: TimeTravelConfig;
1530
+ readonly state: Reactive<{
1531
+ open: boolean;
1532
+ import: string;
1533
+ }, undefined>;
1534
+ readonly time: TimeTravelPlugin;
1535
+ readonly els: Record<string, HTMLElement>;
1536
+ private clups;
1537
+ private keyup?;
1538
+ /** Creates a docked TimeTravel overlay bound to a plugin instance.
1539
+ * @param time TimeTravel plugin instance that owns timeline operations.
1540
+ * @param build Optional initial overlay config overrides.
1541
+ */
1542
+ constructor(time: TimeTravelPlugin, build?: Partial<TimeTravelConfig>);
1543
+ destroy(): void;
1544
+ }
1545
+
1496
1546
  type vanilla_Autotracker<T extends object> = Autotracker<T>;
1497
1547
  declare const vanilla_Autotracker: typeof Autotracker;
1548
+ type vanilla_TimeTravelConfig = TimeTravelConfig;
1549
+ type vanilla_TimeTravelOverlay = TimeTravelOverlay;
1550
+ declare const vanilla_TimeTravelOverlay: typeof TimeTravelOverlay;
1498
1551
  declare const vanilla_effect: typeof effect;
1499
1552
  declare const vanilla_withTracker: typeof withTracker;
1500
1553
  declare namespace vanilla {
1501
- export { vanilla_Autotracker as Autotracker, vanilla_effect as effect, vanilla_withTracker as withTracker };
1554
+ export { vanilla_Autotracker as Autotracker, type vanilla_TimeTravelConfig as TimeTravelConfig, vanilla_TimeTravelOverlay as TimeTravelOverlay, vanilla_effect as effect, vanilla_withTracker as withTracker };
1502
1555
  }
1503
1556
 
1504
1557
  declare const adapters: {