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
package/dist/plugins.cjs
CHANGED
|
@@ -17,7 +17,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
|
-
// src/plugins.ts
|
|
20
|
+
// src/ts/plugins.ts
|
|
21
21
|
var plugins_exports = {};
|
|
22
22
|
__export(plugins_exports, {
|
|
23
23
|
BaseReactorPlugin: () => BaseReactorPlugin,
|
|
@@ -34,8 +34,10 @@ __export(plugins_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(plugins_exports);
|
|
36
36
|
|
|
37
|
-
// src/core/consts.ts
|
|
37
|
+
// src/ts/core/consts.ts
|
|
38
38
|
var CTX = {
|
|
39
|
+
/** Flag indicating whether the application is running in development mode. */
|
|
40
|
+
isDevEnv: "undefined" !== typeof process ? process.env.NODE_ENV !== "production" : true,
|
|
39
41
|
/** active `Autotracker` instance, override for automatic dependency collection on `Reactor` traps. */
|
|
40
42
|
autotracker: null
|
|
41
43
|
};
|
|
@@ -54,7 +56,7 @@ var NIL = Object.freeze({});
|
|
|
54
56
|
var NOOP = () => {
|
|
55
57
|
};
|
|
56
58
|
|
|
57
|
-
// src/utils/obj.ts
|
|
59
|
+
// src/ts/utils/obj.ts
|
|
58
60
|
var arrRx = /^([^\[\]]+)\[(\d+)\]$/;
|
|
59
61
|
function isObj(obj, arraycheck = true) {
|
|
60
62
|
return "object" === typeof obj && obj !== null && (arraycheck ? !Array.isArray(obj) : true);
|
|
@@ -181,7 +183,7 @@ function nuke(target) {
|
|
|
181
183
|
}
|
|
182
184
|
}
|
|
183
185
|
|
|
184
|
-
// src/core/event.ts
|
|
186
|
+
// src/ts/core/event.ts
|
|
185
187
|
var ReactorEvent = class _ReactorEvent {
|
|
186
188
|
/** No active propagation phase. */
|
|
187
189
|
static NONE = 0;
|
|
@@ -304,7 +306,7 @@ var ReactorEvent = class _ReactorEvent {
|
|
|
304
306
|
}
|
|
305
307
|
};
|
|
306
308
|
|
|
307
|
-
// src/core/reactor.ts
|
|
309
|
+
// src/ts/core/reactor.ts
|
|
308
310
|
var Reactor = class {
|
|
309
311
|
log = NOOP;
|
|
310
312
|
core;
|
|
@@ -332,27 +334,27 @@ var Reactor = class {
|
|
|
332
334
|
listeners;
|
|
333
335
|
/**
|
|
334
336
|
* Creates a new Reactor instance.
|
|
335
|
-
* @param
|
|
337
|
+
* @param target Initial state target.
|
|
336
338
|
* @param build Reactor bootstrap/build configuration.
|
|
337
339
|
* @example
|
|
338
340
|
* const rtr = new Reactor({ count: 0 });
|
|
339
341
|
*/
|
|
340
|
-
constructor(
|
|
342
|
+
constructor(target = {}, build) {
|
|
341
343
|
this[INERTIA] = true;
|
|
342
344
|
this.config = { crossRealms: false, smartCloning: false, eventBubbling: true, lineageTracing: false, preserveContext: false, equalityFunction: Object.is, batchingFunction: RTR_BATCH, ...build };
|
|
343
|
-
this.core = this.proxied(
|
|
345
|
+
this.core = this.proxied(target);
|
|
344
346
|
if (build) this.canLog = !!build.debug;
|
|
345
347
|
}
|
|
346
|
-
proxied(
|
|
347
|
-
if (!
|
|
348
|
-
|
|
349
|
-
if (this.config.referenceTracking && parent && key && !this.link(
|
|
350
|
-
const cached = this.proxyCache.get(
|
|
348
|
+
proxied(target, rejectable = false, indiffable = false, parent, key, path) {
|
|
349
|
+
if (!target || "object" !== typeof target) return target;
|
|
350
|
+
target = target[RAW] || target;
|
|
351
|
+
if (this.config.referenceTracking && parent && key && !this.link(target, parent, key, false)) return target;
|
|
352
|
+
const cached = this.proxyCache.get(target);
|
|
351
353
|
if (cached) return cached;
|
|
352
|
-
if (
|
|
353
|
-
rejectable ||=
|
|
354
|
-
indiffable ||=
|
|
355
|
-
const proxy = new Proxy(
|
|
354
|
+
if (target[INERTIA] || !canHandle(target, this.config, false)) return target;
|
|
355
|
+
rejectable ||= target[REJECTABLE];
|
|
356
|
+
indiffable ||= target[INDIFFABLE];
|
|
357
|
+
const proxy = new Proxy(target, {
|
|
356
358
|
// Robust Proxy handler
|
|
357
359
|
get: (object, key2, receiver) => {
|
|
358
360
|
if (key2 === RAW) return this.log(`\u{1F440} [Reactor \`get\` Trap] Peeked at ${object}`), object;
|
|
@@ -365,10 +367,10 @@ var Reactor = class {
|
|
|
365
367
|
for (let i = 0, len = this.config.lineageTracing ? paths.length : 1; i < len; i++) {
|
|
366
368
|
const currPath = this.config.lineageTracing ? paths[i] : fullPath, cords = this.getters.get(currPath);
|
|
367
369
|
if (!cords && !wildcords) continue;
|
|
368
|
-
const
|
|
370
|
+
const target2 = { path: currPath, value, key: keyStr, hadKey: true, object: receiver }, payload = { type: "get", target: target2, currentTarget: target2, root: this.core, rejectable };
|
|
369
371
|
if (cords) value = this.mediate(currPath, payload, "get", cords);
|
|
370
372
|
if (!wildcords) continue;
|
|
371
|
-
|
|
373
|
+
target2.value = value;
|
|
372
374
|
value = this.mediate("*", payload, "get", wildcords);
|
|
373
375
|
}
|
|
374
376
|
}
|
|
@@ -376,7 +378,7 @@ var Reactor = class {
|
|
|
376
378
|
},
|
|
377
379
|
set: (object, key2, value, receiver) => {
|
|
378
380
|
let unchanged, safeValue, safeOldValue, terminated = false;
|
|
379
|
-
const keyStr = String(key2), fullPath = path ? path + "." + keyStr : keyStr, paths = this.config.lineageTracing ? this.trace(object, keyStr) : fullPath, loopLen = this.config.lineageTracing ? paths.length : 1, oldValue = !this.config.preserveContext ? object[key2] : Reflect.get(object, key2, receiver),
|
|
381
|
+
const keyStr = String(key2), fullPath = path ? path + "." + keyStr : keyStr, paths = this.config.lineageTracing ? this.trace(object, keyStr) : fullPath, loopLen = this.config.lineageTracing ? paths.length : 1, oldValue = !this.config.preserveContext ? object[key2] : Reflect.get(object, key2, receiver), hadKey = !this.config.preserveContext ? key2 in object : Reflect.has(object, key2);
|
|
380
382
|
this.log(`\u270F\uFE0F [Reactor \`set\` Trap] Initiated for "${keyStr}" on "${paths}"`), CTX.autotracker?.track(fullPath, this, true);
|
|
381
383
|
if (this.config.referenceTracking || !indiffable) {
|
|
382
384
|
safeOldValue = oldValue?.[RAW] || oldValue;
|
|
@@ -390,13 +392,13 @@ var Reactor = class {
|
|
|
390
392
|
for (let i = 0; i < loopLen; i++) {
|
|
391
393
|
const currPath = this.config.lineageTracing ? paths[i] : fullPath, cords = this.setters.get(currPath);
|
|
392
394
|
if (!cords && !wildcords) continue;
|
|
393
|
-
const
|
|
395
|
+
const target2 = { path: currPath, value, oldValue, key: keyStr, hadKey, object: receiver }, payload = { type: "set", target: target2, currentTarget: target2, root: this.core, terminated, rejectable };
|
|
394
396
|
if (cords) {
|
|
395
397
|
const result2 = this.mediate(currPath, payload, "set", cords);
|
|
396
398
|
if (!(terminated ||= payload.terminated)) value = result2;
|
|
397
399
|
}
|
|
398
400
|
if (!wildcords) continue;
|
|
399
|
-
|
|
401
|
+
target2.value = value;
|
|
400
402
|
const result = this.mediate("*", payload, "set", wildcords);
|
|
401
403
|
if (!(terminated ||= payload.terminated)) value = result;
|
|
402
404
|
}
|
|
@@ -407,14 +409,14 @@ var Reactor = class {
|
|
|
407
409
|
if (this.config.referenceTracking && !unchanged) this.config.smartCloning && this.stamp(object), this.unlink(safeOldValue, object, keyStr), this.link(safeValue, object, keyStr);
|
|
408
410
|
if (this.watchers || this.listeners)
|
|
409
411
|
for (let i = 0; i < loopLen; i++) {
|
|
410
|
-
const currPath = this.config.lineageTracing ? paths[i] : fullPath,
|
|
411
|
-
this.notify(currPath, { type: "set", target, currentTarget:
|
|
412
|
+
const currPath = this.config.lineageTracing ? paths[i] : fullPath, target2 = { path: currPath, value, oldValue, key: keyStr, hadKey, object: receiver };
|
|
413
|
+
this.notify(currPath, { type: "set", target: target2, currentTarget: target2, root: this.core, terminated, rejectable });
|
|
412
414
|
}
|
|
413
415
|
return true;
|
|
414
416
|
},
|
|
415
417
|
deleteProperty: (object, key2) => {
|
|
416
418
|
let value, receiver = this.proxyCache.get(object), terminated = false;
|
|
417
|
-
const keyStr = String(key2), fullPath = path ? path + "." + keyStr : keyStr, paths = this.config.lineageTracing ? this.trace(object, keyStr) : fullPath, loopLen = this.config.lineageTracing ? paths.length : 1, oldValue = !this.config.preserveContext ? object[key2] : Reflect.get(object, key2, receiver),
|
|
419
|
+
const keyStr = String(key2), fullPath = path ? path + "." + keyStr : keyStr, paths = this.config.lineageTracing ? this.trace(object, keyStr) : fullPath, loopLen = this.config.lineageTracing ? paths.length : 1, oldValue = !this.config.preserveContext ? object[key2] : Reflect.get(object, key2, receiver), hadKey = !this.config.preserveContext ? key2 in object : Reflect.has(object, key2);
|
|
418
420
|
this.log(`\u{1F5D1}\uFE0F [Reactor \`deleteProperty\` Trap] Initiated for "${keyStr}" on "${paths}"`), CTX.autotracker?.track(fullPath, this, true);
|
|
419
421
|
if (this.config.deleteProperty) terminated = (value = this.config.deleteProperty(object, key2, oldValue, receiver, paths)) === TERMINATOR;
|
|
420
422
|
if (this.deleters) {
|
|
@@ -422,7 +424,7 @@ var Reactor = class {
|
|
|
422
424
|
for (let i = 0; i < loopLen; i++) {
|
|
423
425
|
const currPath = this.config.lineageTracing ? paths[i] : fullPath, cords = this.deleters.get(currPath);
|
|
424
426
|
if (!cords && !wildcords) continue;
|
|
425
|
-
const
|
|
427
|
+
const target2 = { path: currPath, value, oldValue, key: keyStr, hadKey, object: receiver }, payload = { type: "delete", target: target2, currentTarget: target2, root: this.core, rejectable };
|
|
426
428
|
if (cords) {
|
|
427
429
|
const result2 = this.mediate(currPath, payload, "delete", cords);
|
|
428
430
|
if (!(terminated ||= payload.terminated)) value = result2;
|
|
@@ -438,8 +440,8 @@ var Reactor = class {
|
|
|
438
440
|
if (this.config.referenceTracking) this.config.smartCloning && this.stamp(object), this.unlink(oldValue?.[RAW] || oldValue, object, keyStr);
|
|
439
441
|
if (this.watchers || this.listeners)
|
|
440
442
|
for (let i = 0; i < loopLen; i++) {
|
|
441
|
-
const currPath = this.config.lineageTracing ? paths[i] : fullPath,
|
|
442
|
-
this.notify(currPath, { type: "delete", target, currentTarget:
|
|
443
|
+
const currPath = this.config.lineageTracing ? paths[i] : fullPath, target2 = { path: currPath, value, oldValue, key: keyStr, hadKey, object: receiver };
|
|
444
|
+
this.notify(currPath, { type: "delete", target: target2, currentTarget: target2, root: this.core, rejectable });
|
|
443
445
|
}
|
|
444
446
|
return true;
|
|
445
447
|
},
|
|
@@ -465,7 +467,7 @@ var Reactor = class {
|
|
|
465
467
|
return ownKeys;
|
|
466
468
|
}
|
|
467
469
|
});
|
|
468
|
-
return this.proxyCache.set(
|
|
470
|
+
return this.proxyCache.set(target, proxy), proxy;
|
|
469
471
|
}
|
|
470
472
|
trace(target, path, paths = [], seen = /* @__PURE__ */ new WeakSet()) {
|
|
471
473
|
if (Object.is(target, this.core[RAW] || this.core)) return paths.push(path), paths;
|
|
@@ -557,7 +559,7 @@ var Reactor = class {
|
|
|
557
559
|
fire([path, object, value], e, isCapture, cords = this.listeners.get(path)) {
|
|
558
560
|
if (!cords) return;
|
|
559
561
|
e.type = path !== e.target.path ? "update" : e.staticType;
|
|
560
|
-
e.currentTarget = { path, value, oldValue: e.type !== "update" ? e.target.oldValue : void 0, key: e.type !== "update" ? path : path.slice(path.lastIndexOf(".") + 1) || "",
|
|
562
|
+
e.currentTarget = { path, value, oldValue: e.type !== "update" ? e.target.oldValue : void 0, key: e.type !== "update" ? path : path.slice(path.lastIndexOf(".") + 1) || "", hadKey: e.type !== "update" ? e.target.hadKey : true, object };
|
|
561
563
|
for (let i = 0, len = cords.length, tDepth; i < len; i++) {
|
|
562
564
|
if (e.immediatePropagationStopped) break;
|
|
563
565
|
if (cords[i].capture !== isCapture) continue;
|
|
@@ -612,21 +614,20 @@ var Reactor = class {
|
|
|
612
614
|
}
|
|
613
615
|
getContext(path) {
|
|
614
616
|
const lastDot = path.lastIndexOf("."), value = getAny(this.core, path), object = lastDot === -1 ? this.core : getAny(this.core, path.slice(0, lastDot));
|
|
615
|
-
return { path, value, key: path.slice(lastDot + 1) || "",
|
|
617
|
+
return { path, value, key: path.slice(lastDot + 1) || "", hadKey: true, object };
|
|
616
618
|
}
|
|
617
619
|
bindSignal(cord, sig) {
|
|
618
620
|
if (sig) sig.aborted ? cord.clup() : sig.addEventListener("abort", cord.clup, { once: true });
|
|
619
621
|
return cord.sclup = !sig || sig.aborted ? NOOP : () => sig.removeEventListener("abort", cord.clup), cord.clup;
|
|
620
622
|
}
|
|
621
|
-
cloned(
|
|
622
|
-
if (!
|
|
623
|
-
obj =
|
|
624
|
-
const cloned = seen.get(obj);
|
|
623
|
+
cloned(target, raw, seen = /* @__PURE__ */ new WeakMap()) {
|
|
624
|
+
if (!target || "object" !== typeof target) return target;
|
|
625
|
+
const obj = target[RAW] || target, cloned = seen.get(obj);
|
|
625
626
|
if (cloned) return cloned;
|
|
626
627
|
if (!canHandle(obj, this.config, false)) return obj;
|
|
627
628
|
const version = obj[VERSION] || 0, cached = !raw && this.config.smartCloning && (this.snapCache ??= /* @__PURE__ */ new WeakMap()).get(obj);
|
|
628
629
|
if (cached && obj[SSVERSION] === version) return cached;
|
|
629
|
-
const clone = !raw ? this.config.preserveContext ? Object.create(Object.getPrototypeOf(obj)) : Array.isArray(obj) ? [] : {} : obj
|
|
630
|
+
const clone = !raw ? this.config.preserveContext ? Object.create(Object.getPrototypeOf(obj)) : Array.isArray(obj) ? [] : {} : obj;
|
|
630
631
|
seen.set(obj, clone);
|
|
631
632
|
const keys = this.config.preserveContext ? Reflect.ownKeys(obj) : Object.keys(obj);
|
|
632
633
|
for (let i = 0, len = keys.length; i < len; i++) clone[keys[i]] = this.cloned(obj[keys[i]], raw, seen);
|
|
@@ -810,19 +811,8 @@ var Reactor = class {
|
|
|
810
811
|
for (let i = 0, len = cords.length; i < len; i++) if (Object.is(cords[i].cb, callback) && cords[i].capture === capture) return cords[i].sclup(), cords.splice((len--, i--), 1), !cords.length && this.listeners.delete(path), true;
|
|
811
812
|
return false;
|
|
812
813
|
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
* You could alternatively use or serialize your proxied state "as is" except the environment demands no proxies or new references.
|
|
816
|
-
* @param raw Use raw (deep unproxied & uncloned) version of branch.
|
|
817
|
-
* @param branch Branch to clone.
|
|
818
|
-
* @returns Snapshot deep or smart (structurally shared) clone.
|
|
819
|
-
* @example
|
|
820
|
-
* const snap = rtr.snapshot();
|
|
821
|
-
* @example
|
|
822
|
-
* const snap = rtr.snapshot(false, rtr.core.history.past);
|
|
823
|
-
*/
|
|
824
|
-
snapshot(raw = !this.config.smartCloning, branch = this.core) {
|
|
825
|
-
return this.cloned(branch, raw);
|
|
814
|
+
snapshot(raw = !this.config.smartCloning, branch) {
|
|
815
|
+
return this.cloned(arguments.length < 2 ? this.core : branch, raw);
|
|
826
816
|
}
|
|
827
817
|
/**
|
|
828
818
|
* Cascades object updates into direct child paths.
|
|
@@ -873,11 +863,11 @@ var Reactor = class {
|
|
|
873
863
|
}
|
|
874
864
|
};
|
|
875
865
|
|
|
876
|
-
// src/core/mixins.ts
|
|
877
|
-
var methods = ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "cascade", "
|
|
866
|
+
// src/ts/core/mixins.ts
|
|
867
|
+
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"];
|
|
878
868
|
function reactive(target, build, preferences = NIL) {
|
|
879
869
|
if ("__Reactor__" in target) return target;
|
|
880
|
-
const descriptors = {}, rtr =
|
|
870
|
+
const descriptors = {}, rtr = getReactor(target, true, build), locks = { enumerable: false, configurable: true, writable: false }, hasAffix = !!(preferences.prefix || preferences.suffix);
|
|
881
871
|
for (let i = 0, len = methods.length; i < len; i++) {
|
|
882
872
|
let key = methods[i];
|
|
883
873
|
if (hasAffix) (preferences.whitelist?.includes(key) ?? true) && (key = `${preferences.prefix || ""}${key}${preferences.suffix || ""}`);
|
|
@@ -887,8 +877,11 @@ function reactive(target, build, preferences = NIL) {
|
|
|
887
877
|
descriptors["__Reactor__"] = { value: rtr, ...locks };
|
|
888
878
|
return Object.defineProperties(rtr.core, descriptors), rtr.core;
|
|
889
879
|
}
|
|
880
|
+
function getReactor(target, create = false, build) {
|
|
881
|
+
return (target instanceof Reactor ? target : target.__Reactor__) || (create ? new Reactor(target, build) : void 0);
|
|
882
|
+
}
|
|
890
883
|
|
|
891
|
-
// src/utils/methd.ts
|
|
884
|
+
// src/ts/utils/methd.ts
|
|
892
885
|
function onAllMethods(owner, callback, skipOwn = true, nested = false) {
|
|
893
886
|
let proto = owner;
|
|
894
887
|
while (proto && proto !== Object.prototype) {
|
|
@@ -916,7 +909,7 @@ function guardMethod(fn, onError = (e) => console.error(e)) {
|
|
|
916
909
|
});
|
|
917
910
|
}
|
|
918
911
|
|
|
919
|
-
// src/plugins/base.ts
|
|
912
|
+
// src/ts/plugins/base.ts
|
|
920
913
|
var BaseReactorPlugin = class {
|
|
921
914
|
static plugName;
|
|
922
915
|
get name() {
|
|
@@ -954,7 +947,7 @@ var BaseReactorPlugin = class {
|
|
|
954
947
|
// `()=>{}`: needs to be bounded even before initialization
|
|
955
948
|
};
|
|
956
949
|
|
|
957
|
-
// src/utils/store.ts
|
|
950
|
+
// src/ts/utils/store.ts
|
|
958
951
|
var BaseStorageAdapter = class {
|
|
959
952
|
static name;
|
|
960
953
|
config;
|
|
@@ -1088,7 +1081,7 @@ var IndexedDBAdapter = class extends AsyncStorageAdapter {
|
|
|
1088
1081
|
};
|
|
1089
1082
|
var INDEXED_DB_ADAPTER_BUILD = { dbName: "REACTOR_IDB", stores: ["VAULT"], version: 1, onidb: NOOP, onupgradeneeded: NOOP, onversionchange: NOOP, onsuccess: NOOP, onerror: NOOP, onblocked: NOOP };
|
|
1090
1083
|
|
|
1091
|
-
// src/utils/fn.ts
|
|
1084
|
+
// src/ts/utils/fn.ts
|
|
1092
1085
|
function setTimeout2(handler, timeout, ...args) {
|
|
1093
1086
|
const sig = args[0] instanceof AbortSignal ? args.shift() : void 0;
|
|
1094
1087
|
if (sig?.aborted) return -1;
|
|
@@ -1098,7 +1091,7 @@ function setTimeout2(handler, timeout, ...args) {
|
|
|
1098
1091
|
return sig.addEventListener("abort", kill, { once: true }), id;
|
|
1099
1092
|
}
|
|
1100
1093
|
|
|
1101
|
-
// src/plugins/persist.ts
|
|
1094
|
+
// src/ts/plugins/persist.ts
|
|
1102
1095
|
var PersistPlugin = class extends BaseReactorPlugin {
|
|
1103
1096
|
static plugName = "persist";
|
|
1104
1097
|
adapter;
|
|
@@ -1151,17 +1144,18 @@ var PersistPlugin = class extends BaseReactorPlugin {
|
|
|
1151
1144
|
};
|
|
1152
1145
|
var PERSIST_PLUGIN_BUILD = { disabled: false, key: "REACTOR_STORE", throttle: 2500, useSnapshot: false };
|
|
1153
1146
|
|
|
1154
|
-
// src/utils/num.ts
|
|
1147
|
+
// src/ts/utils/num.ts
|
|
1155
1148
|
function clamp(min = 0, val, max = Infinity) {
|
|
1156
1149
|
return Math.min(Math.max(val, min), max);
|
|
1157
1150
|
}
|
|
1158
1151
|
|
|
1159
|
-
// src/plugins/timeTravel.ts
|
|
1152
|
+
// src/ts/plugins/timeTravel.ts
|
|
1160
1153
|
var TimeTravelPlugin = class extends BaseReactorPlugin {
|
|
1161
1154
|
static plugName = "timeTravel";
|
|
1155
|
+
lastTimestamp = 0;
|
|
1162
1156
|
playbackTimeoutId = -1;
|
|
1163
1157
|
constructor(config, rtr) {
|
|
1164
|
-
super({ ...TIME_TRAVEL_PLUGIN_BUILD, ...config }, rtr, {
|
|
1158
|
+
super({ ...TIME_TRAVEL_PLUGIN_BUILD, ...config }, rtr, { initialState: null, history: [], currentFrame: 0, paused: true });
|
|
1165
1159
|
}
|
|
1166
1160
|
// ===========================================================================
|
|
1167
1161
|
// THE FOUNDATION & WIRETAP (Passive Recording)
|
|
@@ -1169,6 +1163,7 @@ var TimeTravelPlugin = class extends BaseReactorPlugin {
|
|
|
1169
1163
|
wire() {
|
|
1170
1164
|
this.rtr.config.referenceTracking = this.rtr.config.smartCloning = this.rtr.config.eventTimeStamps = true;
|
|
1171
1165
|
if (!this.state.history.length || this.state.initialState == null) this.state.initialState = this.rtr.snapshot();
|
|
1166
|
+
this.lastTimestamp = performance.now();
|
|
1172
1167
|
this.state.set("currentFrame", (v = 0) => clamp(0, v, this.state.history.length), { signal: this.signal, immediate: true });
|
|
1173
1168
|
this.config.on("paths", this.handlePathsState, { signal: this.signal, immediate: true });
|
|
1174
1169
|
!this.state.paused && this.play();
|
|
@@ -1182,16 +1177,17 @@ var TimeTravelPlugin = class extends BaseReactorPlugin {
|
|
|
1182
1177
|
if (!this.state.paused) return;
|
|
1183
1178
|
if (this.state.currentFrame < this.state.history.length) this.state.history = this.state.history.slice(0, this.state.currentFrame);
|
|
1184
1179
|
if (this.state.history.length >= this.config.maxHistoryLength) this.state.history = this.state.history.slice(1);
|
|
1185
|
-
this.state.history.push({
|
|
1180
|
+
this.state.history.push({ path: e.target.path, value: this.rtr.snapshot(false, e.target.value), oldValue: this.rtr.snapshot(false, e.target.oldValue), type: e.staticType, rejected: e.rejected, timedelta: e.timestamp - this.lastTimestamp, hadKey: e.target.hadKey });
|
|
1186
1181
|
this.state.currentFrame = this.state.history.length;
|
|
1182
|
+
this.lastTimestamp = e.timestamp;
|
|
1187
1183
|
}
|
|
1188
1184
|
/** Clears timeline history and resets playhead/genesis to the current reactor state. */
|
|
1189
1185
|
clear() {
|
|
1190
1186
|
this.pause();
|
|
1191
1187
|
this.playbackTimeoutId = -1;
|
|
1192
|
-
this.state.history =
|
|
1193
|
-
this.state.currentFrame = 0;
|
|
1188
|
+
this.state.history.length = this.state.currentFrame = 0;
|
|
1194
1189
|
this.state.initialState = this.rtr.snapshot();
|
|
1190
|
+
this.lastTimestamp = performance.now();
|
|
1195
1191
|
}
|
|
1196
1192
|
// ===========================================================================
|
|
1197
1193
|
// THE TIME MACHINE (Manual Controls)
|
|
@@ -1204,7 +1200,7 @@ var TimeTravelPlugin = class extends BaseReactorPlugin {
|
|
|
1204
1200
|
const e = this.state.history[forward ? this.state.currentFrame : this.state.currentFrame - 1];
|
|
1205
1201
|
if (!e) break;
|
|
1206
1202
|
if (forward) e.type === "delete" ? deleteAny(this.rtr.core, e.path) : setAny(this.rtr.core, e.path, deepClone(e.value, this.rtr.config));
|
|
1207
|
-
else !e.
|
|
1203
|
+
else !e.hadKey ? deleteAny(this.rtr.core, e.path) : setAny(this.rtr.core, e.path, deepClone(e.oldValue, this.rtr.config));
|
|
1208
1204
|
forward ? this.state.currentFrame++ : this.state.currentFrame--;
|
|
1209
1205
|
if (e.rejected) this.rtr.log(`[Reactor ${this.name} Plug] ${forward ? "Replaying" : "Reversing"} REJECTED intent at "${e.path}"`);
|
|
1210
1206
|
}
|
|
@@ -1227,9 +1223,9 @@ var TimeTravelPlugin = class extends BaseReactorPlugin {
|
|
|
1227
1223
|
async automove(forward = true) {
|
|
1228
1224
|
this.state.paused = false;
|
|
1229
1225
|
while ((forward ? this.state.currentFrame < this.state.history.length : this.state.currentFrame > 0) && !this.state.paused) {
|
|
1230
|
-
const currIndex = forward ? this.state.currentFrame : this.state.currentFrame - 1, e = this.state.history[
|
|
1226
|
+
const currIndex = forward ? this.state.currentFrame : this.state.currentFrame - 1, e = this.state.history[forward ? currIndex + 1 : currIndex - 1];
|
|
1231
1227
|
this.jumpTo(this.state.currentFrame + (forward ? 1 : -1), true);
|
|
1232
|
-
if (
|
|
1228
|
+
if (e?.timedelta > 0) await new Promise((res) => this.playbackTimeoutId = setTimeout2(() => res(0), Math.min(e.timedelta, this.config.maxPlaybackDelay), this.signal));
|
|
1233
1229
|
}
|
|
1234
1230
|
this.state.paused = true;
|
|
1235
1231
|
}
|
|
@@ -1243,21 +1239,24 @@ var TimeTravelPlugin = class extends BaseReactorPlugin {
|
|
|
1243
1239
|
// TELEMETRY & I/O (Session Import/Export)
|
|
1244
1240
|
// ===========================================================================
|
|
1245
1241
|
/** Exports the current session as a JSON string. */
|
|
1246
|
-
export() {
|
|
1247
|
-
|
|
1242
|
+
export(replacer, space) {
|
|
1243
|
+
try {
|
|
1244
|
+
return JSON.stringify(this.state, replacer, space);
|
|
1245
|
+
} catch (e) {
|
|
1246
|
+
return this.rtr.log(`[Reactor ${this.name} Plug] Failed to export session`), "";
|
|
1247
|
+
}
|
|
1248
1248
|
}
|
|
1249
1249
|
/** Imports a session from a JSON string, allowing you to replay or analyze past states. */
|
|
1250
1250
|
import(json) {
|
|
1251
1251
|
try {
|
|
1252
1252
|
setAny(this.state, "*", JSON.parse(json));
|
|
1253
|
+
this.lastTimestamp = performance.now();
|
|
1253
1254
|
const resume = !this.state.paused, target = this.state.currentFrame;
|
|
1254
1255
|
this.state.paused = false;
|
|
1255
|
-
setAny(this.rtr.core, "*", deepClone(this.state.initialState, this.rtr.config));
|
|
1256
|
-
this.
|
|
1257
|
-
this.state.currentFrame = 0;
|
|
1258
|
-
this.jumpTo(target), resume && this.play();
|
|
1256
|
+
setAny(this.rtr.core, "*", deepClone(this.state.initialState, this.rtr.config)), this.rtr.tick();
|
|
1257
|
+
this.state.currentFrame = 0, this.jumpTo(target), resume && this.play();
|
|
1259
1258
|
} catch (e) {
|
|
1260
|
-
this.rtr.log(`[Reactor ${this.name} Plug] Failed to load session
|
|
1259
|
+
this.rtr.log(`[Reactor ${this.name} Plug] Failed to load session`);
|
|
1261
1260
|
}
|
|
1262
1261
|
}
|
|
1263
1262
|
};
|
package/dist/plugins.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { P as Paths, I as Inert, B as BaseReactorPlugin,
|
|
2
|
-
export {
|
|
1
|
+
import { P as Paths, I as Inert, B as BaseReactorPlugin, b as Reactor, a as REvent } from './index-Oie9hhE8.cjs';
|
|
2
|
+
export { c as ReactorPluginConstructor } from './index-Oie9hhE8.cjs';
|
|
3
|
+
export { H as HistoryEntry, a as TIME_TRAVEL_PLUGIN_BUILD, b as TimeTravelConfig, T as TimeTravelPlugin, c as TimeTravelState } from './timeTravel-WpgWmKu-.cjs';
|
|
3
4
|
|
|
4
5
|
interface StorageAdapterConfig {
|
|
5
6
|
debug: boolean;
|
|
@@ -108,76 +109,4 @@ declare class PersistPlugin<T extends object = any> extends BaseReactorPlugin<T,
|
|
|
108
109
|
}
|
|
109
110
|
declare const PERSIST_PLUGIN_BUILD: Partial<PersistConfig<any>>;
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
interface HistoryEntry {
|
|
113
|
-
/** Was it a 'set' or a 'delete' surgery? */
|
|
114
|
-
type: REvent<any, any>["staticType"];
|
|
115
|
-
/** The surgical address in the Reactor */
|
|
116
|
-
path: string;
|
|
117
|
-
/** The data payload at that moment */
|
|
118
|
-
value: any;
|
|
119
|
-
/** The "Undo" antidote (Previous value), if applicable */
|
|
120
|
-
oldValue: any;
|
|
121
|
-
/** Did the key for the value exist on its parent object? */
|
|
122
|
-
keyExisted: boolean;
|
|
123
|
-
/** Did the Power Line disapprove?; why? */
|
|
124
|
-
rejected: string;
|
|
125
|
-
/** For chronological re-enactment */
|
|
126
|
-
timestamp: number;
|
|
127
|
-
}
|
|
128
|
-
interface TimeTravelConfig<T extends object = any> {
|
|
129
|
-
/** Specific paths only, no "*"; instead don't pass anything */
|
|
130
|
-
paths?: Paths<T>[];
|
|
131
|
-
/** Maximum number of history entries to keep (Memory Cap), you lose replaying Sessions or the Genesis */
|
|
132
|
-
maxHistoryLength: number;
|
|
133
|
-
/** Max delay between events during playback (ms) */
|
|
134
|
-
maxPlaybackDelay: number;
|
|
135
|
-
}
|
|
136
|
-
interface TimeTravelState {
|
|
137
|
-
/** The "Timeline" of mutations (Chronological Log) */
|
|
138
|
-
history: HistoryEntry[];
|
|
139
|
-
/** The "Genesis" snapshot (Raw Data) */
|
|
140
|
-
initialState: any;
|
|
141
|
-
/** The manual playhead (Index in the Timeline) */
|
|
142
|
-
currentFrame: number;
|
|
143
|
-
/** Whether playback is currently paused (Automatic Replay) */
|
|
144
|
-
paused: boolean;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* The Flight Recorder (Black Box).
|
|
148
|
-
* - Implements S.I.A. logic to allow playback, teleportation, redos and undos.
|
|
149
|
-
*/
|
|
150
|
-
declare class TimeTravelPlugin<T extends object = any> extends BaseReactorPlugin<T, TimeTravelConfig<T>, TimeTravelState> {
|
|
151
|
-
static readonly plugName = "timeTravel";
|
|
152
|
-
protected playbackTimeoutId: number;
|
|
153
|
-
constructor(config?: Partial<TimeTravelConfig<T>>, rtr?: Reactor<T>);
|
|
154
|
-
wire(): void;
|
|
155
|
-
protected handlePathsState({ value: paths, oldValue: prevs }: REvent<TimeTravelConfig<T>, "paths">): void;
|
|
156
|
-
/** Chronicling the lifecycle of the system, Captures the essence of every mutation wave that bubbles up. */
|
|
157
|
-
protected record(e: REvent<T, any>): void;
|
|
158
|
-
/** Clears timeline history and resets playhead/genesis to the current reactor state. */
|
|
159
|
-
clear(): void;
|
|
160
|
-
/** Instant state reconstruction (Teleport). Glides through deltas natively. */
|
|
161
|
-
jumpTo(index?: number, keepShield?: boolean): void;
|
|
162
|
-
/** Step through time, Moves the playhead and teleports the state. */
|
|
163
|
-
step(stride?: number, forward?: boolean): void;
|
|
164
|
-
/** Step back in time, Moves the playhead backward and teleports the state. */
|
|
165
|
-
undo: () => void;
|
|
166
|
-
/** Step forward in time, Restores previously undone actions. */
|
|
167
|
-
redo: () => void;
|
|
168
|
-
/** Core automove engine. Replays or rewinds the "Story" by respecting time gaps. */
|
|
169
|
-
automove(forward?: boolean): Promise<void>;
|
|
170
|
-
/** Start chronological re-enactment of the session. */
|
|
171
|
-
play: () => Promise<void>;
|
|
172
|
-
/** Start reverse chronological re-enactment of the session. */
|
|
173
|
-
rewind: () => Promise<void>;
|
|
174
|
-
/** Pauses the live VCR playback. */
|
|
175
|
-
pause: () => void;
|
|
176
|
-
/** Exports the current session as a JSON string. */
|
|
177
|
-
export(): string;
|
|
178
|
-
/** Imports a session from a JSON string, allowing you to replay or analyze past states. */
|
|
179
|
-
import(json: string): void;
|
|
180
|
-
}
|
|
181
|
-
declare const TIME_TRAVEL_PLUGIN_BUILD: Partial<TimeTravelConfig>;
|
|
182
|
-
|
|
183
|
-
export { type AsyncStorageAdapterConstructor, BaseReactorPlugin, BaseStorageAdapter, type HistoryEntry, INDEXED_DB_ADAPTER_BUILD, IndexedDBAdapter, type IndexedDBAdapterConfig, LocalStorageAdapter, MemoryStorageAdapter, type MemoryStorageAdapterConfig, PERSIST_PLUGIN_BUILD, type PersistConfig, PersistPlugin, StorageAdapter, type StorageAdapterConfig, type StorageAdapterConstructor, TIME_TRAVEL_PLUGIN_BUILD, type TimeTravelConfig, TimeTravelPlugin, type TimeTravelState };
|
|
112
|
+
export { type AsyncStorageAdapterConstructor, BaseReactorPlugin, BaseStorageAdapter, INDEXED_DB_ADAPTER_BUILD, IndexedDBAdapter, type IndexedDBAdapterConfig, LocalStorageAdapter, MemoryStorageAdapter, type MemoryStorageAdapterConfig, PERSIST_PLUGIN_BUILD, type PersistConfig, PersistPlugin, StorageAdapter, type StorageAdapterConfig, type StorageAdapterConstructor };
|
package/dist/plugins.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { P as Paths, I as Inert, B as BaseReactorPlugin,
|
|
2
|
-
export {
|
|
1
|
+
import { P as Paths, I as Inert, B as BaseReactorPlugin, b as Reactor, a as REvent } from './index-Oie9hhE8.js';
|
|
2
|
+
export { c as ReactorPluginConstructor } from './index-Oie9hhE8.js';
|
|
3
|
+
export { H as HistoryEntry, a as TIME_TRAVEL_PLUGIN_BUILD, b as TimeTravelConfig, T as TimeTravelPlugin, c as TimeTravelState } from './timeTravel-B1vedDQc.js';
|
|
3
4
|
|
|
4
5
|
interface StorageAdapterConfig {
|
|
5
6
|
debug: boolean;
|
|
@@ -108,76 +109,4 @@ declare class PersistPlugin<T extends object = any> extends BaseReactorPlugin<T,
|
|
|
108
109
|
}
|
|
109
110
|
declare const PERSIST_PLUGIN_BUILD: Partial<PersistConfig<any>>;
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
interface HistoryEntry {
|
|
113
|
-
/** Was it a 'set' or a 'delete' surgery? */
|
|
114
|
-
type: REvent<any, any>["staticType"];
|
|
115
|
-
/** The surgical address in the Reactor */
|
|
116
|
-
path: string;
|
|
117
|
-
/** The data payload at that moment */
|
|
118
|
-
value: any;
|
|
119
|
-
/** The "Undo" antidote (Previous value), if applicable */
|
|
120
|
-
oldValue: any;
|
|
121
|
-
/** Did the key for the value exist on its parent object? */
|
|
122
|
-
keyExisted: boolean;
|
|
123
|
-
/** Did the Power Line disapprove?; why? */
|
|
124
|
-
rejected: string;
|
|
125
|
-
/** For chronological re-enactment */
|
|
126
|
-
timestamp: number;
|
|
127
|
-
}
|
|
128
|
-
interface TimeTravelConfig<T extends object = any> {
|
|
129
|
-
/** Specific paths only, no "*"; instead don't pass anything */
|
|
130
|
-
paths?: Paths<T>[];
|
|
131
|
-
/** Maximum number of history entries to keep (Memory Cap), you lose replaying Sessions or the Genesis */
|
|
132
|
-
maxHistoryLength: number;
|
|
133
|
-
/** Max delay between events during playback (ms) */
|
|
134
|
-
maxPlaybackDelay: number;
|
|
135
|
-
}
|
|
136
|
-
interface TimeTravelState {
|
|
137
|
-
/** The "Timeline" of mutations (Chronological Log) */
|
|
138
|
-
history: HistoryEntry[];
|
|
139
|
-
/** The "Genesis" snapshot (Raw Data) */
|
|
140
|
-
initialState: any;
|
|
141
|
-
/** The manual playhead (Index in the Timeline) */
|
|
142
|
-
currentFrame: number;
|
|
143
|
-
/** Whether playback is currently paused (Automatic Replay) */
|
|
144
|
-
paused: boolean;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* The Flight Recorder (Black Box).
|
|
148
|
-
* - Implements S.I.A. logic to allow playback, teleportation, redos and undos.
|
|
149
|
-
*/
|
|
150
|
-
declare class TimeTravelPlugin<T extends object = any> extends BaseReactorPlugin<T, TimeTravelConfig<T>, TimeTravelState> {
|
|
151
|
-
static readonly plugName = "timeTravel";
|
|
152
|
-
protected playbackTimeoutId: number;
|
|
153
|
-
constructor(config?: Partial<TimeTravelConfig<T>>, rtr?: Reactor<T>);
|
|
154
|
-
wire(): void;
|
|
155
|
-
protected handlePathsState({ value: paths, oldValue: prevs }: REvent<TimeTravelConfig<T>, "paths">): void;
|
|
156
|
-
/** Chronicling the lifecycle of the system, Captures the essence of every mutation wave that bubbles up. */
|
|
157
|
-
protected record(e: REvent<T, any>): void;
|
|
158
|
-
/** Clears timeline history and resets playhead/genesis to the current reactor state. */
|
|
159
|
-
clear(): void;
|
|
160
|
-
/** Instant state reconstruction (Teleport). Glides through deltas natively. */
|
|
161
|
-
jumpTo(index?: number, keepShield?: boolean): void;
|
|
162
|
-
/** Step through time, Moves the playhead and teleports the state. */
|
|
163
|
-
step(stride?: number, forward?: boolean): void;
|
|
164
|
-
/** Step back in time, Moves the playhead backward and teleports the state. */
|
|
165
|
-
undo: () => void;
|
|
166
|
-
/** Step forward in time, Restores previously undone actions. */
|
|
167
|
-
redo: () => void;
|
|
168
|
-
/** Core automove engine. Replays or rewinds the "Story" by respecting time gaps. */
|
|
169
|
-
automove(forward?: boolean): Promise<void>;
|
|
170
|
-
/** Start chronological re-enactment of the session. */
|
|
171
|
-
play: () => Promise<void>;
|
|
172
|
-
/** Start reverse chronological re-enactment of the session. */
|
|
173
|
-
rewind: () => Promise<void>;
|
|
174
|
-
/** Pauses the live VCR playback. */
|
|
175
|
-
pause: () => void;
|
|
176
|
-
/** Exports the current session as a JSON string. */
|
|
177
|
-
export(): string;
|
|
178
|
-
/** Imports a session from a JSON string, allowing you to replay or analyze past states. */
|
|
179
|
-
import(json: string): void;
|
|
180
|
-
}
|
|
181
|
-
declare const TIME_TRAVEL_PLUGIN_BUILD: Partial<TimeTravelConfig>;
|
|
182
|
-
|
|
183
|
-
export { type AsyncStorageAdapterConstructor, BaseReactorPlugin, BaseStorageAdapter, type HistoryEntry, INDEXED_DB_ADAPTER_BUILD, IndexedDBAdapter, type IndexedDBAdapterConfig, LocalStorageAdapter, MemoryStorageAdapter, type MemoryStorageAdapterConfig, PERSIST_PLUGIN_BUILD, type PersistConfig, PersistPlugin, StorageAdapter, type StorageAdapterConfig, type StorageAdapterConstructor, TIME_TRAVEL_PLUGIN_BUILD, type TimeTravelConfig, TimeTravelPlugin, type TimeTravelState };
|
|
112
|
+
export { type AsyncStorageAdapterConstructor, BaseReactorPlugin, BaseStorageAdapter, INDEXED_DB_ADAPTER_BUILD, IndexedDBAdapter, type IndexedDBAdapterConfig, LocalStorageAdapter, MemoryStorageAdapter, type MemoryStorageAdapterConfig, PERSIST_PLUGIN_BUILD, type PersistConfig, PersistPlugin, StorageAdapter, type StorageAdapterConfig, type StorageAdapterConstructor };
|