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.
- package/README.md +102 -58
- package/dist/TimeTravelOverlay-CJv-S_Km.d.cts +41 -0
- package/dist/TimeTravelOverlay-DxqJL0Zk.d.ts +41 -0
- package/dist/adapters/react.cjs +308 -92
- package/dist/adapters/react.d.cts +68 -10
- package/dist/adapters/react.d.ts +68 -10
- package/dist/adapters/react.js +80 -29
- package/dist/adapters/vanilla.cjs +957 -10
- package/dist/adapters/vanilla.d.cts +4 -2
- package/dist/adapters/vanilla.d.ts +4 -2
- package/dist/adapters/vanilla.js +8 -12
- package/dist/{chunk-Q2AKMIHN.js → chunk-2WBPGSRL.js} +106 -48
- package/dist/chunk-5A44QFT6.js +93 -0
- package/dist/{chunk-4MJUBEI7.js → chunk-DP74DVRT.js} +4 -2
- package/dist/{chunk-UQIMMJTY.js → chunk-P37ADJMM.js} +3 -3
- package/dist/chunk-TFLYCXK4.js +251 -0
- package/dist/{index-C2hyIh0K.d.cts → index-Oie9hhE8.d.cts} +14 -10
- package/dist/{index-C2hyIh0K.d.ts → index-Oie9hhE8.d.ts} +14 -10
- package/dist/index.cjs +45 -52
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -6
- package/dist/plugins.cjs +72 -73
- package/dist/plugins.d.cts +4 -75
- package/dist/plugins.d.ts +4 -75
- package/dist/plugins.js +27 -22
- package/dist/styles/time-travel-overlay.css +189 -0
- package/dist/super.d.ts +79 -26
- package/dist/super.global.js +200 -105
- package/dist/timeTravel-B1vedDQc.d.ts +76 -0
- package/dist/timeTravel-WpgWmKu-.d.cts +76 -0
- package/dist/utils.cjs +34 -7
- package/dist/utils.d.cts +9 -2
- package/dist/utils.d.ts +9 -2
- package/dist/utils.js +17 -65
- package/package.json +3 -2
- package/dist/chunk-FGUCKMLH.js +0 -154
- 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 {
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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.
|
|
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"
|
package/dist/chunk-FGUCKMLH.js
DELETED
|
@@ -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
|
-
};
|
package/dist/chunk-KIQP7G7W.js
DELETED
|
@@ -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
|
-
};
|