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/super.global.js
CHANGED
|
@@ -18,7 +18,7 @@ var sia = (() => {
|
|
|
18
18
|
};
|
|
19
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
20
|
|
|
21
|
-
// src/super.ts
|
|
21
|
+
// src/ts/super.ts
|
|
22
22
|
var super_exports = {};
|
|
23
23
|
__export(super_exports, {
|
|
24
24
|
CTX: () => CTX,
|
|
@@ -56,8 +56,10 @@ var sia = (() => {
|
|
|
56
56
|
volatile: () => volatile
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
// src/core/consts.ts
|
|
59
|
+
// src/ts/core/consts.ts
|
|
60
60
|
var CTX = {
|
|
61
|
+
/** Flag indicating whether the application is running in development mode. */
|
|
62
|
+
isDevEnv: "undefined" !== typeof process ? process.env.NODE_ENV !== "production" : true,
|
|
61
63
|
/** active `Autotracker` instance, override for automatic dependency collection on `Reactor` traps. */
|
|
62
64
|
autotracker: null
|
|
63
65
|
};
|
|
@@ -76,7 +78,7 @@ var sia = (() => {
|
|
|
76
78
|
var NOOP = () => {
|
|
77
79
|
};
|
|
78
80
|
|
|
79
|
-
// src/utils/obj.ts
|
|
81
|
+
// src/ts/utils/obj.ts
|
|
80
82
|
var arrRx = /^([^\[\]]+)\[(\d+)\]$/;
|
|
81
83
|
function isObj(obj, arraycheck = true) {
|
|
82
84
|
return "object" === typeof obj && obj !== null && (arraycheck ? !Array.isArray(obj) : true);
|
|
@@ -93,10 +95,10 @@ var sia = (() => {
|
|
|
93
95
|
function getAny(source, key, separator = ".", keyFunc) {
|
|
94
96
|
if (key === "*") return source;
|
|
95
97
|
if (!key.includes(separator)) return source[keyFunc ? keyFunc(key) : key];
|
|
96
|
-
const
|
|
98
|
+
const keys2 = key.split(separator);
|
|
97
99
|
let currObj = source;
|
|
98
|
-
for (let i = 0, len =
|
|
99
|
-
const key2 = keyFunc ? keyFunc(
|
|
100
|
+
for (let i = 0, len = keys2.length; i < len; i++) {
|
|
101
|
+
const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRx);
|
|
100
102
|
if (match) {
|
|
101
103
|
const [, key3, iStr] = match;
|
|
102
104
|
if (!Array.isArray(currObj[key3]) || !(key3 in currObj)) return void 0;
|
|
@@ -111,9 +113,9 @@ var sia = (() => {
|
|
|
111
113
|
function setAny(target, key, value, separator = ".", keyFunc) {
|
|
112
114
|
if (key === "*") return Object.assign(target, value);
|
|
113
115
|
if (!key.includes(separator)) return void (target[keyFunc ? keyFunc(key) : key] = value);
|
|
114
|
-
const
|
|
115
|
-
for (let currObj = target, i = 0, len =
|
|
116
|
-
const key2 = keyFunc ? keyFunc(
|
|
116
|
+
const keys2 = key.split(separator);
|
|
117
|
+
for (let currObj = target, i = 0, len = keys2.length; i < len; i++) {
|
|
118
|
+
const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRx);
|
|
117
119
|
if (match) {
|
|
118
120
|
const [, key3, iStr] = match;
|
|
119
121
|
if (!Array.isArray(currObj[key3])) currObj[key3] = [];
|
|
@@ -127,14 +129,14 @@ var sia = (() => {
|
|
|
127
129
|
}
|
|
128
130
|
function deleteAny(target, key, separator = ".", keyFunc) {
|
|
129
131
|
if (key === "*") {
|
|
130
|
-
const
|
|
131
|
-
for (let i = 0, len =
|
|
132
|
+
const keys3 = Object.keys(target);
|
|
133
|
+
for (let i = 0, len = keys3.length; i < len; i++) delete target[keys3[i]];
|
|
132
134
|
return;
|
|
133
135
|
}
|
|
134
136
|
if (!key.includes(separator)) return void delete target[keyFunc ? keyFunc(key) : key];
|
|
135
|
-
const
|
|
136
|
-
for (let currObj = target, i = 0, len =
|
|
137
|
-
const key2 = keyFunc ? keyFunc(
|
|
137
|
+
const keys2 = key.split(separator);
|
|
138
|
+
for (let currObj = target, i = 0, len = keys2.length; i < len; i++) {
|
|
139
|
+
const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRx);
|
|
138
140
|
if (match) {
|
|
139
141
|
const [, key3, iStr] = match;
|
|
140
142
|
if (!Array.isArray(currObj[key3]) || !(key3 in currObj)) return;
|
|
@@ -150,9 +152,9 @@ var sia = (() => {
|
|
|
150
152
|
function inAny(source, key, separator = ".", keyFunc) {
|
|
151
153
|
if (key === "*") return true;
|
|
152
154
|
if (!key.includes(separator)) return key in source;
|
|
153
|
-
const
|
|
154
|
-
for (let currObj = source, i = 0, len =
|
|
155
|
-
const key2 = keyFunc ? keyFunc(
|
|
155
|
+
const keys2 = key.split(separator);
|
|
156
|
+
for (let currObj = source, i = 0, len = keys2.length; i < len; i++) {
|
|
157
|
+
const key2 = keyFunc ? keyFunc(keys2[i]) : keys2[i], match = key2.includes("[") && key2.match(arrRx);
|
|
156
158
|
if (match) {
|
|
157
159
|
const [, key3, iStr] = match;
|
|
158
160
|
if (!Array.isArray(currObj[key3]) || !(key3 in currObj)) return false;
|
|
@@ -192,25 +194,25 @@ var sia = (() => {
|
|
|
192
194
|
if (!canHandle(obj, config, false)) return obj;
|
|
193
195
|
const clone = config.preserveContext ? Object.create(Object.getPrototypeOf(obj)) : Array.isArray(obj) ? [] : {};
|
|
194
196
|
seen.set(obj, clone);
|
|
195
|
-
const
|
|
196
|
-
for (let i = 0, len =
|
|
197
|
+
const keys2 = config.preserveContext ? Reflect.ownKeys(obj) : Object.keys(obj);
|
|
198
|
+
for (let i = 0, len = keys2.length; i < len; i++) clone[keys2[i]] = deepClone(obj[keys2[i]], config, seen);
|
|
197
199
|
return clone;
|
|
198
200
|
}
|
|
199
201
|
function nuke(target) {
|
|
200
202
|
let proto = target;
|
|
201
203
|
while (proto && proto !== Object.prototype) {
|
|
202
|
-
const
|
|
203
|
-
for (let i = 0, len =
|
|
204
|
-
if (
|
|
205
|
-
const desc = Object.getOwnPropertyDescriptor(proto,
|
|
204
|
+
const keys2 = Object.getOwnPropertyNames(proto);
|
|
205
|
+
for (let i = 0, len = keys2.length; i < len; i++) {
|
|
206
|
+
if (keys2[i] === "constructor") continue;
|
|
207
|
+
const desc = Object.getOwnPropertyDescriptor(proto, keys2[i]);
|
|
206
208
|
if (desc && ("function" === typeof desc.value || desc.get || desc.set)) continue;
|
|
207
|
-
proto[
|
|
209
|
+
proto[keys2[i]] = null;
|
|
208
210
|
}
|
|
209
211
|
proto = Object.getPrototypeOf(proto);
|
|
210
212
|
}
|
|
211
213
|
}
|
|
212
214
|
|
|
213
|
-
// src/core/event.ts
|
|
215
|
+
// src/ts/core/event.ts
|
|
214
216
|
var ReactorEvent = class _ReactorEvent {
|
|
215
217
|
/** No active propagation phase. */
|
|
216
218
|
static NONE = 0;
|
|
@@ -333,7 +335,7 @@ var sia = (() => {
|
|
|
333
335
|
}
|
|
334
336
|
};
|
|
335
337
|
|
|
336
|
-
// src/core/reactor.ts
|
|
338
|
+
// src/ts/core/reactor.ts
|
|
337
339
|
var Reactor = class {
|
|
338
340
|
log = NOOP;
|
|
339
341
|
core;
|
|
@@ -361,27 +363,27 @@ var sia = (() => {
|
|
|
361
363
|
listeners;
|
|
362
364
|
/**
|
|
363
365
|
* Creates a new Reactor instance.
|
|
364
|
-
* @param
|
|
366
|
+
* @param target Initial state target.
|
|
365
367
|
* @param build Reactor bootstrap/build configuration.
|
|
366
368
|
* @example
|
|
367
369
|
* const rtr = new Reactor({ count: 0 });
|
|
368
370
|
*/
|
|
369
|
-
constructor(
|
|
371
|
+
constructor(target = {}, build) {
|
|
370
372
|
this[INERTIA] = true;
|
|
371
373
|
this.config = { crossRealms: false, smartCloning: false, eventBubbling: true, lineageTracing: false, preserveContext: false, equalityFunction: Object.is, batchingFunction: RTR_BATCH, ...build };
|
|
372
|
-
this.core = this.proxied(
|
|
374
|
+
this.core = this.proxied(target);
|
|
373
375
|
if (build) this.canLog = !!build.debug;
|
|
374
376
|
}
|
|
375
|
-
proxied(
|
|
376
|
-
if (!
|
|
377
|
-
|
|
378
|
-
if (this.config.referenceTracking && parent && key && !this.link(
|
|
379
|
-
const cached = this.proxyCache.get(
|
|
377
|
+
proxied(target, rejectable = false, indiffable = false, parent, key, path) {
|
|
378
|
+
if (!target || "object" !== typeof target) return target;
|
|
379
|
+
target = target[RAW] || target;
|
|
380
|
+
if (this.config.referenceTracking && parent && key && !this.link(target, parent, key, false)) return target;
|
|
381
|
+
const cached = this.proxyCache.get(target);
|
|
380
382
|
if (cached) return cached;
|
|
381
|
-
if (
|
|
382
|
-
rejectable ||=
|
|
383
|
-
indiffable ||=
|
|
384
|
-
const proxy = new Proxy(
|
|
383
|
+
if (target[INERTIA] || !canHandle(target, this.config, false)) return target;
|
|
384
|
+
rejectable ||= target[REJECTABLE];
|
|
385
|
+
indiffable ||= target[INDIFFABLE];
|
|
386
|
+
const proxy = new Proxy(target, {
|
|
385
387
|
// Robust Proxy handler
|
|
386
388
|
get: (object, key2, receiver) => {
|
|
387
389
|
if (key2 === RAW) return this.log(`\u{1F440} [Reactor \`get\` Trap] Peeked at ${object}`), object;
|
|
@@ -394,10 +396,10 @@ var sia = (() => {
|
|
|
394
396
|
for (let i = 0, len = this.config.lineageTracing ? paths.length : 1; i < len; i++) {
|
|
395
397
|
const currPath = this.config.lineageTracing ? paths[i] : fullPath, cords = this.getters.get(currPath);
|
|
396
398
|
if (!cords && !wildcords) continue;
|
|
397
|
-
const
|
|
399
|
+
const target2 = { path: currPath, value, key: keyStr, hadKey: true, object: receiver }, payload = { type: "get", target: target2, currentTarget: target2, root: this.core, rejectable };
|
|
398
400
|
if (cords) value = this.mediate(currPath, payload, "get", cords);
|
|
399
401
|
if (!wildcords) continue;
|
|
400
|
-
|
|
402
|
+
target2.value = value;
|
|
401
403
|
value = this.mediate("*", payload, "get", wildcords);
|
|
402
404
|
}
|
|
403
405
|
}
|
|
@@ -405,7 +407,7 @@ var sia = (() => {
|
|
|
405
407
|
},
|
|
406
408
|
set: (object, key2, value, receiver) => {
|
|
407
409
|
let unchanged, safeValue, safeOldValue, terminated = false;
|
|
408
|
-
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),
|
|
410
|
+
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);
|
|
409
411
|
this.log(`\u270F\uFE0F [Reactor \`set\` Trap] Initiated for "${keyStr}" on "${paths}"`), CTX.autotracker?.track(fullPath, this, true);
|
|
410
412
|
if (this.config.referenceTracking || !indiffable) {
|
|
411
413
|
safeOldValue = oldValue?.[RAW] || oldValue;
|
|
@@ -419,13 +421,13 @@ var sia = (() => {
|
|
|
419
421
|
for (let i = 0; i < loopLen; i++) {
|
|
420
422
|
const currPath = this.config.lineageTracing ? paths[i] : fullPath, cords = this.setters.get(currPath);
|
|
421
423
|
if (!cords && !wildcords) continue;
|
|
422
|
-
const
|
|
424
|
+
const target2 = { path: currPath, value, oldValue, key: keyStr, hadKey, object: receiver }, payload = { type: "set", target: target2, currentTarget: target2, root: this.core, terminated, rejectable };
|
|
423
425
|
if (cords) {
|
|
424
426
|
const result2 = this.mediate(currPath, payload, "set", cords);
|
|
425
427
|
if (!(terminated ||= payload.terminated)) value = result2;
|
|
426
428
|
}
|
|
427
429
|
if (!wildcords) continue;
|
|
428
|
-
|
|
430
|
+
target2.value = value;
|
|
429
431
|
const result = this.mediate("*", payload, "set", wildcords);
|
|
430
432
|
if (!(terminated ||= payload.terminated)) value = result;
|
|
431
433
|
}
|
|
@@ -436,14 +438,14 @@ var sia = (() => {
|
|
|
436
438
|
if (this.config.referenceTracking && !unchanged) this.config.smartCloning && this.stamp(object), this.unlink(safeOldValue, object, keyStr), this.link(safeValue, object, keyStr);
|
|
437
439
|
if (this.watchers || this.listeners)
|
|
438
440
|
for (let i = 0; i < loopLen; i++) {
|
|
439
|
-
const currPath = this.config.lineageTracing ? paths[i] : fullPath,
|
|
440
|
-
this.notify(currPath, { type: "set", target, currentTarget:
|
|
441
|
+
const currPath = this.config.lineageTracing ? paths[i] : fullPath, target2 = { path: currPath, value, oldValue, key: keyStr, hadKey, object: receiver };
|
|
442
|
+
this.notify(currPath, { type: "set", target: target2, currentTarget: target2, root: this.core, terminated, rejectable });
|
|
441
443
|
}
|
|
442
444
|
return true;
|
|
443
445
|
},
|
|
444
446
|
deleteProperty: (object, key2) => {
|
|
445
447
|
let value, receiver = this.proxyCache.get(object), terminated = false;
|
|
446
|
-
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),
|
|
448
|
+
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);
|
|
447
449
|
this.log(`\u{1F5D1}\uFE0F [Reactor \`deleteProperty\` Trap] Initiated for "${keyStr}" on "${paths}"`), CTX.autotracker?.track(fullPath, this, true);
|
|
448
450
|
if (this.config.deleteProperty) terminated = (value = this.config.deleteProperty(object, key2, oldValue, receiver, paths)) === TERMINATOR;
|
|
449
451
|
if (this.deleters) {
|
|
@@ -451,7 +453,7 @@ var sia = (() => {
|
|
|
451
453
|
for (let i = 0; i < loopLen; i++) {
|
|
452
454
|
const currPath = this.config.lineageTracing ? paths[i] : fullPath, cords = this.deleters.get(currPath);
|
|
453
455
|
if (!cords && !wildcords) continue;
|
|
454
|
-
const
|
|
456
|
+
const target2 = { path: currPath, value, oldValue, key: keyStr, hadKey, object: receiver }, payload = { type: "delete", target: target2, currentTarget: target2, root: this.core, rejectable };
|
|
455
457
|
if (cords) {
|
|
456
458
|
const result2 = this.mediate(currPath, payload, "delete", cords);
|
|
457
459
|
if (!(terminated ||= payload.terminated)) value = result2;
|
|
@@ -467,8 +469,8 @@ var sia = (() => {
|
|
|
467
469
|
if (this.config.referenceTracking) this.config.smartCloning && this.stamp(object), this.unlink(oldValue?.[RAW] || oldValue, object, keyStr);
|
|
468
470
|
if (this.watchers || this.listeners)
|
|
469
471
|
for (let i = 0; i < loopLen; i++) {
|
|
470
|
-
const currPath = this.config.lineageTracing ? paths[i] : fullPath,
|
|
471
|
-
this.notify(currPath, { type: "delete", target, currentTarget:
|
|
472
|
+
const currPath = this.config.lineageTracing ? paths[i] : fullPath, target2 = { path: currPath, value, oldValue, key: keyStr, hadKey, object: receiver };
|
|
473
|
+
this.notify(currPath, { type: "delete", target: target2, currentTarget: target2, root: this.core, rejectable });
|
|
472
474
|
}
|
|
473
475
|
return true;
|
|
474
476
|
},
|
|
@@ -494,7 +496,7 @@ var sia = (() => {
|
|
|
494
496
|
return ownKeys;
|
|
495
497
|
}
|
|
496
498
|
});
|
|
497
|
-
return this.proxyCache.set(
|
|
499
|
+
return this.proxyCache.set(target, proxy), proxy;
|
|
498
500
|
}
|
|
499
501
|
trace(target, path, paths = [], seen = /* @__PURE__ */ new WeakSet()) {
|
|
500
502
|
if (Object.is(target, this.core[RAW] || this.core)) return paths.push(path), paths;
|
|
@@ -586,7 +588,7 @@ var sia = (() => {
|
|
|
586
588
|
fire([path, object, value], e, isCapture, cords = this.listeners.get(path)) {
|
|
587
589
|
if (!cords) return;
|
|
588
590
|
e.type = path !== e.target.path ? "update" : e.staticType;
|
|
589
|
-
e.currentTarget = { path, value, oldValue: e.type !== "update" ? e.target.oldValue : void 0, key: e.type !== "update" ? path : path.slice(path.lastIndexOf(".") + 1) || "",
|
|
591
|
+
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 };
|
|
590
592
|
for (let i = 0, len = cords.length, tDepth; i < len; i++) {
|
|
591
593
|
if (e.immediatePropagationStopped) break;
|
|
592
594
|
if (cords[i].capture !== isCapture) continue;
|
|
@@ -641,24 +643,23 @@ var sia = (() => {
|
|
|
641
643
|
}
|
|
642
644
|
getContext(path) {
|
|
643
645
|
const lastDot = path.lastIndexOf("."), value = getAny(this.core, path), object = lastDot === -1 ? this.core : getAny(this.core, path.slice(0, lastDot));
|
|
644
|
-
return { path, value, key: path.slice(lastDot + 1) || "",
|
|
646
|
+
return { path, value, key: path.slice(lastDot + 1) || "", hadKey: true, object };
|
|
645
647
|
}
|
|
646
648
|
bindSignal(cord, sig) {
|
|
647
649
|
if (sig) sig.aborted ? cord.clup() : sig.addEventListener("abort", cord.clup, { once: true });
|
|
648
650
|
return cord.sclup = !sig || sig.aborted ? NOOP : () => sig.removeEventListener("abort", cord.clup), cord.clup;
|
|
649
651
|
}
|
|
650
|
-
cloned(
|
|
651
|
-
if (!
|
|
652
|
-
obj =
|
|
653
|
-
const cloned = seen.get(obj);
|
|
652
|
+
cloned(target, raw, seen = /* @__PURE__ */ new WeakMap()) {
|
|
653
|
+
if (!target || "object" !== typeof target) return target;
|
|
654
|
+
const obj = target[RAW] || target, cloned = seen.get(obj);
|
|
654
655
|
if (cloned) return cloned;
|
|
655
656
|
if (!canHandle(obj, this.config, false)) return obj;
|
|
656
657
|
const version = obj[VERSION] || 0, cached = !raw && this.config.smartCloning && (this.snapCache ??= /* @__PURE__ */ new WeakMap()).get(obj);
|
|
657
658
|
if (cached && obj[SSVERSION] === version) return cached;
|
|
658
|
-
const clone = !raw ? this.config.preserveContext ? Object.create(Object.getPrototypeOf(obj)) : Array.isArray(obj) ? [] : {} : obj
|
|
659
|
+
const clone = !raw ? this.config.preserveContext ? Object.create(Object.getPrototypeOf(obj)) : Array.isArray(obj) ? [] : {} : obj;
|
|
659
660
|
seen.set(obj, clone);
|
|
660
|
-
const
|
|
661
|
-
for (let i = 0, len =
|
|
661
|
+
const keys2 = this.config.preserveContext ? Reflect.ownKeys(obj) : Object.keys(obj);
|
|
662
|
+
for (let i = 0, len = keys2.length; i < len; i++) clone[keys2[i]] = this.cloned(obj[keys2[i]], raw, seen);
|
|
662
663
|
if (!raw && this.config.smartCloning) this.snapCache.set(obj, clone), obj[SSVERSION] = version;
|
|
663
664
|
return clone;
|
|
664
665
|
}
|
|
@@ -839,19 +840,8 @@ var sia = (() => {
|
|
|
839
840
|
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;
|
|
840
841
|
return false;
|
|
841
842
|
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
* You could alternatively use or serialize your proxied state "as is" except the environment demands no proxies or new references.
|
|
845
|
-
* @param raw Use raw (deep unproxied & uncloned) version of branch.
|
|
846
|
-
* @param branch Branch to clone.
|
|
847
|
-
* @returns Snapshot deep or smart (structurally shared) clone.
|
|
848
|
-
* @example
|
|
849
|
-
* const snap = rtr.snapshot();
|
|
850
|
-
* @example
|
|
851
|
-
* const snap = rtr.snapshot(false, rtr.core.history.past);
|
|
852
|
-
*/
|
|
853
|
-
snapshot(raw = !this.config.smartCloning, branch = this.core) {
|
|
854
|
-
return this.cloned(branch, raw);
|
|
843
|
+
snapshot(raw = !this.config.smartCloning, branch) {
|
|
844
|
+
return this.cloned(arguments.length < 2 ? this.core : branch, raw);
|
|
855
845
|
}
|
|
856
846
|
/**
|
|
857
847
|
* Cascades object updates into direct child paths.
|
|
@@ -864,9 +854,9 @@ var sia = (() => {
|
|
|
864
854
|
*/
|
|
865
855
|
cascade({ type, currentTarget: { path, value: news, oldValue: olds } }, objectSafe = true) {
|
|
866
856
|
if (type !== "set" && type !== "delete" || !canHandle(news, this.config) || (objectSafe ? !canHandle(olds, this.config) : false)) return;
|
|
867
|
-
const obj = objectSafe ? mergeObjs(olds, news) : news,
|
|
857
|
+
const obj = objectSafe ? mergeObjs(olds, news) : news, keys2 = Object.keys(obj);
|
|
868
858
|
this.isCascading = true;
|
|
869
|
-
for (let i = 0, len =
|
|
859
|
+
for (let i = 0, len = keys2.length; i < len; i++) setAny(this.core, path === "*" ? keys2[i] : path + "." + keys2[i], obj[keys2[i]]);
|
|
870
860
|
this.isCascading = false;
|
|
871
861
|
}
|
|
872
862
|
/**
|
|
@@ -902,11 +892,11 @@ var sia = (() => {
|
|
|
902
892
|
}
|
|
903
893
|
};
|
|
904
894
|
|
|
905
|
-
// src/core/mixins.ts
|
|
906
|
-
var methods = ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "cascade", "
|
|
895
|
+
// src/ts/core/mixins.ts
|
|
896
|
+
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"];
|
|
907
897
|
function reactive(target, build, preferences = NIL) {
|
|
908
898
|
if ("__Reactor__" in target) return target;
|
|
909
|
-
const descriptors = {}, rtr =
|
|
899
|
+
const descriptors = {}, rtr = getReactor(target, true, build), locks = { enumerable: false, configurable: true, writable: false }, hasAffix = !!(preferences.prefix || preferences.suffix);
|
|
910
900
|
for (let i = 0, len = methods.length; i < len; i++) {
|
|
911
901
|
let key = methods[i];
|
|
912
902
|
if (hasAffix) (preferences.whitelist?.includes(key) ?? true) && (key = `${preferences.prefix || ""}${key}${preferences.suffix || ""}`);
|
|
@@ -943,6 +933,9 @@ var sia = (() => {
|
|
|
943
933
|
function isVolatile(target) {
|
|
944
934
|
return !!getRaw(target)[INDIFFABLE];
|
|
945
935
|
}
|
|
936
|
+
function getReactor(target, create = false, build) {
|
|
937
|
+
return (target instanceof Reactor ? target : target.__Reactor__) || (create ? new Reactor(target, build) : void 0);
|
|
938
|
+
}
|
|
946
939
|
function getRaw(target) {
|
|
947
940
|
return target?.[RAW] || target;
|
|
948
941
|
}
|
|
@@ -953,13 +946,15 @@ var sia = (() => {
|
|
|
953
946
|
return getRaw(target)[SSVERSION] || 0;
|
|
954
947
|
}
|
|
955
948
|
|
|
956
|
-
// src/utils.ts
|
|
949
|
+
// src/ts/utils.ts
|
|
957
950
|
var utils_exports = {};
|
|
958
951
|
__export(utils_exports, {
|
|
952
|
+
assignEl: () => assignEl,
|
|
959
953
|
bindAllMethods: () => bindAllMethods,
|
|
960
954
|
canHandle: () => canHandle,
|
|
961
955
|
clamp: () => clamp,
|
|
962
956
|
cleanKeyCombo: () => cleanKeyCombo,
|
|
957
|
+
createEl: () => createEl,
|
|
963
958
|
deepClone: () => deepClone,
|
|
964
959
|
deleteAny: () => deleteAny,
|
|
965
960
|
formatKeyForDisplay: () => formatKeyForDisplay,
|
|
@@ -988,12 +983,12 @@ var sia = (() => {
|
|
|
988
983
|
stringifyKeyEvent: () => stringifyKeyEvent
|
|
989
984
|
});
|
|
990
985
|
|
|
991
|
-
// src/utils/num.ts
|
|
986
|
+
// src/ts/utils/num.ts
|
|
992
987
|
function clamp(min = 0, val, max = Infinity) {
|
|
993
988
|
return Math.min(Math.max(val, min), max);
|
|
994
989
|
}
|
|
995
990
|
|
|
996
|
-
// src/utils/fn.ts
|
|
991
|
+
// src/ts/utils/fn.ts
|
|
997
992
|
function setTimeout2(handler, timeout, ...args) {
|
|
998
993
|
const sig = args[0] instanceof AbortSignal ? args.shift() : void 0;
|
|
999
994
|
if (sig?.aborted) return -1;
|
|
@@ -1015,7 +1010,7 @@ var sia = (() => {
|
|
|
1015
1010
|
return sig.addEventListener("abort", kill, { once: true }), id;
|
|
1016
1011
|
}
|
|
1017
1012
|
|
|
1018
|
-
// src/utils/methd.ts
|
|
1013
|
+
// src/ts/utils/methd.ts
|
|
1019
1014
|
function onAllMethods(owner, callback, skipOwn = true, nested = false) {
|
|
1020
1015
|
let proto = owner;
|
|
1021
1016
|
while (proto && proto !== Object.prototype) {
|
|
@@ -1048,7 +1043,7 @@ var sia = (() => {
|
|
|
1048
1043
|
});
|
|
1049
1044
|
}
|
|
1050
1045
|
|
|
1051
|
-
// src/utils/keys.ts
|
|
1046
|
+
// src/ts/utils/keys.ts
|
|
1052
1047
|
function parseKeyCombo(combo) {
|
|
1053
1048
|
const parts = cleanKeyCombo(combo).toLowerCase().split("+");
|
|
1054
1049
|
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)) || "" };
|
|
@@ -1111,7 +1106,24 @@ var sia = (() => {
|
|
|
1111
1106
|
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();
|
|
1112
1107
|
}
|
|
1113
1108
|
|
|
1114
|
-
// src/
|
|
1109
|
+
// src/ts/utils/dom.ts
|
|
1110
|
+
function createEl(tag, props, dataset, styles, el = tag ? document?.createElement(tag) : null) {
|
|
1111
|
+
return assignEl(el, props, dataset, styles), el;
|
|
1112
|
+
}
|
|
1113
|
+
function assignEl(el, props, dataset, styles) {
|
|
1114
|
+
if (!el) return;
|
|
1115
|
+
if (props) {
|
|
1116
|
+
for (const k of Object.keys(props)) if (props[k] !== void 0) el[k] = props[k];
|
|
1117
|
+
}
|
|
1118
|
+
if (dataset) {
|
|
1119
|
+
for (const k of Object.keys(dataset)) if (dataset[k] !== void 0) el.dataset[k] = String(dataset[k]);
|
|
1120
|
+
}
|
|
1121
|
+
if (styles) {
|
|
1122
|
+
for (const k of Object.keys(styles)) if (styles[k] !== void 0) el.style[k] = styles[k];
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
// src/ts/plugins.ts
|
|
1115
1127
|
var plugins_exports = {};
|
|
1116
1128
|
__export(plugins_exports, {
|
|
1117
1129
|
BaseReactorPlugin: () => BaseReactorPlugin,
|
|
@@ -1127,7 +1139,7 @@ var sia = (() => {
|
|
|
1127
1139
|
TimeTravelPlugin: () => TimeTravelPlugin
|
|
1128
1140
|
});
|
|
1129
1141
|
|
|
1130
|
-
// src/plugins/base.ts
|
|
1142
|
+
// src/ts/plugins/base.ts
|
|
1131
1143
|
var BaseReactorPlugin = class {
|
|
1132
1144
|
static plugName;
|
|
1133
1145
|
get name() {
|
|
@@ -1165,7 +1177,7 @@ var sia = (() => {
|
|
|
1165
1177
|
// `()=>{}`: needs to be bounded even before initialization
|
|
1166
1178
|
};
|
|
1167
1179
|
|
|
1168
|
-
// src/utils/store.ts
|
|
1180
|
+
// src/ts/utils/store.ts
|
|
1169
1181
|
var BaseStorageAdapter = class {
|
|
1170
1182
|
static name;
|
|
1171
1183
|
config;
|
|
@@ -1299,7 +1311,7 @@ var sia = (() => {
|
|
|
1299
1311
|
};
|
|
1300
1312
|
var INDEXED_DB_ADAPTER_BUILD = { dbName: "REACTOR_IDB", stores: ["VAULT"], version: 1, onidb: NOOP, onupgradeneeded: NOOP, onversionchange: NOOP, onsuccess: NOOP, onerror: NOOP, onblocked: NOOP };
|
|
1301
1313
|
|
|
1302
|
-
// src/plugins/persist.ts
|
|
1314
|
+
// src/ts/plugins/persist.ts
|
|
1303
1315
|
var PersistPlugin = class extends BaseReactorPlugin {
|
|
1304
1316
|
static plugName = "persist";
|
|
1305
1317
|
adapter;
|
|
@@ -1352,12 +1364,13 @@ var sia = (() => {
|
|
|
1352
1364
|
};
|
|
1353
1365
|
var PERSIST_PLUGIN_BUILD = { disabled: false, key: "REACTOR_STORE", throttle: 2500, useSnapshot: false };
|
|
1354
1366
|
|
|
1355
|
-
// src/plugins/timeTravel.ts
|
|
1367
|
+
// src/ts/plugins/timeTravel.ts
|
|
1356
1368
|
var TimeTravelPlugin = class extends BaseReactorPlugin {
|
|
1357
1369
|
static plugName = "timeTravel";
|
|
1370
|
+
lastTimestamp = 0;
|
|
1358
1371
|
playbackTimeoutId = -1;
|
|
1359
1372
|
constructor(config, rtr) {
|
|
1360
|
-
super({ ...TIME_TRAVEL_PLUGIN_BUILD, ...config }, rtr, {
|
|
1373
|
+
super({ ...TIME_TRAVEL_PLUGIN_BUILD, ...config }, rtr, { initialState: null, history: [], currentFrame: 0, paused: true });
|
|
1361
1374
|
}
|
|
1362
1375
|
// ===========================================================================
|
|
1363
1376
|
// THE FOUNDATION & WIRETAP (Passive Recording)
|
|
@@ -1365,6 +1378,7 @@ var sia = (() => {
|
|
|
1365
1378
|
wire() {
|
|
1366
1379
|
this.rtr.config.referenceTracking = this.rtr.config.smartCloning = this.rtr.config.eventTimeStamps = true;
|
|
1367
1380
|
if (!this.state.history.length || this.state.initialState == null) this.state.initialState = this.rtr.snapshot();
|
|
1381
|
+
this.lastTimestamp = performance.now();
|
|
1368
1382
|
this.state.set("currentFrame", (v = 0) => clamp(0, v, this.state.history.length), { signal: this.signal, immediate: true });
|
|
1369
1383
|
this.config.on("paths", this.handlePathsState, { signal: this.signal, immediate: true });
|
|
1370
1384
|
!this.state.paused && this.play();
|
|
@@ -1378,16 +1392,17 @@ var sia = (() => {
|
|
|
1378
1392
|
if (!this.state.paused) return;
|
|
1379
1393
|
if (this.state.currentFrame < this.state.history.length) this.state.history = this.state.history.slice(0, this.state.currentFrame);
|
|
1380
1394
|
if (this.state.history.length >= this.config.maxHistoryLength) this.state.history = this.state.history.slice(1);
|
|
1381
|
-
this.state.history.push({
|
|
1395
|
+
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 });
|
|
1382
1396
|
this.state.currentFrame = this.state.history.length;
|
|
1397
|
+
this.lastTimestamp = e.timestamp;
|
|
1383
1398
|
}
|
|
1384
1399
|
/** Clears timeline history and resets playhead/genesis to the current reactor state. */
|
|
1385
1400
|
clear() {
|
|
1386
1401
|
this.pause();
|
|
1387
1402
|
this.playbackTimeoutId = -1;
|
|
1388
|
-
this.state.history =
|
|
1389
|
-
this.state.currentFrame = 0;
|
|
1403
|
+
this.state.history.length = this.state.currentFrame = 0;
|
|
1390
1404
|
this.state.initialState = this.rtr.snapshot();
|
|
1405
|
+
this.lastTimestamp = performance.now();
|
|
1391
1406
|
}
|
|
1392
1407
|
// ===========================================================================
|
|
1393
1408
|
// THE TIME MACHINE (Manual Controls)
|
|
@@ -1400,7 +1415,7 @@ var sia = (() => {
|
|
|
1400
1415
|
const e = this.state.history[forward ? this.state.currentFrame : this.state.currentFrame - 1];
|
|
1401
1416
|
if (!e) break;
|
|
1402
1417
|
if (forward) e.type === "delete" ? deleteAny(this.rtr.core, e.path) : setAny(this.rtr.core, e.path, deepClone(e.value, this.rtr.config));
|
|
1403
|
-
else !e.
|
|
1418
|
+
else !e.hadKey ? deleteAny(this.rtr.core, e.path) : setAny(this.rtr.core, e.path, deepClone(e.oldValue, this.rtr.config));
|
|
1404
1419
|
forward ? this.state.currentFrame++ : this.state.currentFrame--;
|
|
1405
1420
|
if (e.rejected) this.rtr.log(`[Reactor ${this.name} Plug] ${forward ? "Replaying" : "Reversing"} REJECTED intent at "${e.path}"`);
|
|
1406
1421
|
}
|
|
@@ -1423,9 +1438,9 @@ var sia = (() => {
|
|
|
1423
1438
|
async automove(forward = true) {
|
|
1424
1439
|
this.state.paused = false;
|
|
1425
1440
|
while ((forward ? this.state.currentFrame < this.state.history.length : this.state.currentFrame > 0) && !this.state.paused) {
|
|
1426
|
-
const currIndex = forward ? this.state.currentFrame : this.state.currentFrame - 1, e = this.state.history[
|
|
1441
|
+
const currIndex = forward ? this.state.currentFrame : this.state.currentFrame - 1, e = this.state.history[forward ? currIndex + 1 : currIndex - 1];
|
|
1427
1442
|
this.jumpTo(this.state.currentFrame + (forward ? 1 : -1), true);
|
|
1428
|
-
if (
|
|
1443
|
+
if (e?.timedelta > 0) await new Promise((res) => this.playbackTimeoutId = setTimeout2(() => res(0), Math.min(e.timedelta, this.config.maxPlaybackDelay), this.signal));
|
|
1429
1444
|
}
|
|
1430
1445
|
this.state.paused = true;
|
|
1431
1446
|
}
|
|
@@ -1439,35 +1454,39 @@ var sia = (() => {
|
|
|
1439
1454
|
// TELEMETRY & I/O (Session Import/Export)
|
|
1440
1455
|
// ===========================================================================
|
|
1441
1456
|
/** Exports the current session as a JSON string. */
|
|
1442
|
-
export() {
|
|
1443
|
-
|
|
1457
|
+
export(replacer, space) {
|
|
1458
|
+
try {
|
|
1459
|
+
return JSON.stringify(this.state, replacer, space);
|
|
1460
|
+
} catch (e) {
|
|
1461
|
+
return this.rtr.log(`[Reactor ${this.name} Plug] Failed to export session`), "";
|
|
1462
|
+
}
|
|
1444
1463
|
}
|
|
1445
1464
|
/** Imports a session from a JSON string, allowing you to replay or analyze past states. */
|
|
1446
1465
|
import(json) {
|
|
1447
1466
|
try {
|
|
1448
1467
|
setAny(this.state, "*", JSON.parse(json));
|
|
1468
|
+
this.lastTimestamp = performance.now();
|
|
1449
1469
|
const resume = !this.state.paused, target = this.state.currentFrame;
|
|
1450
1470
|
this.state.paused = false;
|
|
1451
|
-
setAny(this.rtr.core, "*", deepClone(this.state.initialState, this.rtr.config));
|
|
1452
|
-
this.
|
|
1453
|
-
this.state.currentFrame = 0;
|
|
1454
|
-
this.jumpTo(target), resume && this.play();
|
|
1471
|
+
setAny(this.rtr.core, "*", deepClone(this.state.initialState, this.rtr.config)), this.rtr.tick();
|
|
1472
|
+
this.state.currentFrame = 0, this.jumpTo(target), resume && this.play();
|
|
1455
1473
|
} catch (e) {
|
|
1456
|
-
this.rtr.log(`[Reactor ${this.name} Plug] Failed to load session
|
|
1474
|
+
this.rtr.log(`[Reactor ${this.name} Plug] Failed to load session`);
|
|
1457
1475
|
}
|
|
1458
1476
|
}
|
|
1459
1477
|
};
|
|
1460
1478
|
var TIME_TRAVEL_PLUGIN_BUILD = { maxPlaybackDelay: 2e3 };
|
|
1461
1479
|
|
|
1462
|
-
// src/adapters/vanilla.ts
|
|
1480
|
+
// src/ts/adapters/vanilla.ts
|
|
1463
1481
|
var vanilla_exports = {};
|
|
1464
1482
|
__export(vanilla_exports, {
|
|
1465
1483
|
Autotracker: () => Autotracker,
|
|
1484
|
+
TimeTravelOverlay: () => TimeTravelOverlay,
|
|
1466
1485
|
effect: () => effect,
|
|
1467
1486
|
withTracker: () => withTracker
|
|
1468
1487
|
});
|
|
1469
1488
|
|
|
1470
|
-
// src/adapters/autotracker.ts
|
|
1489
|
+
// src/ts/adapters/autotracker.ts
|
|
1471
1490
|
var Autotracker = class {
|
|
1472
1491
|
proxy;
|
|
1473
1492
|
deps = /* @__PURE__ */ new Map();
|
|
@@ -1609,7 +1628,7 @@ var sia = (() => {
|
|
|
1609
1628
|
}
|
|
1610
1629
|
}
|
|
1611
1630
|
|
|
1612
|
-
// src/adapters/vanilla/effect.ts
|
|
1631
|
+
// src/ts/adapters/vanilla/effect.ts
|
|
1613
1632
|
function effect(callback, options) {
|
|
1614
1633
|
const atrkr = new Autotracker();
|
|
1615
1634
|
let destroyed = false;
|
|
@@ -1619,7 +1638,83 @@ var sia = (() => {
|
|
|
1619
1638
|
return () => (destroyed = true, atrkr.destroy());
|
|
1620
1639
|
}
|
|
1621
1640
|
|
|
1622
|
-
// src/
|
|
1641
|
+
// src/ts/adapters/vanilla/TimeTravelOverlay.ts
|
|
1642
|
+
var keys = {
|
|
1643
|
+
overrides: ["Ctrl+z", "Cmd+z", "Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z", "Ctrl+g", "Cmd+g", ",", ".", "ArrowLeft", "ArrowRight", "Space", "Alt+Space", "Escape", "Delete", "e", "i", "c"],
|
|
1644
|
+
shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: ["Ctrl+g", "Cmd+g"], prevFrame: ",", nextFrame: ".", skipBwd: "ArrowLeft", skipFwd: "ArrowRight", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
|
|
1645
|
+
};
|
|
1646
|
+
var TimeTravelOverlay = class _TimeTravelOverlay {
|
|
1647
|
+
static count = 0;
|
|
1648
|
+
index = _TimeTravelOverlay.count;
|
|
1649
|
+
config;
|
|
1650
|
+
state = reactive({ open: false, import: "" });
|
|
1651
|
+
time;
|
|
1652
|
+
els;
|
|
1653
|
+
clups = [];
|
|
1654
|
+
keyup;
|
|
1655
|
+
/** Creates a docked TimeTravel overlay bound to a plugin instance.
|
|
1656
|
+
* @param time TimeTravel plugin instance that owns timeline operations.
|
|
1657
|
+
* @param build Optional initial overlay config overrides.
|
|
1658
|
+
*/
|
|
1659
|
+
constructor(time, build = {}) {
|
|
1660
|
+
this.time = time;
|
|
1661
|
+
this.config = reactive({ title: `Time Travel Overlay ${this.index = ++_TimeTravelOverlay.count}`, ...build });
|
|
1662
|
+
this.state.open = !!this.config.startOpen;
|
|
1663
|
+
const s = this.time.state, host = createEl("div", { className: "tt-overlay-host" }), toggle = createEl("button", { className: "tt-overlay-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "tt-overlay", ariaLabel: "time travel overlay" }), title = createEl("div", { className: "title" }), frame = createEl("span", { className: "muted" }), clrHistory = createEl("button", { textContent: `Clear History${formatKeyForDisplay(keys.shortcuts.clrHistory)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clrHistory, false), onclick: () => (this.time.clear(), this.state.import = "") }), undo = createEl("button", { textContent: `Undo${formatKeyForDisplay(keys.shortcuts.undo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.undo, false), onclick: this.time.undo }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: this.time.redo }), genesis = createEl("button", { textContent: `Genesis${formatKeyForDisplay(keys.shortcuts.genesis[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.genesis, false), onclick: () => this.time.jumpTo(0) }), playPause = createEl("button", { onclick: () => this.time[s.paused ? "play" : "pause"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.playPause, false) }), rewind = createEl("button", { textContent: `Rewind${formatKeyForDisplay(keys.shortcuts.rewind)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.rewind, false), onclick: this.time.rewind }), range = createEl("input", { type: "range", min: "0", max: "0", value: "0", title: "time travel frame", ariaLabel: "time travel frame", oninput: () => this.time.jumpTo(Number(range.value)) }), exp = createEl("button", { textContent: `Export${formatKeyForDisplay(keys.shortcuts.export)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.export, false), onclick: () => this.state.import = this.time.export(null, 2) }), imp = createEl("button", { textContent: `Import${formatKeyForDisplay(keys.shortcuts.import)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.import, false), onclick: () => this.state.import.trim().length && this.time.import(this.state.import) }), clr = createEl("button", { textContent: `Clear${formatKeyForDisplay(keys.shortcuts.clear)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clear, false), onclick: () => this.state.import = "" }), payload = createEl("textarea", { className: "tt-io", readOnly: true, placeholder: "current payload json", title: "current payload" }), io = createEl("textarea", { className: "tt-io", placeholder: "timeline payload json", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "tt-footnote", textContent: "Want this in your app? " }), link = createEl("a", { target: "_blank", rel: "noreferrer noopener", textContent: "sia-reactor", href: "https://www.npmjs.com/package/sia-reactor" }), box = createEl("div", { className: "tt-status-box" }), status = createEl("div", { className: "tt-status-row" }), row1 = createEl("div", { className: "tt-row" }), row2 = createEl("div", { className: "tt-row" }), row3 = createEl("div", { className: "tt-row" });
|
|
1664
|
+
status.append((box.append(frame), box), clrHistory);
|
|
1665
|
+
panel.append(title, status, (row1.append(undo, redo, genesis), row1), (row2.append(playPause, rewind), row2), payload, range, (row3.append(exp, imp, clr), row3), io, (foot.appendChild(link), foot));
|
|
1666
|
+
host.append(toggle, panel);
|
|
1667
|
+
this.els = { host, toggle, panel, title, frame, clrHistory, undo, redo, genesis, playPause, rewind, range, exp, imp, clr, payload, io };
|
|
1668
|
+
this.keyup = (e) => {
|
|
1669
|
+
const a = this.state.open && keyEventAllowed(e, keys);
|
|
1670
|
+
a === "undo" ? this.time.undo() : a === "redo" ? this.time.redo() : a === "genesis" ? this.time.jumpTo(0) : a === "prevFrame" ? this.time.step(1, false) : a === "nextFrame" ? this.time.step(1, true) : a === "skipBwd" ? this.time.step(5, false) : a === "skipFwd" ? this.time.step(5, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = "");
|
|
1671
|
+
};
|
|
1672
|
+
window.addEventListener("keydown", this.keyup);
|
|
1673
|
+
const sync = [
|
|
1674
|
+
effect(() => this.config.color ? host.style.setProperty("--sia-tt-color", this.config.color) : host.style.removeProperty("--sia-tt-color")),
|
|
1675
|
+
effect(() => {
|
|
1676
|
+
if (this.config.devOnly && !CTX.isDevEnv) return void host.remove();
|
|
1677
|
+
const dock = getDock(this.config.container);
|
|
1678
|
+
if (host.parentNode !== dock) dock.appendChild(host);
|
|
1679
|
+
}),
|
|
1680
|
+
effect(() => toggle.textContent = `${(panel.hidden = !this.state.open) ? "Show" : "Hide"} ${title.textContent = this.config.title ?? ""}`),
|
|
1681
|
+
effect(() => playPause.textContent = `${s.paused ? "Play" : "Pause"}${formatKeyForDisplay(keys.shortcuts.playPause)}`),
|
|
1682
|
+
effect(() => {
|
|
1683
|
+
frame.textContent = `Frame: ${s.currentFrame} / ${s.history.length}`;
|
|
1684
|
+
range.disabled = clrHistory.disabled = !s.history.length;
|
|
1685
|
+
genesis.disabled = rewind.disabled = undo.disabled = !s.currentFrame;
|
|
1686
|
+
playPause.disabled = redo.disabled = s.currentFrame >= s.history.length;
|
|
1687
|
+
range.max = String(s.history.length);
|
|
1688
|
+
range.value = String(Math.min(s.currentFrame, s.history.length));
|
|
1689
|
+
payload.value = JSON.stringify(s.currentFrame ? s.history[s.currentFrame - 1] : { type: "genesis", value: s.initialState }, null, 2);
|
|
1690
|
+
}),
|
|
1691
|
+
effect(() => {
|
|
1692
|
+
clr.disabled = imp.disabled = !this.state.import.trim().length;
|
|
1693
|
+
io.value !== this.state.import && (io.value = this.state.import);
|
|
1694
|
+
})
|
|
1695
|
+
];
|
|
1696
|
+
this.clups.push(...sync);
|
|
1697
|
+
}
|
|
1698
|
+
destroy() {
|
|
1699
|
+
this.clups.forEach((fn) => fn());
|
|
1700
|
+
this.keyup && window.removeEventListener("keydown", this.keyup);
|
|
1701
|
+
this.els.host.remove();
|
|
1702
|
+
nuke(this), --_TimeTravelOverlay.count;
|
|
1703
|
+
}
|
|
1704
|
+
};
|
|
1705
|
+
function getDirChild(parent, className) {
|
|
1706
|
+
for (const child of parent.children) if (child instanceof HTMLElement && child.classList.contains(className)) return child;
|
|
1707
|
+
}
|
|
1708
|
+
function getDock(container) {
|
|
1709
|
+
const host = container && container !== document.documentElement ? container : document.body;
|
|
1710
|
+
if (host !== document.body && getComputedStyle(host).position === "static") host.style.position = "relative";
|
|
1711
|
+
const layer = getDirChild(host, "tt-overlay-layer") || createEl("div", { className: "tt-overlay-layer" }, void 0, { position: host === document.body ? "fixed" : "absolute" });
|
|
1712
|
+
if (layer.parentElement !== host) host.appendChild(layer);
|
|
1713
|
+
const dock = getDirChild(layer, "tt-overlay-dock") || createEl("div", { className: "tt-overlay-dock" });
|
|
1714
|
+
return dock.parentElement !== layer && layer.appendChild(dock), dock;
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
// src/ts/super.ts
|
|
1623
1718
|
var adapters = { vanilla: vanilla_exports };
|
|
1624
1719
|
return __toCommonJS(super_exports);
|
|
1625
1720
|
})();
|