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
@@ -0,0 +1,76 @@
1
+ import { a as REvent, P as Paths, B as BaseReactorPlugin, b as Reactor } from './index-Oie9hhE8.js';
2
+
3
+ /** The DNA of a specific moment in time, Records the 'Desire' (Intent) or the 'Fact' (State). */
4
+ interface HistoryEntry {
5
+ /** The surgical address in the Reactor */
6
+ path: string;
7
+ /** The data payload at that moment */
8
+ value: any;
9
+ /** The "Undo" antidote (Previous value), if applicable */
10
+ oldValue: any;
11
+ /** Was it a 'set' or a 'delete' surgery? */
12
+ type: REvent<any, any>["staticType"];
13
+ /** Did the Power Line disapprove?; why? */
14
+ rejected: string;
15
+ /** For chronological re-enactment */
16
+ timedelta: number;
17
+ /** Did the key for the value exist on its parent object? */
18
+ hadKey: boolean;
19
+ }
20
+ interface TimeTravelConfig<T extends object = any> {
21
+ /** Specific paths only, no "*"; instead don't pass anything */
22
+ paths?: Paths<T>[];
23
+ /** Maximum number of history entries to keep (Memory Cap), you lose replaying Sessions or the Genesis */
24
+ maxHistoryLength: number;
25
+ /** Max delay between events during playback (ms) */
26
+ maxPlaybackDelay: number;
27
+ }
28
+ interface TimeTravelState {
29
+ /** The "Genesis" snapshot (Raw Data) */
30
+ initialState: any;
31
+ /** The "Timeline" of mutations (Chronological Log) */
32
+ history: HistoryEntry[];
33
+ /** The manual playhead (Index in the Timeline) */
34
+ currentFrame: number;
35
+ /** Whether playback is currently paused (Automatic Replay) */
36
+ paused: boolean;
37
+ }
38
+ /**
39
+ * The Flight Recorder (Black Box).
40
+ * - Implements S.I.A. logic to allow playback, teleportation, redos and undos.
41
+ */
42
+ declare class TimeTravelPlugin<T extends object = any> extends BaseReactorPlugin<T, TimeTravelConfig<T>, TimeTravelState> {
43
+ static readonly plugName = "timeTravel";
44
+ protected lastTimestamp: number;
45
+ protected playbackTimeoutId: number;
46
+ constructor(config?: Partial<TimeTravelConfig<T>>, rtr?: Reactor<T>);
47
+ wire(): void;
48
+ protected handlePathsState({ value: paths, oldValue: prevs }: REvent<TimeTravelConfig<T>, "paths">): void;
49
+ /** Chronicling the lifecycle of the system, Captures the essence of every mutation wave that bubbles up. */
50
+ protected record(e: REvent<T, any>): void;
51
+ /** Clears timeline history and resets playhead/genesis to the current reactor state. */
52
+ clear(): void;
53
+ /** Instant state reconstruction (Teleport). Glides through deltas natively. */
54
+ jumpTo(index?: number, keepShield?: boolean): void;
55
+ /** Step through time, Moves the playhead and teleports the state. */
56
+ step(stride?: number, forward?: boolean): void;
57
+ /** Step back in time, Moves the playhead backward and teleports the state. */
58
+ undo: () => void;
59
+ /** Step forward in time, Restores previously undone actions. */
60
+ redo: () => void;
61
+ /** Core automove engine. Replays or rewinds the "Story" by respecting time gaps. */
62
+ automove(forward?: boolean): Promise<void>;
63
+ /** Start chronological re-enactment of the session. */
64
+ play: () => Promise<void>;
65
+ /** Start reverse chronological re-enactment of the session. */
66
+ rewind: () => Promise<void>;
67
+ /** Pauses the live VCR playback. */
68
+ pause: () => void;
69
+ /** Exports the current session as a JSON string. */
70
+ export(replacer?: ((this: any, key: string, value: any) => any) | (number | string)[] | null, space?: string | number): string;
71
+ /** Imports a session from a JSON string, allowing you to replay or analyze past states. */
72
+ import(json: string): void;
73
+ }
74
+ declare const TIME_TRAVEL_PLUGIN_BUILD: Partial<TimeTravelConfig>;
75
+
76
+ export { type HistoryEntry as H, TimeTravelPlugin as T, TIME_TRAVEL_PLUGIN_BUILD as a, type TimeTravelConfig as b, type TimeTravelState as c };
@@ -0,0 +1,76 @@
1
+ import { a as REvent, P as Paths, B as BaseReactorPlugin, b as Reactor } from './index-Oie9hhE8.cjs';
2
+
3
+ /** The DNA of a specific moment in time, Records the 'Desire' (Intent) or the 'Fact' (State). */
4
+ interface HistoryEntry {
5
+ /** The surgical address in the Reactor */
6
+ path: string;
7
+ /** The data payload at that moment */
8
+ value: any;
9
+ /** The "Undo" antidote (Previous value), if applicable */
10
+ oldValue: any;
11
+ /** Was it a 'set' or a 'delete' surgery? */
12
+ type: REvent<any, any>["staticType"];
13
+ /** Did the Power Line disapprove?; why? */
14
+ rejected: string;
15
+ /** For chronological re-enactment */
16
+ timedelta: number;
17
+ /** Did the key for the value exist on its parent object? */
18
+ hadKey: boolean;
19
+ }
20
+ interface TimeTravelConfig<T extends object = any> {
21
+ /** Specific paths only, no "*"; instead don't pass anything */
22
+ paths?: Paths<T>[];
23
+ /** Maximum number of history entries to keep (Memory Cap), you lose replaying Sessions or the Genesis */
24
+ maxHistoryLength: number;
25
+ /** Max delay between events during playback (ms) */
26
+ maxPlaybackDelay: number;
27
+ }
28
+ interface TimeTravelState {
29
+ /** The "Genesis" snapshot (Raw Data) */
30
+ initialState: any;
31
+ /** The "Timeline" of mutations (Chronological Log) */
32
+ history: HistoryEntry[];
33
+ /** The manual playhead (Index in the Timeline) */
34
+ currentFrame: number;
35
+ /** Whether playback is currently paused (Automatic Replay) */
36
+ paused: boolean;
37
+ }
38
+ /**
39
+ * The Flight Recorder (Black Box).
40
+ * - Implements S.I.A. logic to allow playback, teleportation, redos and undos.
41
+ */
42
+ declare class TimeTravelPlugin<T extends object = any> extends BaseReactorPlugin<T, TimeTravelConfig<T>, TimeTravelState> {
43
+ static readonly plugName = "timeTravel";
44
+ protected lastTimestamp: number;
45
+ protected playbackTimeoutId: number;
46
+ constructor(config?: Partial<TimeTravelConfig<T>>, rtr?: Reactor<T>);
47
+ wire(): void;
48
+ protected handlePathsState({ value: paths, oldValue: prevs }: REvent<TimeTravelConfig<T>, "paths">): void;
49
+ /** Chronicling the lifecycle of the system, Captures the essence of every mutation wave that bubbles up. */
50
+ protected record(e: REvent<T, any>): void;
51
+ /** Clears timeline history and resets playhead/genesis to the current reactor state. */
52
+ clear(): void;
53
+ /** Instant state reconstruction (Teleport). Glides through deltas natively. */
54
+ jumpTo(index?: number, keepShield?: boolean): void;
55
+ /** Step through time, Moves the playhead and teleports the state. */
56
+ step(stride?: number, forward?: boolean): void;
57
+ /** Step back in time, Moves the playhead backward and teleports the state. */
58
+ undo: () => void;
59
+ /** Step forward in time, Restores previously undone actions. */
60
+ redo: () => void;
61
+ /** Core automove engine. Replays or rewinds the "Story" by respecting time gaps. */
62
+ automove(forward?: boolean): Promise<void>;
63
+ /** Start chronological re-enactment of the session. */
64
+ play: () => Promise<void>;
65
+ /** Start reverse chronological re-enactment of the session. */
66
+ rewind: () => Promise<void>;
67
+ /** Pauses the live VCR playback. */
68
+ pause: () => void;
69
+ /** Exports the current session as a JSON string. */
70
+ export(replacer?: ((this: any, key: string, value: any) => any) | (number | string)[] | null, space?: string | number): string;
71
+ /** Imports a session from a JSON string, allowing you to replay or analyze past states. */
72
+ import(json: string): void;
73
+ }
74
+ declare const TIME_TRAVEL_PLUGIN_BUILD: Partial<TimeTravelConfig>;
75
+
76
+ export { type HistoryEntry as H, TimeTravelPlugin as T, TIME_TRAVEL_PLUGIN_BUILD as a, type TimeTravelConfig as b, type TimeTravelState as c };
package/dist/utils.cjs CHANGED
@@ -17,13 +17,15 @@ var __copyProps = (to, from, except, desc) => {
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
- // src/utils.ts
20
+ // src/ts/utils.ts
21
21
  var utils_exports = {};
22
22
  __export(utils_exports, {
23
+ assignEl: () => assignEl,
23
24
  bindAllMethods: () => bindAllMethods,
24
25
  canHandle: () => canHandle,
25
26
  clamp: () => clamp,
26
27
  cleanKeyCombo: () => cleanKeyCombo,
28
+ createEl: () => createEl,
27
29
  deepClone: () => deepClone,
28
30
  deleteAny: () => deleteAny,
29
31
  formatKeyForDisplay: () => formatKeyForDisplay,
@@ -53,13 +55,19 @@ __export(utils_exports, {
53
55
  });
54
56
  module.exports = __toCommonJS(utils_exports);
55
57
 
56
- // src/core/consts.ts
58
+ // src/ts/core/consts.ts
59
+ var CTX = {
60
+ /** Flag indicating whether the application is running in development mode. */
61
+ isDevEnv: "undefined" !== typeof process ? process.env.NODE_ENV !== "production" : true,
62
+ /** active `Autotracker` instance, override for automatic dependency collection on `Reactor` traps. */
63
+ autotracker: null
64
+ };
57
65
  var RTR_BATCH = "undefined" !== typeof window ? ("undefined" !== typeof queueMicrotask ? queueMicrotask : setTimeout).bind(window) : "undefined" !== typeof process && process.nextTick ? process.nextTick : setTimeout;
58
66
  var RTR_LOG = console.log.bind(console, "[S.I.A Reactor]");
59
67
  var EVT_WARN = console.warn.bind(console, "[S.I.A Event]");
60
68
  var NIL = Object.freeze({});
61
69
 
62
- // src/utils/obj.ts
70
+ // src/ts/utils/obj.ts
63
71
  var arrRx = /^([^\[\]]+)\[(\d+)\]$/;
64
72
  function isObj(obj, arraycheck = true) {
65
73
  return "object" === typeof obj && obj !== null && (arraycheck ? !Array.isArray(obj) : true);
@@ -193,12 +201,12 @@ function nuke(target) {
193
201
  }
194
202
  }
195
203
 
196
- // src/utils/num.ts
204
+ // src/ts/utils/num.ts
197
205
  function clamp(min = 0, val, max = Infinity) {
198
206
  return Math.min(Math.max(val, min), max);
199
207
  }
200
208
 
201
- // src/utils/fn.ts
209
+ // src/ts/utils/fn.ts
202
210
  function setTimeout2(handler, timeout, ...args) {
203
211
  const sig = args[0] instanceof AbortSignal ? args.shift() : void 0;
204
212
  if (sig?.aborted) return -1;
@@ -220,7 +228,7 @@ function requestAnimationFrame(callback, sig, win = window) {
220
228
  return sig.addEventListener("abort", kill, { once: true }), id;
221
229
  }
222
230
 
223
- // src/utils/methd.ts
231
+ // src/ts/utils/methd.ts
224
232
  function onAllMethods(owner, callback, skipOwn = true, nested = false) {
225
233
  let proto = owner;
226
234
  while (proto && proto !== Object.prototype) {
@@ -253,7 +261,7 @@ function guardMethod(fn, onError = (e) => console.error(e)) {
253
261
  });
254
262
  }
255
263
 
256
- // src/utils/keys.ts
264
+ // src/ts/utils/keys.ts
257
265
  function parseKeyCombo(combo) {
258
266
  const parts = cleanKeyCombo(combo).toLowerCase().split("+");
259
267
  return { ctrlKey: parts.includes("ctrl"), shiftKey: parts.includes("shift"), altKey: parts.includes("alt"), metaKey: parts.includes("meta") || parts.includes("cmd"), key: parts.find((p) => !["ctrl", "shift", "alt", "meta", "cmd"].includes(p)) || "" };
@@ -315,12 +323,31 @@ function parseForARIAKS(s, formatted = true) {
315
323
  const m = { ctrl: "Control", cmd: "Meta", space: "Space", plus: "+" };
316
324
  return (formatted && !Array.isArray(s) ? s : formatKeyForDisplay(s)).toLowerCase().replace(/[()]/g, "").replace(/\bor\b/g, " ").replace(/\w+/g, (k) => m[k] || k).replace(/\s+/g, " ").trim();
317
325
  }
326
+
327
+ // src/ts/utils/dom.ts
328
+ function createEl(tag, props, dataset, styles, el = tag ? document?.createElement(tag) : null) {
329
+ return assignEl(el, props, dataset, styles), el;
330
+ }
331
+ function assignEl(el, props, dataset, styles) {
332
+ if (!el) return;
333
+ if (props) {
334
+ for (const k of Object.keys(props)) if (props[k] !== void 0) el[k] = props[k];
335
+ }
336
+ if (dataset) {
337
+ for (const k of Object.keys(dataset)) if (dataset[k] !== void 0) el.dataset[k] = String(dataset[k]);
338
+ }
339
+ if (styles) {
340
+ for (const k of Object.keys(styles)) if (styles[k] !== void 0) el.style[k] = styles[k];
341
+ }
342
+ }
318
343
  // Annotate the CommonJS export names for ESM import in node:
319
344
  0 && (module.exports = {
345
+ assignEl,
320
346
  bindAllMethods,
321
347
  canHandle,
322
348
  clamp,
323
349
  cleanKeyCombo,
350
+ createEl,
324
351
  deepClone,
325
352
  deleteAny,
326
353
  formatKeyForDisplay,
package/dist/utils.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { c as canHandle, d as deepClone, e as deleteAny, g as getAny, f as getTrailRecords, i as inAny, h as isObj, j as isPOJO, m as mergeObjs, n as nuke, p as parseAnyObj, k as parseEvtOpts, s as setAny } from './index-C2hyIh0K.cjs';
1
+ export { d as canHandle, e as deepClone, f as deleteAny, g as getAny, h as getTrailRecords, i as inAny, j as isObj, k as isPOJO, m as mergeObjs, n as nuke, p as parseAnyObj, l as parseEvtOpts, s as setAny } from './index-Oie9hhE8.cjs';
2
2
 
3
3
  declare function clamp(min: number | undefined, val: number, max?: number): number;
4
4
 
@@ -168,4 +168,11 @@ declare function formatKeyShortcutsForDisplay(keyShortcuts: Record<string, strin
168
168
  */
169
169
  declare function parseForARIAKS(s: string | string[], formatted?: boolean): string;
170
170
 
171
- export { type KeyStruct, bindAllMethods, clamp, cleanKeyCombo, formatKeyForDisplay, formatKeyShortcutsForDisplay, getTermsForKey, guardAllMethods, guardMethod, keyEventAllowed, type keysSettings, matchKeys, onAllMethods, parseForARIAKS, parseKeyCombo, requestAnimationFrame, setInterval, setTimeout, stringifyKeyEvent };
171
+ type Dataset = Record<string, string | number>;
172
+ type Style = Partial<CSSStyleDeclaration>;
173
+ declare function createEl<K extends keyof HTMLElementTagNameMap>(tag: K, props?: Partial<HTMLElementTagNameMap[K]>, dataset?: Dataset, styles?: Style): HTMLElementTagNameMap[K];
174
+ declare function createEl(tag: string, props?: Partial<HTMLElement>, dataset?: Dataset, styles?: Style): HTMLElement | null;
175
+ declare function assignEl<K extends keyof HTMLElementTagNameMap>(el?: HTMLElementTagNameMap[K], props?: Partial<HTMLElementTagNameMap[K]>, dataset?: Dataset, styles?: Style): void;
176
+ declare function assignEl(el?: HTMLElement | null, props?: Partial<HTMLElement>, dataset?: Dataset, styles?: Style): void;
177
+
178
+ export { type KeyStruct, assignEl, bindAllMethods, clamp, cleanKeyCombo, createEl, formatKeyForDisplay, formatKeyShortcutsForDisplay, getTermsForKey, guardAllMethods, guardMethod, keyEventAllowed, type keysSettings, matchKeys, onAllMethods, parseForARIAKS, parseKeyCombo, requestAnimationFrame, setInterval, setTimeout, stringifyKeyEvent };
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { c as canHandle, d as deepClone, e as deleteAny, g as getAny, f as getTrailRecords, i as inAny, h as isObj, j as isPOJO, m as mergeObjs, n as nuke, p as parseAnyObj, k as parseEvtOpts, s as setAny } from './index-C2hyIh0K.js';
1
+ export { d as canHandle, e as deepClone, f as deleteAny, g as getAny, h as getTrailRecords, i as inAny, j as isObj, k as isPOJO, m as mergeObjs, n as nuke, p as parseAnyObj, l as parseEvtOpts, s as setAny } from './index-Oie9hhE8.js';
2
2
 
3
3
  declare function clamp(min: number | undefined, val: number, max?: number): number;
4
4
 
@@ -168,4 +168,11 @@ declare function formatKeyShortcutsForDisplay(keyShortcuts: Record<string, strin
168
168
  */
169
169
  declare function parseForARIAKS(s: string | string[], formatted?: boolean): string;
170
170
 
171
- export { type KeyStruct, bindAllMethods, clamp, cleanKeyCombo, formatKeyForDisplay, formatKeyShortcutsForDisplay, getTermsForKey, guardAllMethods, guardMethod, keyEventAllowed, type keysSettings, matchKeys, onAllMethods, parseForARIAKS, parseKeyCombo, requestAnimationFrame, setInterval, setTimeout, stringifyKeyEvent };
171
+ type Dataset = Record<string, string | number>;
172
+ type Style = Partial<CSSStyleDeclaration>;
173
+ declare function createEl<K extends keyof HTMLElementTagNameMap>(tag: K, props?: Partial<HTMLElementTagNameMap[K]>, dataset?: Dataset, styles?: Style): HTMLElementTagNameMap[K];
174
+ declare function createEl(tag: string, props?: Partial<HTMLElement>, dataset?: Dataset, styles?: Style): HTMLElement | null;
175
+ declare function assignEl<K extends keyof HTMLElementTagNameMap>(el?: HTMLElementTagNameMap[K], props?: Partial<HTMLElementTagNameMap[K]>, dataset?: Dataset, styles?: Style): void;
176
+ declare function assignEl(el?: HTMLElement | null, props?: Partial<HTMLElement>, dataset?: Dataset, styles?: Style): void;
177
+
178
+ export { type KeyStruct, assignEl, bindAllMethods, clamp, cleanKeyCombo, createEl, formatKeyForDisplay, formatKeyShortcutsForDisplay, getTermsForKey, guardAllMethods, guardMethod, keyEventAllowed, type keysSettings, matchKeys, onAllMethods, parseForARIAKS, parseKeyCombo, requestAnimationFrame, setInterval, setTimeout, stringifyKeyEvent };
package/dist/utils.js CHANGED
@@ -1,3 +1,16 @@
1
+ import {
2
+ assignEl,
3
+ cleanKeyCombo,
4
+ createEl,
5
+ formatKeyForDisplay,
6
+ formatKeyShortcutsForDisplay,
7
+ getTermsForKey,
8
+ keyEventAllowed,
9
+ matchKeys,
10
+ parseForARIAKS,
11
+ parseKeyCombo,
12
+ stringifyKeyEvent
13
+ } from "./chunk-5A44QFT6.js";
1
14
  import {
2
15
  bindAllMethods,
3
16
  clamp,
@@ -7,7 +20,7 @@ import {
7
20
  requestAnimationFrame,
8
21
  setInterval,
9
22
  setTimeout
10
- } from "./chunk-UQIMMJTY.js";
23
+ } from "./chunk-P37ADJMM.js";
11
24
  import {
12
25
  canHandle,
13
26
  deepClone,
@@ -22,75 +35,14 @@ import {
22
35
  parseAnyObj,
23
36
  parseEvtOpts,
24
37
  setAny
25
- } from "./chunk-4MJUBEI7.js";
26
-
27
- // src/utils/keys.ts
28
- function parseKeyCombo(combo) {
29
- const parts = cleanKeyCombo(combo).toLowerCase().split("+");
30
- return { ctrlKey: parts.includes("ctrl"), shiftKey: parts.includes("shift"), altKey: parts.includes("alt"), metaKey: parts.includes("meta") || parts.includes("cmd"), key: parts.find((p) => !["ctrl", "shift", "alt", "meta", "cmd"].includes(p)) || "" };
31
- }
32
- function stringifyKeyEvent(e) {
33
- const parts = [];
34
- if (e.ctrlKey) parts.push("ctrl");
35
- if (e.altKey) parts.push("alt");
36
- if (e.shiftKey) parts.push("shift");
37
- if (e.metaKey) parts.push("meta");
38
- parts.push(e.key?.toLowerCase() ?? "");
39
- return parts.join("+");
40
- }
41
- function cleanKeyCombo(combo) {
42
- const clean = (combo2) => {
43
- const m = ["ctrl", "alt", "shift", "meta"], alias = { cmd: "meta", space: " " };
44
- if (combo2 === " " || combo2 === "+") return combo2;
45
- combo2 = combo2.replace(/\+\s*\+$/, "+plus");
46
- const p = combo2.toLowerCase().split("+").filter((k) => k !== "").map((k) => alias[k] || (k === "plus" ? "+" : k.trim() || " "));
47
- return [...p.filter((k) => m.includes(k)).sort((a, b) => m.indexOf(a) - m.indexOf(b)), ...p.filter((k) => !m.includes(k)) || ""].join("+");
48
- };
49
- return Array.isArray(combo) ? combo.map(clean) : clean(combo);
50
- }
51
- function matchKeys(required, actual, strict = false) {
52
- actual = cleanKeyCombo(actual);
53
- const match = (required2, actual2) => {
54
- required2 = cleanKeyCombo(required2);
55
- if (strict) return required2 === actual2;
56
- const reqKeys = required2.split("+"), actKeys = actual2.split("+");
57
- return reqKeys.every((k) => actKeys.includes(k));
58
- };
59
- return Array.isArray(required) ? required.some((req) => match(req, actual)) : match(required, actual);
60
- }
61
- function getTermsForKey(combo, settings) {
62
- const terms = { override: false, block: false, whitelisted: false, action: null }, { overrides = [], shortcuts = {}, blocks = [], strictMatches: s = false, whitelist = [] } = settings || {};
63
- combo = cleanKeyCombo(combo);
64
- if (matchKeys(overrides, combo, s)) terms.override = true;
65
- if (matchKeys(blocks, combo, s)) terms.block = true;
66
- if (matchKeys(whitelist, combo)) terms.whitelisted = true;
67
- terms.action = Object.keys(shortcuts).find((key) => matchKeys(shortcuts[key], combo, s)) || null;
68
- return terms;
69
- }
70
- function keyEventAllowed(e, settings) {
71
- if (settings.disabled || (e.key === " " || e.key === "Enter") && (e.target?.ownerDocument || document).activeElement?.tagName === "BUTTON" || (e.target?.ownerDocument || document).activeElement?.matches("input,textarea,[contenteditable='true']")) return false;
72
- const combo = stringifyKeyEvent(e), { override, block, action, whitelisted } = getTermsForKey(combo, settings);
73
- if (block) return false;
74
- if (override) e.preventDefault();
75
- if (action) return action;
76
- if (whitelisted) return e.key.toLowerCase();
77
- return false;
78
- }
79
- var formatKeyForDisplay = (combo) => ` ${(Array.isArray(combo) ? combo : [combo]).map((c) => `(${cleanKeyCombo(c).replace(" ", "space")})`).join(" or ")}`;
80
- function formatKeyShortcutsForDisplay(keyShortcuts) {
81
- const shortcuts = {};
82
- for (const action of Object.keys(keyShortcuts)) shortcuts[action] = formatKeyForDisplay(keyShortcuts[action]);
83
- return shortcuts;
84
- }
85
- function parseForARIAKS(s, formatted = true) {
86
- const m = { ctrl: "Control", cmd: "Meta", space: "Space", plus: "+" };
87
- return (formatted && !Array.isArray(s) ? s : formatKeyForDisplay(s)).toLowerCase().replace(/[()]/g, "").replace(/\bor\b/g, " ").replace(/\w+/g, (k) => m[k] || k).replace(/\s+/g, " ").trim();
88
- }
38
+ } from "./chunk-DP74DVRT.js";
89
39
  export {
40
+ assignEl,
90
41
  bindAllMethods,
91
42
  canHandle,
92
43
  clamp,
93
44
  cleanKeyCombo,
45
+ createEl,
94
46
  deepClone,
95
47
  deleteAny,
96
48
  formatKeyForDisplay,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sia-reactor",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "description": "The Programmable Data DOM. A high-performance State Intent Architecture (S.I.A.) Engine with zero-allocation loops, event propagation, and structural sharing.",
5
5
  "author": "Oketade Oluwatobiloba <tobioketade007@gmail.com>",
6
6
  "license": "MIT",
@@ -50,7 +50,8 @@
50
50
  "import": "./dist/adapters/react.js",
51
51
  "require": "./dist/adapters/react.cjs",
52
52
  "default": "./dist/adapters/react.js"
53
- }
53
+ },
54
+ "./styles/time-travel-overlay.css": "./dist/styles/time-travel-overlay.css"
54
55
  },
55
56
  "publishConfig": {
56
57
  "access": "public"
@@ -1,154 +0,0 @@
1
- import {
2
- CTX,
3
- NIL,
4
- RAW,
5
- canHandle,
6
- nuke
7
- } from "./chunk-4MJUBEI7.js";
8
-
9
- // src/adapters/autotracker.ts
10
- var Autotracker = class {
11
- proxy;
12
- deps = /* @__PURE__ */ new Map();
13
- isTracking = true;
14
- rtr;
15
- /** only allows one reactor to autotrack when available */
16
- autortr;
17
- clups = [];
18
- lastPath;
19
- proxyCache = /* @__PURE__ */ new WeakMap();
20
- /** @param rtr Reactor instance used for path subscriptions. */
21
- constructor(rtr) {
22
- this.autortr = this.rtr = rtr;
23
- }
24
- /**
25
- * Starts a new tracking pass and returns a tracking proxy for `target` if `this` was instantiated with a `Reactor`.
26
- * @param target Snapshot (or state branch) to track reads from.
27
- * @returns Read-tracking proxy.
28
- * @example
29
- * const atrkr = new Autotracker(rtr);
30
- * const state = atrkr.tracked(rtr.snapshot());
31
- * const name = state.user.profile.name;
32
- */
33
- tracked(target) {
34
- return this.unblock(), this.rtr ? this.proxy = this.proxied(target, "") : target;
35
- }
36
- proxied(obj, path) {
37
- if (!obj || "object" !== typeof obj) return obj;
38
- const cached = this.proxyCache.get(obj);
39
- if (cached) return cached;
40
- if (!canHandle(obj, this.rtr.config, false)) return obj;
41
- const proxy = new Proxy(obj, {
42
- // Minimal Proxy Handler
43
- get: (object, key, receiver) => {
44
- if (key === RAW) return this.rtr.log(`\u{1F440} [AutoTracker \`get\` Trap] Peeked at ${object}`), object;
45
- const keyStr = String(key), fullPath = path ? `${path}.${keyStr}` : keyStr;
46
- return this.rtr.log(`\u{1F50D} [AutoTracker \`get\` Trap] Initiated for "${keyStr}" on "${path}"`), this.track(fullPath), this.proxied(!this.rtr.config.preserveContext ? object[key] : Reflect.get(object, key, receiver), fullPath);
47
- },
48
- has: (object, key) => {
49
- const keyStr = String(key), fullPath = path ? `${path}.${keyStr}` : keyStr;
50
- return this.rtr.log(`\u2753 [AutoTracker \`has\` Trap] Initiated for "${keyStr}" on "${path}"`), this.track(fullPath), !this.rtr.config.preserveContext ? key in object : Reflect.has(object, key);
51
- },
52
- getOwnPropertyDescriptor: (object, key) => {
53
- const keyStr = String(key), fullPath = path ? `${path}.${keyStr}` : keyStr;
54
- return this.rtr.log(`\u{1F4CB} [AutoTracker \`getOwnPropertyDescriptor\` Trap] Initiated for "${keyStr}" on "${path}"`), this.track(fullPath), !this.rtr.config.preserveContext ? Object.getOwnPropertyDescriptor(object, key) : Reflect.getOwnPropertyDescriptor(object, key);
55
- },
56
- ownKeys: (object) => {
57
- const safePath = path || "*";
58
- return this.rtr.log(`\u{1F511} [AutoTracker \`ownKeys\` Trap] Initiated on "${safePath}"`), this.track(safePath), Reflect.ownKeys(object);
59
- },
60
- set: (_, key) => {
61
- throw new Error(`\u{1F6E1}\uFE0F [AutoTracker \`set\` Trap] Blocked for "${String(key)}" on "${path}"`);
62
- },
63
- deleteProperty: (_, key) => {
64
- throw new Error(`\u{1F6E1}\uFE0F [AutoTracker \`deleteProperty\` Trap] Blocked for "${String(key)}" on "${path}"`);
65
- },
66
- defineProperty: (_, key) => {
67
- throw new Error(`\u{1F6E1}\uFE0F [AutoTracker \`defineProperty\` Trap] Blocked for "${String(key)}" on "${path}"`);
68
- },
69
- setPrototypeOf: (_, key) => {
70
- throw new Error(`\u{1F6E1}\uFE0F [AutoTracker \`setPrototypeOf\` Trap] Blocked for "${String(key)}" on "${path}"`);
71
- }
72
- });
73
- return this.proxyCache.set(obj, proxy), proxy;
74
- }
75
- /** Adds a path to the tracking set. */
76
- track(path, rtr = this.rtr, prune = false) {
77
- if (!this.isTracking || !path || this.autortr && this.autortr !== rtr) return path;
78
- let paths = this.deps.get(rtr);
79
- if (!prune && !paths) paths = (this.deps.set(rtr, paths = /* @__PURE__ */ new Set()), paths);
80
- if (path.startsWith(this.lastPath + ".")) paths.delete(this.lastPath);
81
- return !prune && paths.add(this.lastPath = path), path;
82
- }
83
- /** Removes a path from the tracking set. */
84
- untrack(path, rtr = this.rtr) {
85
- this.deps.get(rtr)?.delete(path);
86
- }
87
- /** Enables path tracking. */
88
- unblock(rtr = this.rtr) {
89
- this.deps.clear();
90
- this.autortr = rtr;
91
- this.isTracking = true;
92
- this.lastPath = void 0;
93
- }
94
- /** Temporarily disables path tracking. */
95
- block() {
96
- this.autortr = void 0;
97
- this.isTracking = false;
98
- }
99
- /**
100
- * Subscribes an effect to tracked paths.
101
- * Uses `watch` when `options.sync === true` (synchronous updates), otherwise
102
- * uses `on` (batched/asynchronous listener wave).
103
- * @param cb Effect callback.
104
- * @param options Effect options.
105
- * @returns Cleanup function for active subscriptions.
106
- * @example
107
- * const atrkr = new Autotracker(rtr);
108
- * const view = atrkr.tracked(rtr.snapshot()); // tracked works if `rtr` was passed at instantiation
109
- * view.user.name;
110
- * const stop = atrkr.callback(() => console.log("changed")); // re-run after when ".user.name" changes
111
- * @example Packaged Customization
112
- * const atrkr = new Autotracker(); // no reactor passed
113
- * withTracker(atrkr, () => state.user.name); // import `withTracker` first
114
- * 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
115
- * @example Extensive customization
116
- * atrkr.unblock();
117
- * const prev = CTX.autotracker;
118
- * CTX.autotracker = atrkr; // import CTX first
119
- * state.user.name;
120
- * CTX.autotracker = prev;
121
- */
122
- callback(cb, options = NIL) {
123
- this.cleanup();
124
- const method = options.sync ? "watch" : "on";
125
- for (const [rtr, paths] of this.deps) {
126
- if (!paths.size || paths.has("*")) rtr && this.clups.push(rtr[method]("*", cb, options));
127
- else for (const path of paths) this.clups.push(rtr[method](path, cb, options));
128
- }
129
- return () => this.cleanup();
130
- }
131
- /** Clears active subscriptions and blocks tracking. */
132
- cleanup() {
133
- this.block();
134
- for (let i = 0, len = this.clups.length; i < len; i++) this.clups[i]();
135
- this.clups.length = 0;
136
- }
137
- destroy() {
138
- this.deps.clear(), this.cleanup(), nuke(this);
139
- }
140
- };
141
- function withTracker(tracker, run, rtr) {
142
- const prev = CTX.autotracker;
143
- CTX.autotracker = tracker;
144
- try {
145
- return tracker.unblock(rtr), run();
146
- } finally {
147
- CTX.autotracker = prev;
148
- }
149
- }
150
-
151
- export {
152
- Autotracker,
153
- withTracker
154
- };
@@ -1,80 +0,0 @@
1
- import {
2
- Reactor
3
- } from "./chunk-Q2AKMIHN.js";
4
- import {
5
- INDIFFABLE,
6
- INERTIA,
7
- NIL,
8
- RAW,
9
- REJECTABLE,
10
- SSVERSION,
11
- VERSION
12
- } from "./chunk-4MJUBEI7.js";
13
-
14
- // src/core/mixins.ts
15
- var methods = ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "cascade", "snapshot", "reset", "destroy"];
16
- function reactive(target, build, preferences = NIL) {
17
- if ("__Reactor__" in target) return target;
18
- const descriptors = {}, rtr = target instanceof Reactor ? target : new Reactor(target, build), locks = { enumerable: false, configurable: true, writable: false }, hasAffix = !!(preferences.prefix || preferences.suffix);
19
- for (let i = 0, len = methods.length; i < len; i++) {
20
- let key = methods[i];
21
- if (hasAffix) (preferences.whitelist?.includes(key) ?? true) && (key = `${preferences.prefix || ""}${key}${preferences.suffix || ""}`);
22
- else if (preferences.whitelist?.includes(key)) continue;
23
- descriptors[key] = { value: rtr[key].bind(rtr), ...locks };
24
- }
25
- descriptors["__Reactor__"] = { value: rtr, ...locks };
26
- return Object.defineProperties(rtr.core, descriptors), rtr.core;
27
- }
28
- function inert(target) {
29
- return getRaw(target)[INERTIA] = true, target;
30
- }
31
- function live(target) {
32
- return delete getRaw(target)[INERTIA], target;
33
- }
34
- function isInert(target) {
35
- return !!getRaw(target)[INERTIA];
36
- }
37
- function intent(target) {
38
- return getRaw(target)[REJECTABLE] = true, target;
39
- }
40
- function state(target) {
41
- return delete getRaw(target)[REJECTABLE], target;
42
- }
43
- function isIntent(target) {
44
- return !!getRaw(target)[REJECTABLE];
45
- }
46
- function volatile(target) {
47
- return getRaw(target)[INDIFFABLE] = true, target;
48
- }
49
- function stable(target) {
50
- return delete getRaw(target)[INDIFFABLE], target;
51
- }
52
- function isVolatile(target) {
53
- return !!getRaw(target)[INDIFFABLE];
54
- }
55
- function getRaw(target) {
56
- return target?.[RAW] || target;
57
- }
58
- function getVersion(target) {
59
- return getRaw(target)[VERSION] || 0;
60
- }
61
- function getSnapshotVersion(target) {
62
- return getRaw(target)[SSVERSION] || 0;
63
- }
64
-
65
- export {
66
- methods,
67
- reactive,
68
- inert,
69
- live,
70
- isInert,
71
- intent,
72
- state,
73
- isIntent,
74
- volatile,
75
- stable,
76
- isVolatile,
77
- getRaw,
78
- getVersion,
79
- getSnapshotVersion
80
- };