sia-reactor 0.0.21 → 0.0.23

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 +115 -89
  2. package/dist/{TimeTravelOverlay-DxqJL0Zk.d.ts → TimeTravelOverlay-Dglcwpg-.d.ts} +9 -8
  3. package/dist/{TimeTravelOverlay-CJv-S_Km.d.cts → TimeTravelOverlay-OjklzuCD.d.cts} +9 -8
  4. package/dist/adapters/react.cjs +74 -91
  5. package/dist/adapters/react.d.cts +23 -22
  6. package/dist/adapters/react.d.ts +23 -22
  7. package/dist/adapters/react.js +3 -3
  8. package/dist/adapters/vanilla.cjs +74 -91
  9. package/dist/adapters/vanilla.d.cts +4 -4
  10. package/dist/adapters/vanilla.d.ts +4 -4
  11. package/dist/adapters/vanilla.js +3 -3
  12. package/dist/{chunk-TFLYCXK4.js → chunk-5JNWC7Z4.js} +14 -13
  13. package/dist/{chunk-DP74DVRT.js → chunk-MKL3JUPO.js} +55 -15
  14. package/dist/{chunk-2WBPGSRL.js → chunk-MSTHQVNK.js} +61 -78
  15. package/dist/{index-Oie9hhE8.d.cts → index-m0aAWxhX.d.cts} +330 -218
  16. package/dist/{index-Oie9hhE8.d.ts → index-m0aAWxhX.d.ts} +330 -218
  17. package/dist/index.cjs +69 -89
  18. package/dist/index.d.cts +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.js +2 -4
  21. package/dist/{plugins.cjs → modules.cjs} +464 -195
  22. package/dist/modules.d.cts +52 -0
  23. package/dist/modules.d.ts +52 -0
  24. package/dist/modules.js +619 -0
  25. package/dist/super.d.ts +642 -298
  26. package/dist/super.global.js +481 -210
  27. package/dist/timeTravel-DExvNb04.d.ts +352 -0
  28. package/dist/timeTravel-DctvcHVt.d.cts +352 -0
  29. package/dist/utils.cjs +59 -14
  30. package/dist/utils.d.cts +1 -1
  31. package/dist/utils.d.ts +1 -1
  32. package/dist/utils.js +7 -1
  33. package/package.json +6 -6
  34. package/dist/plugins.d.cts +0 -112
  35. package/dist/plugins.d.ts +0 -112
  36. package/dist/plugins.js +0 -370
  37. package/dist/timeTravel-B1vedDQc.d.ts +0 -76
  38. package/dist/timeTravel-WpgWmKu-.d.cts +0 -76
@@ -1,7 +1,7 @@
1
- import { E as EffectOptions, b as Reactor, R as Reactive, o as ReactorBuild, W as WildPaths, q as PathValue } from '../index-Oie9hhE8.js';
1
+ import { E as EffectOptions, R as Reactor, d as Reactive, u as ReactorBuild, W as WildPaths, v as PathValue } from '../index-m0aAWxhX.js';
2
2
  import { useLayoutEffect } from 'react';
3
- import { T as TimeTravelPlugin } from '../timeTravel-B1vedDQc.js';
4
- import { T as TimeTravelConfig } from '../TimeTravelOverlay-DxqJL0Zk.js';
3
+ import { m as TimeTravelModule } from '../timeTravel-DExvNb04.js';
4
+ import { T as TimeTravelConfig } from '../TimeTravelOverlay-Dglcwpg-.js';
5
5
 
6
6
  /**
7
7
  * Subscribes a component to desired Reactor state and returns it.
@@ -12,12 +12,12 @@ import { T as TimeTravelConfig } from '../TimeTravelOverlay-DxqJL0Zk.js';
12
12
  * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
13
13
  * @returns State for render usage if state is scoped locally or just desired.
14
14
  * @example
15
- * const a = useReactor({ user: { name: "Ada" } }); // per-component scoped
15
+ * const a = useReactor({ user: { name: "Kosi" } }); // per-component scoped
16
16
  * @example
17
- * const state = reactive({ user: { name: "Ada" } });
17
+ * const state = reactive({ user: { name: "Kosi" } });
18
18
  * const b = useReactor(state);
19
19
  * @example
20
- * const rtr = new Reactor({ user: { name: "Ada" } });
20
+ * const rtr = new Reactor({ user: { name: "Kosi" } });
21
21
  * const c = useReactor(rtr);
22
22
  */
23
23
  declare function useReactor<T extends object>(target: T | Reactor<T> | Reactive<T>, options?: EffectOptions, build?: ReactorBuild<T>): T;
@@ -39,12 +39,12 @@ declare function useAnyReactor(options?: EffectOptions): void;
39
39
  * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
40
40
  * @returns Tracked snapshot snap for render usage.
41
41
  * @example
42
- * const a = useReactorSnapshot({ user: { name: "Ada" } }); // per-component scoped
42
+ * const a = useReactorSnapshot({ user: { name: "Kosi" } }); // per-component scoped
43
43
  * @example
44
- * const state = reactive({ user: { name: "Ada" } });
44
+ * const state = reactive({ user: { name: "Kosi" } });
45
45
  * const b = useReactorSnapshot(state);
46
46
  * @example
47
- * const rtr = new Reactor({ user: { name: "Ada" } });
47
+ * const rtr = new Reactor({ user: { name: "Kosi" } });
48
48
  * const c = useReactorSnapshot(rtr);
49
49
  */
50
50
  declare function useReactorSnapshot<T extends object>(target: T | Reactor<T> | Reactive<T>, options?: EffectOptions, build?: ReactorBuild<T>): T;
@@ -62,12 +62,12 @@ declare function useReactorSnapshot<T extends object>(target: T | Reactor<T> | R
62
62
  * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
63
63
  * @returns The selected slice.
64
64
  * @example
65
- * const a = useSelector({ user: { name: "Ada" } }, (s) => s.user.name); // per-component scoped
65
+ * const a = useSelector({ user: { name: "Kosi" } }, (s) => s.user.name); // per-component scoped
66
66
  * @example
67
- * const state = reactive({ user: { name: "Ada" } });
67
+ * const state = reactive({ user: { name: "Kosi" } });
68
68
  * const b = useSelector(state, (s) => s.user.name);
69
69
  * @example
70
- * const rtr = new Reactor({ user: { name: "Ada" } });
70
+ * const rtr = new Reactor({ user: { name: "Kosi" } });
71
71
  * const c = useSelector(rtr, (s) => s.user.name);
72
72
  */
73
73
  declare function useSelector<T extends object, R>(target: T | Reactor<T> | Reactive<T>, sel: (state: T) => R, eq?: (prev: R | undefined, next: R) => boolean, options?: EffectOptions, build?: ReactorBuild<T>): R;
@@ -95,12 +95,12 @@ declare function useAnySelector<R>(sel: () => R, eq?: (value1: any, value2: any)
95
95
  * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
96
96
  * @returns The selected slice.
97
97
  * @example
98
- * const a = useSelectorSnapshot({ user: { name: "Ada" } }, (s) => s.user.name); // per-component scoped
98
+ * const a = useSelectorSnapshot({ user: { name: "Kosi" } }, (s) => s.user.name); // per-component scoped
99
99
  * @example
100
- * const state = reactive({ user: { name: "Ada" } });
100
+ * const state = reactive({ user: { name: "Kosi" } });
101
101
  * const b = useSelectorSnapshot(state, (s) => s.user.name);
102
102
  * @example
103
- * const rtr = new Reactor({ user: { name: "Ada" } });
103
+ * const rtr = new Reactor({ user: { name: "Kosi" } });
104
104
  * const c = useSelectorSnapshot(rtr, (s) => s.user.name);
105
105
  */
106
106
  declare function useSelectorSnapshot<T extends object, R>(target: T | Reactor<T> | Reactive<T>, sel: (state: T) => R, eq?: (value1: any, value2: any) => boolean, options?: EffectOptions, build?: ReactorBuild<T>): R;
@@ -116,12 +116,12 @@ declare function useSelectorSnapshot<T extends object, R>(target: T | Reactor<T>
116
116
  * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
117
117
  * @returns Current value at the requested path.
118
118
  * @example
119
- * const a = usePath({ user: { profile: { name: "Ada" } } }, "user.profile.name");
119
+ * const a = usePath({ user: { profile: { name: "Kosi" } } }, "user.profile.name");
120
120
  * @example
121
- * const state = reactive({ user: { profile: { name: "Ada" } } });
121
+ * const state = reactive({ user: { profile: { name: "Kosi" } } });
122
122
  * const b = usePath(state, "user.profile.name");
123
123
  * @example
124
- * const rtr = new Reactor({ user: { profile: { name: "Ada" } } });
124
+ * const rtr = new Reactor({ user: { profile: { name: "Kosi" } } });
125
125
  * const c = usePath(rtr, "user.profile.name");
126
126
  * @example
127
127
  * const wholeState = usePath(state, "*");
@@ -133,11 +133,12 @@ declare const useISOLayoutEffect: typeof useLayoutEffect;
133
133
 
134
134
  /** React props for controlling the vanilla TimeTravel overlay. */
135
135
  interface TimeTravelOverlayProps extends Partial<TimeTravelConfig> {
136
- /** Plugin instance controlled by this overlay bridge. */
137
- time: TimeTravelPlugin;
136
+ /** Module instance controlled by this overlay bridge. */
137
+ time: TimeTravelModule;
138
138
  }
139
- /** React bridge for mounting and controlling a vanilla TimeTravelOverlay instance.
140
- * Instantiates a `TimeTravelOverlay` for the provided plugin, tears it down on unmount, and syncs prop changes into reactive `config`.
139
+ /**
140
+ - React bridge for mounting and controlling a vanilla TimeTravelOverlay instance.
141
+ - Instantiates a `TimeTravelOverlay` for the provided module, tears it down on unmount, and syncs prop changes into reactive `config`.
141
142
  * Use this when your app is React but you want the overlay behavior with react-safe instance lifecycle management.
142
143
  * @param props Overlay bridge props.
143
144
  */
@@ -2,10 +2,10 @@ import {
2
2
  Autotracker,
3
3
  TimeTravelOverlay,
4
4
  withTracker
5
- } from "../chunk-TFLYCXK4.js";
5
+ } from "../chunk-5JNWC7Z4.js";
6
6
  import {
7
7
  getReactor
8
- } from "../chunk-2WBPGSRL.js";
8
+ } from "../chunk-MSTHQVNK.js";
9
9
  import "../chunk-5A44QFT6.js";
10
10
  import "../chunk-P37ADJMM.js";
11
11
  import {
@@ -13,7 +13,7 @@ import {
13
13
  NIL,
14
14
  NOOP,
15
15
  getAny
16
- } from "../chunk-DP74DVRT.js";
16
+ } from "../chunk-MKL3JUPO.js";
17
17
 
18
18
  // src/ts/adapters/react/hooks/useReactor.ts
19
19
  import { useRef, useCallback, useSyncExternalStore, useMemo } from "react";
@@ -31,7 +31,9 @@ module.exports = __toCommonJS(vanilla_exports);
31
31
  var CTX = {
32
32
  /** Flag indicating whether the application is running in development mode. */
33
33
  isDevEnv: "undefined" !== typeof process ? process.env.NODE_ENV !== "production" : true,
34
- /** active `Autotracker` instance, override for automatic dependency collection on `Reactor` traps. */
34
+ /** Flag indicating whether a cascade is currently ongoing so reactors can allow all writes. */
35
+ isCascading: false,
36
+ /** Active `Autotracker` instance, override for automatic dependency collection on `Reactor` traps. */
35
37
  autotracker: null
36
38
  };
37
39
  var RAW = /* @__PURE__ */ Symbol.for("S.I.A_RAW");
@@ -43,14 +45,13 @@ var VERSION = /* @__PURE__ */ Symbol.for("S.I.A_VERSION");
43
45
  var SSVERSION = /* @__PURE__ */ Symbol.for("S.I.A_SNAPSHOT_VERSION");
44
46
  var RTR_BATCH = "undefined" !== typeof window ? ("undefined" !== typeof queueMicrotask ? queueMicrotask : setTimeout).bind(window) : "undefined" !== typeof process && process.nextTick ? process.nextTick : setTimeout;
45
47
  var RTR_LOG = console.log.bind(console, "[S.I.A Reactor]");
46
- var EVT_WARN = console.warn.bind(console, "[S.I.A Event]");
47
48
  var EVT_OPTS = { LISTENER: ["capture", "depth", "once", "signal", "immediate"], MEDIATOR: ["lazy", "signal", "immediate"] };
48
49
  var NIL = Object.freeze({});
49
50
  var NOOP = () => {
50
51
  };
51
52
 
52
53
  // src/ts/utils/obj.ts
53
- var arrRx = /^([^\[\]]+)\[(\d+)\]$/;
54
+ var arrRegex = /^([^\[\]]+)\[(\d+)\]$/;
54
55
  function isObj(obj, arraycheck = true) {
55
56
  return "object" === typeof obj && obj !== null && (arraycheck ? !Array.isArray(obj) : true);
56
57
  }
@@ -58,7 +59,7 @@ function isPOJO(obj, config = NIL, typecheck = true) {
58
59
  return (typecheck ? isObj(obj, false) : true) && (config.crossRealms ? Object.prototype.toString.call(obj) === "[object Object]" : obj.constructor === Object);
59
60
  }
60
61
  function canHandle(obj, config = NIL, typecheck = true) {
61
- if (typecheck && !isObj(obj, false)) return false;
62
+ if (typecheck && !isObj(obj, false) || obj[INERTIA]) return false;
62
63
  if (Array.isArray(obj) || !config.preserveContext && isPOJO(obj, config, false)) return true;
63
64
  if (config.preserveContext) return !(obj instanceof Map) && !(obj instanceof Set) && !(obj instanceof WeakMap) && !(obj instanceof WeakSet) && !(obj instanceof Error) && !(obj instanceof Number) && !(obj instanceof Date) && !(obj instanceof String) && !(obj instanceof RegExp) && !(obj instanceof ArrayBuffer) && !(obj instanceof Promise);
64
65
  return false;
@@ -69,7 +70,7 @@ function getAny(source, key, separator = ".", keyFunc) {
69
70
  const keys2 = key.split(separator);
70
71
  let currObj = source;
71
72
  for (let i = 0, len = keys2.length; i < len; i++) {
72
- const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRx);
73
+ const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRegex);
73
74
  if (match) {
74
75
  const [, key3, iStr] = match;
75
76
  if (!Array.isArray(currObj[key3]) || !(key3 in currObj)) return void 0;
@@ -86,7 +87,7 @@ function setAny(target, key, value, separator = ".", keyFunc) {
86
87
  if (!key.includes(separator)) return void (target[keyFunc ? keyFunc(key) : key] = value);
87
88
  const keys2 = key.split(separator);
88
89
  for (let currObj = target, i = 0, len = keys2.length; i < len; i++) {
89
- const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRx);
90
+ const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRegex);
90
91
  if (match) {
91
92
  const [, key3, iStr] = match;
92
93
  if (!Array.isArray(currObj[key3])) currObj[key3] = [];
@@ -107,7 +108,7 @@ function deleteAny(target, key, separator = ".", keyFunc) {
107
108
  if (!key.includes(separator)) return void delete target[keyFunc ? keyFunc(key) : key];
108
109
  const keys2 = key.split(separator);
109
110
  for (let currObj = target, i = 0, len = keys2.length; i < len; i++) {
110
- const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRx);
111
+ const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRegex);
111
112
  if (match) {
112
113
  const [, key3, iStr] = match;
113
114
  if (!Array.isArray(currObj[key3]) || !(key3 in currObj)) return;
@@ -125,7 +126,7 @@ function inAny(source, key, separator = ".", keyFunc) {
125
126
  if (!key.includes(separator)) return key in source;
126
127
  const keys2 = key.split(separator);
127
128
  for (let currObj = source, i = 0, len = keys2.length; i < len; i++) {
128
- const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRx);
129
+ const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRegex);
129
130
  if (match) {
130
131
  const [, key3, iStr] = match;
131
132
  if (!Array.isArray(currObj[key3]) || !(key3 in currObj)) return false;
@@ -142,10 +143,6 @@ function inAny(source, key, separator = ".", keyFunc) {
142
143
  function parseEvtOpts(options, opts, boolOpt = opts[0], result = {}) {
143
144
  return Object.assign(result, "boolean" === typeof options ? { [boolOpt]: options } : options), result;
144
145
  }
145
- function mergeObjs(o1 = {}, o2 = {}) {
146
- const merged = { ...o1 || {}, ...o2 || {} };
147
- return Object.keys(merged).forEach((k) => isObj(o1?.[k]) && isObj(o2?.[k]) && (merged[k] = mergeObjs(o1[k], o2[k]))), merged;
148
- }
149
146
  function getTrailRecords(obj, path, reverse = false) {
150
147
  const parts = path.split("."), chain = [["*", obj, obj]];
151
148
  for (let acc = "", currObj = obj, i = 0, len = parts.length; i < len; i++) chain.push([acc += (i ? "." : "") + parts[i], currObj, currObj = currObj?.[parts[i]]]);
@@ -269,9 +266,9 @@ var Autotracker = class {
269
266
  * const stop = atrkr.callback(() => console.log("changed")); // re-run after when ".user.name" changes
270
267
  * @example Packaged Customization
271
268
  * const atrkr = new Autotracker(); // no reactor passed
272
- * withTracker(atrkr, () => state.user.name); // import `withTracker` first
269
+ * withTracker(atrkr, () => state.user.name); // import `withTracker` too
273
270
  * const stop = atrkr.callback(() => console.log("sync"), { sync: true }); // re-run immediately when ".user.name" changes, works on any path used from any reactor state
274
- * @example Extensive customization
271
+ * @example Extensive Customization
275
272
  * atrkr.unblock();
276
273
  * const prev = CTX.autotracker;
277
274
  * CTX.autotracker = atrkr; // import CTX first
@@ -340,35 +337,34 @@ var ReactorEvent = class _ReactorEvent {
340
337
  staticType;
341
338
  /** Original event target context. */
342
339
  target;
343
- /** Root reactive object for this event wave. */
340
+ /** Root reactive object for this event instance wave. */
344
341
  root;
345
- /** Original target path for this event wave. */
342
+ /** Original target path for this event instance wave. */
346
343
  path;
347
344
  /** Current value at the event target path. */
348
345
  value;
349
346
  /** Previous value at the event target path. */
350
347
  oldValue;
351
- /** Whether resolve/reject intent semantics are allowed for this event. */
348
+ /** Whether resolve/reject intent semantics are allowed for this event instance. */
352
349
  rejectable;
353
- /** Whether this event wave can bubble back up to ancestors or just capture down. */
350
+ /** Whether this event instance wave can bubble back up to ancestors or just capture down. */
354
351
  bubbles;
355
352
  /**
356
- * `DOMHighResTimeStamp` for this event payload for native event parity and accuracy.
353
+ * `DOMHighResTimeStamp` for this event instance payload for native event parity and accuracy.
357
354
  * Enable `eventTimeStamps` option, then use this over custom timestamps in listeners for accuracy.
358
355
  * */
359
356
  timestamp;
360
- _warn = NOOP;
357
+ /** The `Reactor` instance that dispatched this event instance. */
358
+ reactor;
361
359
  _resolved = "";
362
360
  _rejected = "";
363
361
  _propagationStopped = false;
364
362
  _immediatePropagationStopped = false;
365
363
  /**
366
364
  * @param payload Source payload for this event instance.
367
- * @param bubbles Whether bubbling is enabled for this wave.
368
- * @param canWarn Whether warning output is enabled.
369
- * @param canStamp Whether timestamping is enabled.
365
+ * @param reactor The `Reactor` instance creating this event instance.
370
366
  */
371
- constructor(payload, bubbles = false, canStamp = false, canWarn = true) {
367
+ constructor(payload, reactor) {
372
368
  this.staticType = this.type = payload.type;
373
369
  this.target = payload.target;
374
370
  this.currentTarget = payload.currentTarget;
@@ -377,9 +373,9 @@ var ReactorEvent = class _ReactorEvent {
377
373
  this.value = payload.target.value;
378
374
  this.oldValue = payload.target.oldValue;
379
375
  this.rejectable = payload.rejectable;
380
- this.bubbles = bubbles;
381
- if (canStamp) this.timestamp = performance.now();
382
- if (canWarn) this._warn = EVT_WARN;
376
+ this.bubbles = !!reactor.config.eventBubbling;
377
+ if (reactor.config.eventTimeStamps) this.timestamp = performance.now();
378
+ this.reactor = reactor;
383
379
  }
384
380
  /** Whether propagation has been stopped. */
385
381
  get propagationStopped() {
@@ -409,9 +405,9 @@ var ReactorEvent = class _ReactorEvent {
409
405
  * @example e.resolve("API Load successful"); // message
410
406
  */
411
407
  resolve(message) {
412
- if (!this.rejectable) return this._warn(`[ReactorEvent] Ignored resolve() call on a non-rejectable ${this.staticType} at "${this.path}"`);
413
- if (this.eventPhase !== _ReactorEvent.CAPTURING_PHASE) this._warn(`[ReactorEvent] Resolving an intent on ${this.staticType} at "${this.path}" outside of the capture phase is unadvised.`);
414
- if (this.rejectable) this._resolved = message || `Could ${this.staticType} intended value at "${this.path}"`;
408
+ if (!this.rejectable) return this.reactor.log(`[ReactorEvent] Ignored \`resolve()\` call on a non-rejectable ${this.staticType} at "${this.path}"`);
409
+ if (this.eventPhase !== _ReactorEvent.CAPTURING_PHASE) this.reactor.log(`[ReactorEvent] Resolving an intent on ${this.staticType} at "${this.path}" outside of the capture phase is unadvised.`);
410
+ if (this.rejectable) this.reactor.log(`[ReactorEvent] ${this._resolved = message || `Could ${this.staticType} intended value at "${this.path}"`}`);
415
411
  }
416
412
  /** Rejection reason for rejectable events. */
417
413
  get rejected() {
@@ -424,9 +420,9 @@ var ReactorEvent = class _ReactorEvent {
424
420
  * @example e.resolve("User is not logged in"); // reason
425
421
  */
426
422
  reject(reason) {
427
- if (!this.rejectable) return this._warn(`[ReactorEvent] Ignored reject() call on a non-rejectable ${this.staticType} at "${this.path}"`);
428
- if (this.eventPhase !== _ReactorEvent.CAPTURING_PHASE) this._warn(`[ReactorEvent] Rejecting an intent on ${this.staticType} at "${this.path}" outside of the capture phase is unadvised.`);
429
- if (this.rejectable) this._rejected = reason || `Couldn't ${this.staticType} intended value at "${this.path}"`;
423
+ if (!this.rejectable) return this.reactor.log(`[ReactorEvent] Ignored \`reject()\` call on a non-rejectable ${this.staticType} at "${this.path}"`);
424
+ if (this.eventPhase !== _ReactorEvent.CAPTURING_PHASE) this.reactor.log(`[ReactorEvent] Rejecting an intent on ${this.staticType} at "${this.path}" outside of the capture phase is unadvised.`);
425
+ if (this.rejectable) this.reactor.log(`[ReactorEvent] ${this._rejected = reason || `Couldn't ${this.staticType} intended value at "${this.path}"`}`);
430
426
  }
431
427
  /**
432
428
  * Returns event path values from target to root.
@@ -435,24 +431,22 @@ var ReactorEvent = class _ReactorEvent {
435
431
  composedPath() {
436
432
  return getTrailRecords(this.root, this.path, true).map((r) => r[2]);
437
433
  }
438
- get canWarn() {
439
- return this._warn !== NOOP;
440
- }
441
434
  };
442
435
 
443
436
  // src/ts/core/reactor.ts
444
437
  var Reactor = class {
438
+ /** Logger function for this reactor instance, override if desired, `this.canLog = false` resets. */
445
439
  log = NOOP;
440
+ /** The core state object for this reactor instance. */
446
441
  core;
447
442
  // `?:`s | pay the ~800 byte price upfront for what u might never use
448
- plugins;
443
+ /** The modules being used by this reactor. */
444
+ modules;
445
+ /** Configuration options for this reactor instance. */
449
446
  config;
447
+ /** Whether this reactor instance is currently batching updates, a window view into the engine timing */
450
448
  isBatching = false;
451
449
  // Async Batching
452
- isCascading = false;
453
- // Setter Cascading
454
- isLogging = false;
455
- // keeping track so API getter doesn't slow down internal iterations in any way
456
450
  queue;
457
451
  // Tasks to run after flush
458
452
  batch;
@@ -485,7 +479,7 @@ var Reactor = class {
485
479
  if (this.config.referenceTracking && parent && key && !this.link(target, parent, key, false)) return target;
486
480
  const cached = this.proxyCache.get(target);
487
481
  if (cached) return cached;
488
- if (target[INERTIA] || !canHandle(target, this.config, false)) return target;
482
+ if (!canHandle(target, this.config, false)) return target;
489
483
  rejectable ||= target[REJECTABLE];
490
484
  indiffable ||= target[INDIFFABLE];
491
485
  const proxy = new Proxy(target, {
@@ -519,7 +513,7 @@ var Reactor = class {
519
513
  safeValue = value?.[RAW] || value;
520
514
  unchanged = this.config.equalityFunction(safeValue, safeOldValue);
521
515
  }
522
- if (!indiffable && unchanged && !this.isCascading) return this.log(`\u{1F504} [Reactor \`set\` Trap] Unchanged for "${keyStr}" on "${paths}"`), true;
516
+ if (!indiffable && unchanged && !CTX.isCascading) return this.log(`\u{1F504} [Reactor \`set\` Trap] Unchanged for "${keyStr}" on "${paths}"`), true;
523
517
  if (this.config.set) terminated = (value = this.config.set(object, key2, value, oldValue, receiver, paths)) === TERMINATOR;
524
518
  if (this.setters) {
525
519
  const wildcords = this.setters.get("*");
@@ -673,7 +667,7 @@ var Reactor = class {
673
667
  if (this.queue?.size) for (const task of this.queue) task(), this.queue.delete(task);
674
668
  }
675
669
  wave(path, payload) {
676
- const e = new ReactorEvent(payload, this.config.eventBubbling, this.config.eventTimeStamps, this.isLogging), chain = getTrailRecords(this.core, path);
670
+ const e = new ReactorEvent(payload, this), chain = getTrailRecords(this.core, path);
677
671
  e.eventPhase = ReactorEvent.CAPTURING_PHASE;
678
672
  for (let i = 0; i <= chain.length - 2; i++) {
679
673
  if (e.propagationStopped) break;
@@ -747,8 +741,8 @@ var Reactor = class {
747
741
  return depth;
748
742
  }
749
743
  getContext(path) {
750
- const lastDot = path.lastIndexOf("."), value = getAny(this.core, path), object = lastDot === -1 ? this.core : getAny(this.core, path.slice(0, lastDot));
751
- return { path, value, key: path.slice(lastDot + 1) || "", hadKey: true, object };
744
+ const last = path.lastIndexOf("."), value = getAny(this.core, path), object = last === -1 ? this.core : getAny(this.core, path.slice(0, last));
745
+ return { path, value, key: path.slice(last + 1) || "", hadKey: true, object };
752
746
  }
753
747
  bindSignal(cord, sig) {
754
748
  if (sig) sig.aborted ? cord.clup() : sig.addEventListener("abort", cord.clup, { once: true });
@@ -764,7 +758,12 @@ var Reactor = class {
764
758
  const clone = !raw ? this.config.preserveContext ? Object.create(Object.getPrototypeOf(obj)) : Array.isArray(obj) ? [] : {} : obj;
765
759
  seen.set(obj, clone);
766
760
  const keys2 = this.config.preserveContext ? Reflect.ownKeys(obj) : Object.keys(obj);
767
- for (let i = 0, len = keys2.length; i < len; i++) clone[keys2[i]] = this.cloned(obj[keys2[i]], raw, seen);
761
+ for (let i = 0, len = keys2.length; i < len; i++)
762
+ try {
763
+ clone[keys2[i]] = this.cloned(obj[keys2[i]], raw, seen);
764
+ } catch (e) {
765
+ if (e instanceof RangeError) throw e;
766
+ }
768
767
  if (!raw && this.config.smartCloning) this.snapCache.set(obj, clone), obj[SSVERSION] = version;
769
768
  return clone;
770
769
  }
@@ -852,7 +851,7 @@ var Reactor = class {
852
851
  * rtr.delete("cache.temp", () => TERMINATOR);
853
852
  */
854
853
  delete(path, callback, options) {
855
- return this.syncAdd("delete", path, callback, options, (imm) => (imm !== "auto" || inAny(this.core, path)) && deleteAny(this.core, path, void 0));
854
+ return this.syncAdd("delete", path, callback, options, (imm) => (imm !== "auto" || inAny(this.core, path)) && deleteAny(this.core, path));
856
855
  }
857
856
  /** Registers a delete mediator for a path that only triggers once. */
858
857
  donce(path, callback, options) {
@@ -869,7 +868,7 @@ var Reactor = class {
869
868
  }
870
869
  /**
871
870
  * Registers a watcher for a path.
872
- * Watch callbacks run synchronously with the operation.
871
+ * Watch callbacks run synchronously with the operation, use leaf paths for reliability as it sees exact sets; no bubbling here.
873
872
  * @param path Path or wildcard path.
874
873
  * @param callback Watch callback.
875
874
  * @param options Sync options.
@@ -918,7 +917,7 @@ var Reactor = class {
918
917
  cord = { cb: callback, capture, depth, once, clup: () => this.off(path, callback, options), lDepth: depth !== void 0 ? this.getDepth(path) : depth };
919
918
  if (immediate && (immediate !== "auto" || inAny(this.core, path))) {
920
919
  const target = this.getContext(path);
921
- callback(new ReactorEvent({ type: "init", target, currentTarget: target, root: this.core, rejectable: false }, this.config.eventBubbling, this.isLogging));
920
+ callback(new ReactorEvent({ type: "init", target, currentTarget: target, root: this.core, rejectable: false }, this));
922
921
  }
923
922
  (cords ?? (this.listeners.set(path, cords = []), cords)).push(cord);
924
923
  return this.bindSignal(cord, signal);
@@ -949,56 +948,39 @@ var Reactor = class {
949
948
  return this.cloned(arguments.length < 2 ? this.core : branch, raw);
950
949
  }
951
950
  /**
952
- * Cascades object updates into direct child paths.
953
- * @param payload Event or payload source.
954
- * @param objectSafe Merge old/new object values before cascading, don't set for arrays; merger doesn't play nice
955
- * @example
956
- * rtr.on("user", (event) => rtr.cascade(event));
957
- * @example
958
- * rtr.watch("user", (_value, payload) => rtr.cascade(payload));
959
- */
960
- cascade({ type, currentTarget: { path, value: news, oldValue: olds } }, objectSafe = true) {
961
- if (type !== "set" && type !== "delete" || !canHandle(news, this.config) || (objectSafe ? !canHandle(olds, this.config) : false)) return;
962
- const obj = objectSafe ? mergeObjs(olds, news) : news, keys2 = Object.keys(obj);
963
- this.isCascading = true;
964
- for (let i = 0, len = keys2.length; i < len; i++) setAny(this.core, path === "*" ? keys2[i] : path + "." + keys2[i], obj[keys2[i]]);
965
- this.isCascading = false;
966
- }
967
- /**
968
- * Installs a plugin instance.
969
- * @param plugin Plugin instance.
970
- * @returns Current reactor for fluent chaining.
951
+ * Installs a module instance.
952
+ * @param target Module instance.
953
+ * @param id Optional identification tag for this instance in the module.
954
+ * @returns Current `Reactor` instance for fluent chaining.
971
955
  */
972
- plugIn(plugin) {
973
- const name = plugin.constructor.plugName;
974
- this.plugins?.get(name)?.destroy();
975
- return (this.plugins ??= /* @__PURE__ */ new Map()).set(name, (plugin.setup(this), plugin)), this;
956
+ use(target, id) {
957
+ return (this.modules ??= /* @__PURE__ */ new Set()).add(target.setup(this, id)), this;
976
958
  }
977
- /** Resets the reactor to its initial state. */
959
+ /** Resets this reactor instance to its initial state. */
978
960
  reset() {
979
961
  this.getters?.clear(), this.setters?.clear(), this.deleters?.clear(), this.watchers?.clear(), this.listeners?.clear();
980
962
  this.batch?.clear(), this.queue?.clear(), this.isBatching = false;
981
963
  }
982
964
  destroy() {
983
- if (this.plugins) for (const plug of this.plugins.values()) plug.destroy();
965
+ if (this.modules) for (const mdle of this.modules) mdle.destroy();
984
966
  this.reset(), nuke(this);
985
967
  }
986
968
  get canLog() {
987
- return this.isLogging = this.log !== NOOP;
969
+ return this.log !== NOOP;
988
970
  }
989
971
  set canLog(value) {
990
- this.log = (this.isLogging = value) ? RTR_LOG : NOOP;
972
+ this.log = value ? RTR_LOG : NOOP;
991
973
  }
992
- get canTraceLineage() {
993
- return this.config.referenceTracking && !!this.config.lineageTracing;
974
+ get canLineageTrace() {
975
+ return this.config.lineageTracing && this.config.referenceTracking;
994
976
  }
995
977
  get canSmartClone() {
996
- return this.config.referenceTracking && !!this.config.smartCloning;
978
+ return this.config.smartCloning && this.config.referenceTracking;
997
979
  }
998
980
  };
999
981
 
1000
982
  // src/ts/core/mixins.ts
1001
- var methods = ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "snapshot", "cascade", "plugIn", "reset", "destroy"];
983
+ var methods = ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "snapshot", "use", "reset", "destroy"];
1002
984
  function reactive(target, build, preferences = NIL) {
1003
985
  if ("__Reactor__" in target) return target;
1004
986
  const descriptors = {}, rtr = getReactor(target, true, build), locks = { enumerable: false, configurable: true, writable: false }, hasAffix = !!(preferences.prefix || preferences.suffix);
@@ -1006,7 +988,7 @@ function reactive(target, build, preferences = NIL) {
1006
988
  let key = methods[i];
1007
989
  if (hasAffix) (preferences.whitelist?.includes(key) ?? true) && (key = `${preferences.prefix || ""}${key}${preferences.suffix || ""}`);
1008
990
  else if (preferences.whitelist?.includes(key)) continue;
1009
- descriptors[key] = { value: rtr[key].bind(rtr), ...locks };
991
+ descriptors[key] = { value: rtr[methods[i]].bind(rtr), ...locks };
1010
992
  }
1011
993
  descriptors["__Reactor__"] = { value: rtr, ...locks };
1012
994
  return Object.defineProperties(rtr.core, descriptors), rtr.core;
@@ -1088,8 +1070,8 @@ function assignEl(el, props, dataset, styles) {
1088
1070
 
1089
1071
  // src/ts/adapters/vanilla/TimeTravelOverlay.ts
1090
1072
  var keys = {
1091
- overrides: ["Ctrl+z", "Cmd+z", "Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z", "Ctrl+g", "Cmd+g", ",", ".", "ArrowLeft", "ArrowRight", "Space", "Alt+Space", "Escape", "Delete", "e", "i", "c"],
1092
- shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: ["Ctrl+g", "Cmd+g"], prevFrame: ",", nextFrame: ".", skipBwd: "ArrowLeft", skipFwd: "ArrowRight", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
1073
+ overrides: ["Ctrl+z", "Cmd+z", "Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z", "Home", "End", ",", ".", "ArrowLeft", "ArrowRight", "Space", "Alt+Space", "Escape", "Delete", "e", "i", "c"],
1074
+ shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: "Home", ending: "End", prevFrame: ",", nextFrame: ".", skipBwd: "ArrowLeft", skipFwd: "ArrowRight", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
1093
1075
  };
1094
1076
  var TimeTravelOverlay = class _TimeTravelOverlay {
1095
1077
  static count = 0;
@@ -1100,22 +1082,22 @@ var TimeTravelOverlay = class _TimeTravelOverlay {
1100
1082
  els;
1101
1083
  clups = [];
1102
1084
  keyup;
1103
- /** Creates a docked TimeTravel overlay bound to a plugin instance.
1104
- * @param time TimeTravel plugin instance that owns timeline operations.
1085
+ /** Creates a docked TimeTravel overlay bound to a module instance.
1086
+ * @param time TimeTravel module instance that owns timeline operations.
1105
1087
  * @param build Optional initial overlay config overrides.
1106
1088
  */
1107
1089
  constructor(time, build = {}) {
1108
1090
  this.time = time;
1109
1091
  this.config = reactive({ title: `Time Travel Overlay ${this.index = ++_TimeTravelOverlay.count}`, ...build });
1110
1092
  this.state.open = !!this.config.startOpen;
1111
- const s = this.time.state, host = createEl("div", { className: "tt-overlay-host" }), toggle = createEl("button", { className: "tt-overlay-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "tt-overlay", ariaLabel: "time travel overlay" }), title = createEl("div", { className: "title" }), frame = createEl("span", { className: "muted" }), clrHistory = createEl("button", { textContent: `Clear History${formatKeyForDisplay(keys.shortcuts.clrHistory)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clrHistory, false), onclick: () => (this.time.clear(), this.state.import = "") }), undo = createEl("button", { textContent: `Undo${formatKeyForDisplay(keys.shortcuts.undo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.undo, false), onclick: this.time.undo }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: this.time.redo }), genesis = createEl("button", { textContent: `Genesis${formatKeyForDisplay(keys.shortcuts.genesis[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.genesis, false), onclick: () => this.time.jumpTo(0) }), playPause = createEl("button", { onclick: () => this.time[s.paused ? "play" : "pause"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.playPause, false) }), rewind = createEl("button", { textContent: `Rewind${formatKeyForDisplay(keys.shortcuts.rewind)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.rewind, false), onclick: this.time.rewind }), range = createEl("input", { type: "range", min: "0", max: "0", value: "0", title: "time travel frame", ariaLabel: "time travel frame", oninput: () => this.time.jumpTo(Number(range.value)) }), exp = createEl("button", { textContent: `Export${formatKeyForDisplay(keys.shortcuts.export)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.export, false), onclick: () => this.state.import = this.time.export(null, 2) }), imp = createEl("button", { textContent: `Import${formatKeyForDisplay(keys.shortcuts.import)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.import, false), onclick: () => this.state.import.trim().length && this.time.import(this.state.import) }), clr = createEl("button", { textContent: `Clear${formatKeyForDisplay(keys.shortcuts.clear)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clear, false), onclick: () => this.state.import = "" }), payload = createEl("textarea", { className: "tt-io", readOnly: true, placeholder: "current payload json", title: "current payload" }), io = createEl("textarea", { className: "tt-io", placeholder: "timeline payload json", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "tt-footnote", textContent: "Want this in your app? " }), link = createEl("a", { target: "_blank", rel: "noreferrer noopener", textContent: "sia-reactor", href: "https://www.npmjs.com/package/sia-reactor" }), box = createEl("div", { className: "tt-status-box" }), status = createEl("div", { className: "tt-status-row" }), row1 = createEl("div", { className: "tt-row" }), row2 = createEl("div", { className: "tt-row" }), row3 = createEl("div", { className: "tt-row" });
1093
+ const s = this.time.state, host = createEl("div", { className: "tt-overlay-host" }), toggle = createEl("button", { className: "tt-overlay-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "tt-overlay", ariaLabel: "time travel overlay" }), title = createEl("div", { className: "title" }), frame = createEl("span", { className: "muted" }), clrHistory = createEl("button", { textContent: `Clear History${formatKeyForDisplay(keys.shortcuts.clrHistory)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clrHistory, false), onclick: () => (this.time.clear(), this.state.import = "") }), undo = createEl("button", { textContent: `Undo${formatKeyForDisplay(keys.shortcuts.undo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.undo, false), onclick: this.time.undo }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: this.time.redo }), genesis = createEl("button", { textContent: `Genesis${formatKeyForDisplay(keys.shortcuts.genesis)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.genesis, false), onclick: () => this.time.jumpTo(0) }), playPause = createEl("button", { onclick: () => this.time[s.paused ? "play" : "pause"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.playPause, false) }), rewind = createEl("button", { textContent: `Rewind${formatKeyForDisplay(keys.shortcuts.rewind)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.rewind, false), onclick: this.time.rewind }), range = createEl("input", { type: "range", min: "0", max: "0", value: "0", title: "time travel frame", ariaLabel: "time travel frame", oninput: () => this.time.jumpTo(Number(range.value)) }), exp = createEl("button", { textContent: `Export${formatKeyForDisplay(keys.shortcuts.export)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.export, false), onclick: () => this.state.import = this.time.export(null, 2) }), imp = createEl("button", { textContent: `Import${formatKeyForDisplay(keys.shortcuts.import)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.import, false), onclick: () => this.state.import.trim().length && this.time.import(this.state.import) }), clr = createEl("button", { textContent: `Clear${formatKeyForDisplay(keys.shortcuts.clear)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clear, false), onclick: () => this.state.import = "" }), payload = createEl("textarea", { className: "tt-io", readOnly: true, placeholder: "current payload json", title: "current payload" }), io = createEl("textarea", { className: "tt-io", placeholder: "timeline payload json", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "tt-footnote", textContent: "Want this in your app? " }), link = createEl("a", { target: "_blank", rel: "noreferrer noopener", textContent: "sia-reactor", href: "https://www.npmjs.com/package/sia-reactor" }), box = createEl("div", { className: "tt-status-box" }), status = createEl("div", { className: "tt-status-row" }), row1 = createEl("div", { className: "tt-row" }), row2 = createEl("div", { className: "tt-row" }), row3 = createEl("div", { className: "tt-row" });
1112
1094
  status.append((box.append(frame), box), clrHistory);
1113
1095
  panel.append(title, status, (row1.append(undo, redo, genesis), row1), (row2.append(playPause, rewind), row2), payload, range, (row3.append(exp, imp, clr), row3), io, (foot.appendChild(link), foot));
1114
1096
  host.append(toggle, panel);
1115
1097
  this.els = { host, toggle, panel, title, frame, clrHistory, undo, redo, genesis, playPause, rewind, range, exp, imp, clr, payload, io };
1116
1098
  this.keyup = (e) => {
1117
- const a = this.state.open && keyEventAllowed(e, keys);
1118
- a === "undo" ? this.time.undo() : a === "redo" ? this.time.redo() : a === "genesis" ? this.time.jumpTo(0) : a === "prevFrame" ? this.time.step(1, false) : a === "nextFrame" ? this.time.step(1, true) : a === "skipBwd" ? this.time.step(5, false) : a === "skipFwd" ? this.time.step(5, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = "");
1099
+ const a = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true) && keyEventAllowed(e, keys);
1100
+ a === "undo" ? this.time.undo() : a === "redo" ? this.time.redo() : a === "genesis" ? this.time.jumpTo(0) : a === "ending" ? this.time.jumpTo(s.history.length) : a === "prevFrame" ? this.time.step(1, false) : a === "nextFrame" ? this.time.step(1, true) : a === "skipBwd" ? this.time.step(5, false) : a === "skipFwd" ? this.time.step(5, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = "");
1119
1101
  };
1120
1102
  window.addEventListener("keydown", this.keyup);
1121
1103
  const sync = [
@@ -1130,7 +1112,8 @@ var TimeTravelOverlay = class _TimeTravelOverlay {
1130
1112
  effect(() => {
1131
1113
  frame.textContent = `Frame: ${s.currentFrame} / ${s.history.length}`;
1132
1114
  range.disabled = clrHistory.disabled = !s.history.length;
1133
- genesis.disabled = rewind.disabled = undo.disabled = !s.currentFrame;
1115
+ genesis.disabled = undo.disabled = !s.currentFrame;
1116
+ rewind.disabled = !s.paused || !s.currentFrame;
1134
1117
  playPause.disabled = redo.disabled = s.currentFrame >= s.history.length;
1135
1118
  range.max = String(s.history.length);
1136
1119
  range.value = String(Math.min(s.currentFrame, s.history.length));
@@ -1144,7 +1127,7 @@ var TimeTravelOverlay = class _TimeTravelOverlay {
1144
1127
  this.clups.push(...sync);
1145
1128
  }
1146
1129
  destroy() {
1147
- this.clups.forEach((fn) => fn());
1130
+ for (const clup of this.clups) clup();
1148
1131
  this.keyup && window.removeEventListener("keydown", this.keyup);
1149
1132
  this.els.host.remove();
1150
1133
  nuke(this), --_TimeTravelOverlay.count;
@@ -1,7 +1,7 @@
1
- import { E as EffectOptions } from '../index-Oie9hhE8.cjs';
2
- export { A as Autotracker, w as withTracker } from '../index-Oie9hhE8.cjs';
3
- export { T as TimeTravelConfig, a as TimeTravelOverlay } from '../TimeTravelOverlay-CJv-S_Km.cjs';
4
- import '../timeTravel-WpgWmKu-.cjs';
1
+ import { E as EffectOptions } from '../index-m0aAWxhX.cjs';
2
+ export { A as Autotracker, w as withTracker } from '../index-m0aAWxhX.cjs';
3
+ export { T as TimeTravelConfig, a as TimeTravelOverlay } from '../TimeTravelOverlay-OjklzuCD.cjs';
4
+ import '../timeTravel-DctvcHVt.cjs';
5
5
 
6
6
  /**
7
7
  * Runs a reactive side effect in vanilla JavaScript.
@@ -1,7 +1,7 @@
1
- import { E as EffectOptions } from '../index-Oie9hhE8.js';
2
- export { A as Autotracker, w as withTracker } from '../index-Oie9hhE8.js';
3
- export { T as TimeTravelConfig, a as TimeTravelOverlay } from '../TimeTravelOverlay-DxqJL0Zk.js';
4
- import '../timeTravel-B1vedDQc.js';
1
+ import { E as EffectOptions } from '../index-m0aAWxhX.js';
2
+ export { A as Autotracker, w as withTracker } from '../index-m0aAWxhX.js';
3
+ export { T as TimeTravelConfig, a as TimeTravelOverlay } from '../TimeTravelOverlay-Dglcwpg-.js';
4
+ import '../timeTravel-DExvNb04.js';
5
5
 
6
6
  /**
7
7
  * Runs a reactive side effect in vanilla JavaScript.
@@ -3,11 +3,11 @@ import {
3
3
  TimeTravelOverlay,
4
4
  effect,
5
5
  withTracker
6
- } from "../chunk-TFLYCXK4.js";
7
- import "../chunk-2WBPGSRL.js";
6
+ } from "../chunk-5JNWC7Z4.js";
7
+ import "../chunk-MSTHQVNK.js";
8
8
  import "../chunk-5A44QFT6.js";
9
9
  import "../chunk-P37ADJMM.js";
10
- import "../chunk-DP74DVRT.js";
10
+ import "../chunk-MKL3JUPO.js";
11
11
  export {
12
12
  Autotracker,
13
13
  TimeTravelOverlay,