sia-reactor 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +115 -89
- package/dist/{TimeTravelOverlay-DxqJL0Zk.d.ts → TimeTravelOverlay-Dglcwpg-.d.ts} +9 -8
- package/dist/{TimeTravelOverlay-CJv-S_Km.d.cts → TimeTravelOverlay-OjklzuCD.d.cts} +9 -8
- package/dist/adapters/react.cjs +74 -91
- package/dist/adapters/react.d.cts +23 -22
- package/dist/adapters/react.d.ts +23 -22
- package/dist/adapters/react.js +3 -3
- package/dist/adapters/vanilla.cjs +74 -91
- package/dist/adapters/vanilla.d.cts +4 -4
- package/dist/adapters/vanilla.d.ts +4 -4
- package/dist/adapters/vanilla.js +3 -3
- package/dist/{chunk-TFLYCXK4.js → chunk-5JNWC7Z4.js} +14 -13
- package/dist/{chunk-DP74DVRT.js → chunk-MKL3JUPO.js} +55 -15
- package/dist/{chunk-2WBPGSRL.js → chunk-MSTHQVNK.js} +61 -78
- package/dist/{index-Oie9hhE8.d.cts → index-m0aAWxhX.d.cts} +330 -218
- package/dist/{index-Oie9hhE8.d.ts → index-m0aAWxhX.d.ts} +330 -218
- package/dist/index.cjs +69 -89
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -4
- package/dist/{plugins.cjs → modules.cjs} +464 -195
- package/dist/modules.d.cts +52 -0
- package/dist/modules.d.ts +52 -0
- package/dist/modules.js +619 -0
- package/dist/super.d.ts +642 -298
- package/dist/super.global.js +481 -210
- package/dist/timeTravel-DExvNb04.d.ts +352 -0
- package/dist/timeTravel-DctvcHVt.d.cts +352 -0
- package/dist/utils.cjs +59 -14
- package/dist/utils.d.cts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +7 -1
- package/package.json +6 -6
- package/dist/plugins.d.cts +0 -112
- package/dist/plugins.d.ts +0 -112
- package/dist/plugins.js +0 -370
- package/dist/timeTravel-B1vedDQc.d.ts +0 -76
- package/dist/timeTravel-WpgWmKu-.d.cts +0 -76
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
reactive
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MSTHQVNK.js";
|
|
4
4
|
import {
|
|
5
5
|
createEl,
|
|
6
6
|
formatKeyForDisplay,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
RAW,
|
|
14
14
|
canHandle,
|
|
15
15
|
nuke
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-MKL3JUPO.js";
|
|
17
17
|
|
|
18
18
|
// src/ts/adapters/autotracker.ts
|
|
19
19
|
var Autotracker = class {
|
|
@@ -119,9 +119,9 @@ var Autotracker = class {
|
|
|
119
119
|
* const stop = atrkr.callback(() => console.log("changed")); // re-run after when ".user.name" changes
|
|
120
120
|
* @example Packaged Customization
|
|
121
121
|
* const atrkr = new Autotracker(); // no reactor passed
|
|
122
|
-
* withTracker(atrkr, () => state.user.name); // import `withTracker`
|
|
122
|
+
* withTracker(atrkr, () => state.user.name); // import `withTracker` too
|
|
123
123
|
* 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
|
|
124
|
-
* @example Extensive
|
|
124
|
+
* @example Extensive Customization
|
|
125
125
|
* atrkr.unblock();
|
|
126
126
|
* const prev = CTX.autotracker;
|
|
127
127
|
* CTX.autotracker = atrkr; // import CTX first
|
|
@@ -169,8 +169,8 @@ function effect(callback, options) {
|
|
|
169
169
|
|
|
170
170
|
// src/ts/adapters/vanilla/TimeTravelOverlay.ts
|
|
171
171
|
var keys = {
|
|
172
|
-
overrides: ["Ctrl+z", "Cmd+z", "Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z", "
|
|
173
|
-
shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis:
|
|
172
|
+
overrides: ["Ctrl+z", "Cmd+z", "Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z", "Home", "End", ",", ".", "ArrowLeft", "ArrowRight", "Space", "Alt+Space", "Escape", "Delete", "e", "i", "c"],
|
|
173
|
+
shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: "Home", ending: "End", prevFrame: ",", nextFrame: ".", skipBwd: "ArrowLeft", skipFwd: "ArrowRight", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
|
|
174
174
|
};
|
|
175
175
|
var TimeTravelOverlay = class _TimeTravelOverlay {
|
|
176
176
|
static count = 0;
|
|
@@ -181,22 +181,22 @@ var TimeTravelOverlay = class _TimeTravelOverlay {
|
|
|
181
181
|
els;
|
|
182
182
|
clups = [];
|
|
183
183
|
keyup;
|
|
184
|
-
/** Creates a docked TimeTravel overlay bound to a
|
|
185
|
-
* @param time TimeTravel
|
|
184
|
+
/** Creates a docked TimeTravel overlay bound to a module instance.
|
|
185
|
+
* @param time TimeTravel module instance that owns timeline operations.
|
|
186
186
|
* @param build Optional initial overlay config overrides.
|
|
187
187
|
*/
|
|
188
188
|
constructor(time, build = {}) {
|
|
189
189
|
this.time = time;
|
|
190
190
|
this.config = reactive({ title: `Time Travel Overlay ${this.index = ++_TimeTravelOverlay.count}`, ...build });
|
|
191
191
|
this.state.open = !!this.config.startOpen;
|
|
192
|
-
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
|
|
192
|
+
const s = this.time.state, host = createEl("div", { className: "tt-overlay-host" }), toggle = createEl("button", { className: "tt-overlay-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "tt-overlay", ariaLabel: "time travel overlay" }), title = createEl("div", { className: "title" }), frame = createEl("span", { className: "muted" }), clrHistory = createEl("button", { textContent: `Clear History${formatKeyForDisplay(keys.shortcuts.clrHistory)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clrHistory, false), onclick: () => (this.time.clear(), this.state.import = "") }), undo = createEl("button", { textContent: `Undo${formatKeyForDisplay(keys.shortcuts.undo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.undo, false), onclick: this.time.undo }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: this.time.redo }), genesis = createEl("button", { textContent: `Genesis${formatKeyForDisplay(keys.shortcuts.genesis)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.genesis, false), onclick: () => this.time.jumpTo(0) }), playPause = createEl("button", { onclick: () => this.time[s.paused ? "play" : "pause"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.playPause, false) }), rewind = createEl("button", { textContent: `Rewind${formatKeyForDisplay(keys.shortcuts.rewind)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.rewind, false), onclick: this.time.rewind }), range = createEl("input", { type: "range", min: "0", max: "0", value: "0", title: "time travel frame", ariaLabel: "time travel frame", oninput: () => this.time.jumpTo(Number(range.value)) }), exp = createEl("button", { textContent: `Export${formatKeyForDisplay(keys.shortcuts.export)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.export, false), onclick: () => this.state.import = this.time.export(null, 2) }), imp = createEl("button", { textContent: `Import${formatKeyForDisplay(keys.shortcuts.import)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.import, false), onclick: () => this.state.import.trim().length && this.time.import(this.state.import) }), clr = createEl("button", { textContent: `Clear${formatKeyForDisplay(keys.shortcuts.clear)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clear, false), onclick: () => this.state.import = "" }), payload = createEl("textarea", { className: "tt-io", readOnly: true, placeholder: "current payload json", title: "current payload" }), io = createEl("textarea", { className: "tt-io", placeholder: "timeline payload json", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "tt-footnote", textContent: "Want this in your app? " }), link = createEl("a", { target: "_blank", rel: "noreferrer noopener", textContent: "sia-reactor", href: "https://www.npmjs.com/package/sia-reactor" }), box = createEl("div", { className: "tt-status-box" }), status = createEl("div", { className: "tt-status-row" }), row1 = createEl("div", { className: "tt-row" }), row2 = createEl("div", { className: "tt-row" }), row3 = createEl("div", { className: "tt-row" });
|
|
193
193
|
status.append((box.append(frame), box), clrHistory);
|
|
194
194
|
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));
|
|
195
195
|
host.append(toggle, panel);
|
|
196
196
|
this.els = { host, toggle, panel, title, frame, clrHistory, undo, redo, genesis, playPause, rewind, range, exp, imp, clr, payload, io };
|
|
197
197
|
this.keyup = (e) => {
|
|
198
|
-
const a = this.state.open && keyEventAllowed(e, keys);
|
|
199
|
-
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 = "");
|
|
198
|
+
const a = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true) && keyEventAllowed(e, keys);
|
|
199
|
+
a === "undo" ? this.time.undo() : a === "redo" ? this.time.redo() : a === "genesis" ? this.time.jumpTo(0) : a === "ending" ? this.time.jumpTo(s.history.length) : a === "prevFrame" ? this.time.step(1, false) : a === "nextFrame" ? this.time.step(1, true) : a === "skipBwd" ? this.time.step(5, false) : a === "skipFwd" ? this.time.step(5, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = "");
|
|
200
200
|
};
|
|
201
201
|
window.addEventListener("keydown", this.keyup);
|
|
202
202
|
const sync = [
|
|
@@ -211,7 +211,8 @@ var TimeTravelOverlay = class _TimeTravelOverlay {
|
|
|
211
211
|
effect(() => {
|
|
212
212
|
frame.textContent = `Frame: ${s.currentFrame} / ${s.history.length}`;
|
|
213
213
|
range.disabled = clrHistory.disabled = !s.history.length;
|
|
214
|
-
genesis.disabled =
|
|
214
|
+
genesis.disabled = undo.disabled = !s.currentFrame;
|
|
215
|
+
rewind.disabled = !s.paused || !s.currentFrame;
|
|
215
216
|
playPause.disabled = redo.disabled = s.currentFrame >= s.history.length;
|
|
216
217
|
range.max = String(s.history.length);
|
|
217
218
|
range.value = String(Math.min(s.currentFrame, s.history.length));
|
|
@@ -225,7 +226,7 @@ var TimeTravelOverlay = class _TimeTravelOverlay {
|
|
|
225
226
|
this.clups.push(...sync);
|
|
226
227
|
}
|
|
227
228
|
destroy() {
|
|
228
|
-
this.clups
|
|
229
|
+
for (const clup of this.clups) clup();
|
|
229
230
|
this.keyup && window.removeEventListener("keydown", this.keyup);
|
|
230
231
|
this.els.host.remove();
|
|
231
232
|
nuke(this), --_TimeTravelOverlay.count;
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
var CTX = {
|
|
3
3
|
/** Flag indicating whether the application is running in development mode. */
|
|
4
4
|
isDevEnv: "undefined" !== typeof process ? process.env.NODE_ENV !== "production" : true,
|
|
5
|
-
/**
|
|
5
|
+
/** Flag indicating whether a cascade is currently ongoing so reactors can allow all writes. */
|
|
6
|
+
isCascading: false,
|
|
7
|
+
/** Active `Autotracker` instance, override for automatic dependency collection on `Reactor` traps. */
|
|
6
8
|
autotracker: null
|
|
7
9
|
};
|
|
8
10
|
var RAW = /* @__PURE__ */ Symbol.for("S.I.A_RAW");
|
|
@@ -14,14 +16,13 @@ var VERSION = /* @__PURE__ */ Symbol.for("S.I.A_VERSION");
|
|
|
14
16
|
var SSVERSION = /* @__PURE__ */ Symbol.for("S.I.A_SNAPSHOT_VERSION");
|
|
15
17
|
var RTR_BATCH = "undefined" !== typeof window ? ("undefined" !== typeof queueMicrotask ? queueMicrotask : setTimeout).bind(window) : "undefined" !== typeof process && process.nextTick ? process.nextTick : setTimeout;
|
|
16
18
|
var RTR_LOG = console.log.bind(console, "[S.I.A Reactor]");
|
|
17
|
-
var EVT_WARN = console.warn.bind(console, "[S.I.A Event]");
|
|
18
19
|
var EVT_OPTS = { LISTENER: ["capture", "depth", "once", "signal", "immediate"], MEDIATOR: ["lazy", "signal", "immediate"] };
|
|
19
20
|
var NIL = Object.freeze({});
|
|
20
21
|
var NOOP = () => {
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
// src/ts/utils/obj.ts
|
|
24
|
-
var
|
|
25
|
+
var arrRegex = /^([^\[\]]+)\[(\d+)\]$/;
|
|
25
26
|
function isObj(obj, arraycheck = true) {
|
|
26
27
|
return "object" === typeof obj && obj !== null && (arraycheck ? !Array.isArray(obj) : true);
|
|
27
28
|
}
|
|
@@ -29,7 +30,7 @@ function isPOJO(obj, config = NIL, typecheck = true) {
|
|
|
29
30
|
return (typecheck ? isObj(obj, false) : true) && (config.crossRealms ? Object.prototype.toString.call(obj) === "[object Object]" : obj.constructor === Object);
|
|
30
31
|
}
|
|
31
32
|
function canHandle(obj, config = NIL, typecheck = true) {
|
|
32
|
-
if (typecheck && !isObj(obj, false)) return false;
|
|
33
|
+
if (typecheck && !isObj(obj, false) || obj[INERTIA]) return false;
|
|
33
34
|
if (Array.isArray(obj) || !config.preserveContext && isPOJO(obj, config, false)) return true;
|
|
34
35
|
if (config.preserveContext) return !(obj instanceof Map) && !(obj instanceof Set) && !(obj instanceof WeakMap) && !(obj instanceof WeakSet) && !(obj instanceof Error) && !(obj instanceof Number) && !(obj instanceof Date) && !(obj instanceof String) && !(obj instanceof RegExp) && !(obj instanceof ArrayBuffer) && !(obj instanceof Promise);
|
|
35
36
|
return false;
|
|
@@ -40,7 +41,7 @@ function getAny(source, key, separator = ".", keyFunc) {
|
|
|
40
41
|
const keys = key.split(separator);
|
|
41
42
|
let currObj = source;
|
|
42
43
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
43
|
-
const key2 = keyFunc ? keyFunc(keys[i]) : keys[i], match = key2.includes("[") && key2.match(
|
|
44
|
+
const key2 = keyFunc ? keyFunc(keys[i]) : keys[i], match = key2.includes("[") && key2.match(arrRegex);
|
|
44
45
|
if (match) {
|
|
45
46
|
const [, key3, iStr] = match;
|
|
46
47
|
if (!Array.isArray(currObj[key3]) || !(key3 in currObj)) return void 0;
|
|
@@ -57,7 +58,7 @@ function setAny(target, key, value, separator = ".", keyFunc) {
|
|
|
57
58
|
if (!key.includes(separator)) return void (target[keyFunc ? keyFunc(key) : key] = value);
|
|
58
59
|
const keys = key.split(separator);
|
|
59
60
|
for (let currObj = target, i = 0, len = keys.length; i < len; i++) {
|
|
60
|
-
const key2 = keyFunc ? keyFunc(keys[i]) : keys[i], match = key2.includes("[") && key2.match(
|
|
61
|
+
const key2 = keyFunc ? keyFunc(keys[i]) : keys[i], match = key2.includes("[") && key2.match(arrRegex);
|
|
61
62
|
if (match) {
|
|
62
63
|
const [, key3, iStr] = match;
|
|
63
64
|
if (!Array.isArray(currObj[key3])) currObj[key3] = [];
|
|
@@ -78,7 +79,7 @@ function deleteAny(target, key, separator = ".", keyFunc) {
|
|
|
78
79
|
if (!key.includes(separator)) return void delete target[keyFunc ? keyFunc(key) : key];
|
|
79
80
|
const keys = key.split(separator);
|
|
80
81
|
for (let currObj = target, i = 0, len = keys.length; i < len; i++) {
|
|
81
|
-
const key2 = keyFunc ? keyFunc(keys[i]) : keys[i], match = key2.includes("[") && key2.match(
|
|
82
|
+
const key2 = keyFunc ? keyFunc(keys[i]) : keys[i], match = key2.includes("[") && key2.match(arrRegex);
|
|
82
83
|
if (match) {
|
|
83
84
|
const [, key3, iStr] = match;
|
|
84
85
|
if (!Array.isArray(currObj[key3]) || !(key3 in currObj)) return;
|
|
@@ -96,7 +97,7 @@ function inAny(source, key, separator = ".", keyFunc) {
|
|
|
96
97
|
if (!key.includes(separator)) return key in source;
|
|
97
98
|
const keys = key.split(separator);
|
|
98
99
|
for (let currObj = source, i = 0, len = keys.length; i < len; i++) {
|
|
99
|
-
const key2 = keyFunc ? keyFunc(keys[i]) : keys[i], match = key2.includes("[") && key2.match(
|
|
100
|
+
const key2 = keyFunc ? keyFunc(keys[i]) : keys[i], match = key2.includes("[") && key2.match(arrRegex);
|
|
100
101
|
if (match) {
|
|
101
102
|
const [, key3, iStr] = match;
|
|
102
103
|
if (!Array.isArray(currObj[key3]) || !(key3 in currObj)) return false;
|
|
@@ -113,16 +114,48 @@ function inAny(source, key, separator = ".", keyFunc) {
|
|
|
113
114
|
function parseAnyObj(obj, separator = ".", keyFunc = (p) => p, seen = /* @__PURE__ */ new WeakSet()) {
|
|
114
115
|
if (!isObj(obj) || seen.has(obj)) return obj;
|
|
115
116
|
seen.add(obj);
|
|
116
|
-
const result = {};
|
|
117
|
-
|
|
117
|
+
const result = {}, keys = Object.keys(obj);
|
|
118
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
119
|
+
const k = keys[i];
|
|
120
|
+
k === "*" || k.includes(separator) ? setAny(result, k, parseAnyObj(obj[k], separator, keyFunc, seen), separator, keyFunc) : result[k] = isObj(obj[k]) ? parseAnyObj(obj[k], separator, keyFunc, seen) : obj[k];
|
|
121
|
+
}
|
|
118
122
|
return result;
|
|
119
123
|
}
|
|
120
124
|
function parseEvtOpts(options, opts, boolOpt = opts[0], result = {}) {
|
|
121
125
|
return Object.assign(result, "boolean" === typeof options ? { [boolOpt]: options } : options), result;
|
|
122
126
|
}
|
|
123
|
-
function
|
|
124
|
-
const
|
|
125
|
-
|
|
127
|
+
function fanout(a, b, c, d) {
|
|
128
|
+
const isEvPd = !!a?.target, isPath = !isEvPd && "string" === typeof b, [state, path, olds, news, opts, type] = isEvPd ? [a.root, a.currentTarget.path, a.currentTarget.oldValue, a.currentTarget.value, b || NIL, a.type] : isPath ? [a, b, getAny(a, b), c, d || NIL, void 0] : [void 0, void 0, a, b, c || NIL, void 0], target = isEvPd ? getAny(a.root, a.currentTarget.path) : isPath ? getAny(state, path) : olds;
|
|
129
|
+
if (isEvPd && type !== "set" && type !== "delete" || !target || !canHandle(news, opts)) return;
|
|
130
|
+
const prev = CTX.isCascading;
|
|
131
|
+
CTX.isCascading = isEvPd;
|
|
132
|
+
try {
|
|
133
|
+
const walk = (target2, obj, depth = isEvPd ? 1 : Infinity, keys = Object.keys(obj)) => {
|
|
134
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
135
|
+
const val = obj[keys[i]];
|
|
136
|
+
try {
|
|
137
|
+
if ((opts.atomic ?? true) && Array.isArray(val)) target2[keys[i]] = val, target2[keys[i]].length = target2[keys[i]].length;
|
|
138
|
+
else depth > 1 && canHandle(val, opts) ? walk(target2[keys[i]] ||= {}, val, depth - 1) : target2[keys[i]] = val;
|
|
139
|
+
} catch (e) {
|
|
140
|
+
if (e instanceof RangeError) throw e;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
if ((opts.atomic ?? true) && Array.isArray(news) && isPath) setAny(state, path, news), getAny(state, path).length = news.length;
|
|
145
|
+
else walk(target, opts.merge ? mergeObjs(olds, news, opts) : news, opts.depth === true ? Infinity : opts.depth);
|
|
146
|
+
} finally {
|
|
147
|
+
CTX.isCascading = prev;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
var fanoutOptsArr = ["merge", "depth", "atomic"];
|
|
151
|
+
function mergeObjs(o1, o2, config, pojocheck = true) {
|
|
152
|
+
if (pojocheck && (!isPOJO(o1 || NIL, config) || !isPOJO(o2 || NIL, config))) return o2;
|
|
153
|
+
const merged = { ...o1 ||= {}, ...o2 ||= {} }, keys = Object.keys(merged);
|
|
154
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
155
|
+
const o1C = o1[keys[i]], o2C = o2[keys[i]];
|
|
156
|
+
if (isPOJO(o1C, config) && isPOJO(o2C, config)) merged[keys[i]] = mergeObjs(o1C, o2C, config, false);
|
|
157
|
+
}
|
|
158
|
+
return merged;
|
|
126
159
|
}
|
|
127
160
|
function getTrailRecords(obj, path, reverse = false) {
|
|
128
161
|
const parts = path.split("."), chain = [["*", obj, obj]];
|
|
@@ -137,7 +170,12 @@ function deepClone(obj, config = NIL, seen = /* @__PURE__ */ new WeakMap()) {
|
|
|
137
170
|
const clone = config.preserveContext ? Object.create(Object.getPrototypeOf(obj)) : Array.isArray(obj) ? [] : {};
|
|
138
171
|
seen.set(obj, clone);
|
|
139
172
|
const keys = config.preserveContext ? Reflect.ownKeys(obj) : Object.keys(obj);
|
|
140
|
-
for (let i = 0, len = keys.length; i < len; i++)
|
|
173
|
+
for (let i = 0, len = keys.length; i < len; i++)
|
|
174
|
+
try {
|
|
175
|
+
clone[keys[i]] = deepClone(obj[keys[i]], config, seen);
|
|
176
|
+
} catch (e) {
|
|
177
|
+
if (e instanceof RangeError) throw e;
|
|
178
|
+
}
|
|
141
179
|
return clone;
|
|
142
180
|
}
|
|
143
181
|
function nuke(target) {
|
|
@@ -165,10 +203,10 @@ export {
|
|
|
165
203
|
SSVERSION,
|
|
166
204
|
RTR_BATCH,
|
|
167
205
|
RTR_LOG,
|
|
168
|
-
EVT_WARN,
|
|
169
206
|
EVT_OPTS,
|
|
170
207
|
NIL,
|
|
171
208
|
NOOP,
|
|
209
|
+
arrRegex,
|
|
172
210
|
isObj,
|
|
173
211
|
isPOJO,
|
|
174
212
|
canHandle,
|
|
@@ -178,6 +216,8 @@ export {
|
|
|
178
216
|
inAny,
|
|
179
217
|
parseAnyObj,
|
|
180
218
|
parseEvtOpts,
|
|
219
|
+
fanout,
|
|
220
|
+
fanoutOptsArr,
|
|
181
221
|
mergeObjs,
|
|
182
222
|
getTrailRecords,
|
|
183
223
|
deepClone,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CTX,
|
|
3
3
|
EVT_OPTS,
|
|
4
|
-
EVT_WARN,
|
|
5
4
|
INDIFFABLE,
|
|
6
5
|
INERTIA,
|
|
7
6
|
NIL,
|
|
@@ -18,11 +17,10 @@ import {
|
|
|
18
17
|
getAny,
|
|
19
18
|
getTrailRecords,
|
|
20
19
|
inAny,
|
|
21
|
-
mergeObjs,
|
|
22
20
|
nuke,
|
|
23
21
|
parseEvtOpts,
|
|
24
22
|
setAny
|
|
25
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-MKL3JUPO.js";
|
|
26
24
|
|
|
27
25
|
// src/ts/core/event.ts
|
|
28
26
|
var ReactorEvent = class _ReactorEvent {
|
|
@@ -47,35 +45,34 @@ var ReactorEvent = class _ReactorEvent {
|
|
|
47
45
|
staticType;
|
|
48
46
|
/** Original event target context. */
|
|
49
47
|
target;
|
|
50
|
-
/** Root reactive object for this event wave. */
|
|
48
|
+
/** Root reactive object for this event instance wave. */
|
|
51
49
|
root;
|
|
52
|
-
/** Original target path for this event wave. */
|
|
50
|
+
/** Original target path for this event instance wave. */
|
|
53
51
|
path;
|
|
54
52
|
/** Current value at the event target path. */
|
|
55
53
|
value;
|
|
56
54
|
/** Previous value at the event target path. */
|
|
57
55
|
oldValue;
|
|
58
|
-
/** Whether resolve/reject intent semantics are allowed for this event. */
|
|
56
|
+
/** Whether resolve/reject intent semantics are allowed for this event instance. */
|
|
59
57
|
rejectable;
|
|
60
|
-
/** Whether this event wave can bubble back up to ancestors or just capture down. */
|
|
58
|
+
/** Whether this event instance wave can bubble back up to ancestors or just capture down. */
|
|
61
59
|
bubbles;
|
|
62
60
|
/**
|
|
63
|
-
* `DOMHighResTimeStamp` for this event payload for native event parity and accuracy.
|
|
61
|
+
* `DOMHighResTimeStamp` for this event instance payload for native event parity and accuracy.
|
|
64
62
|
* Enable `eventTimeStamps` option, then use this over custom timestamps in listeners for accuracy.
|
|
65
63
|
* */
|
|
66
64
|
timestamp;
|
|
67
|
-
|
|
65
|
+
/** The `Reactor` instance that dispatched this event instance. */
|
|
66
|
+
reactor;
|
|
68
67
|
_resolved = "";
|
|
69
68
|
_rejected = "";
|
|
70
69
|
_propagationStopped = false;
|
|
71
70
|
_immediatePropagationStopped = false;
|
|
72
71
|
/**
|
|
73
72
|
* @param payload Source payload for this event instance.
|
|
74
|
-
* @param
|
|
75
|
-
* @param canWarn Whether warning output is enabled.
|
|
76
|
-
* @param canStamp Whether timestamping is enabled.
|
|
73
|
+
* @param reactor The `Reactor` instance creating this event instance.
|
|
77
74
|
*/
|
|
78
|
-
constructor(payload,
|
|
75
|
+
constructor(payload, reactor) {
|
|
79
76
|
this.staticType = this.type = payload.type;
|
|
80
77
|
this.target = payload.target;
|
|
81
78
|
this.currentTarget = payload.currentTarget;
|
|
@@ -84,9 +81,9 @@ var ReactorEvent = class _ReactorEvent {
|
|
|
84
81
|
this.value = payload.target.value;
|
|
85
82
|
this.oldValue = payload.target.oldValue;
|
|
86
83
|
this.rejectable = payload.rejectable;
|
|
87
|
-
this.bubbles =
|
|
88
|
-
if (
|
|
89
|
-
|
|
84
|
+
this.bubbles = !!reactor.config.eventBubbling;
|
|
85
|
+
if (reactor.config.eventTimeStamps) this.timestamp = performance.now();
|
|
86
|
+
this.reactor = reactor;
|
|
90
87
|
}
|
|
91
88
|
/** Whether propagation has been stopped. */
|
|
92
89
|
get propagationStopped() {
|
|
@@ -116,9 +113,9 @@ var ReactorEvent = class _ReactorEvent {
|
|
|
116
113
|
* @example e.resolve("API Load successful"); // message
|
|
117
114
|
*/
|
|
118
115
|
resolve(message) {
|
|
119
|
-
if (!this.rejectable) return this.
|
|
120
|
-
if (this.eventPhase !== _ReactorEvent.CAPTURING_PHASE) this.
|
|
121
|
-
if (this.rejectable) this._resolved = message || `Could ${this.staticType} intended value at "${this.path}"
|
|
116
|
+
if (!this.rejectable) return this.reactor.log(`[ReactorEvent] Ignored \`resolve()\` call on a non-rejectable ${this.staticType} at "${this.path}"`);
|
|
117
|
+
if (this.eventPhase !== _ReactorEvent.CAPTURING_PHASE) this.reactor.log(`[ReactorEvent] Resolving an intent on ${this.staticType} at "${this.path}" outside of the capture phase is unadvised.`);
|
|
118
|
+
if (this.rejectable) this.reactor.log(`[ReactorEvent] ${this._resolved = message || `Could ${this.staticType} intended value at "${this.path}"`}`);
|
|
122
119
|
}
|
|
123
120
|
/** Rejection reason for rejectable events. */
|
|
124
121
|
get rejected() {
|
|
@@ -131,9 +128,9 @@ var ReactorEvent = class _ReactorEvent {
|
|
|
131
128
|
* @example e.resolve("User is not logged in"); // reason
|
|
132
129
|
*/
|
|
133
130
|
reject(reason) {
|
|
134
|
-
if (!this.rejectable) return this.
|
|
135
|
-
if (this.eventPhase !== _ReactorEvent.CAPTURING_PHASE) this.
|
|
136
|
-
if (this.rejectable) this._rejected = reason || `Couldn't ${this.staticType} intended value at "${this.path}"
|
|
131
|
+
if (!this.rejectable) return this.reactor.log(`[ReactorEvent] Ignored \`reject()\` call on a non-rejectable ${this.staticType} at "${this.path}"`);
|
|
132
|
+
if (this.eventPhase !== _ReactorEvent.CAPTURING_PHASE) this.reactor.log(`[ReactorEvent] Rejecting an intent on ${this.staticType} at "${this.path}" outside of the capture phase is unadvised.`);
|
|
133
|
+
if (this.rejectable) this.reactor.log(`[ReactorEvent] ${this._rejected = reason || `Couldn't ${this.staticType} intended value at "${this.path}"`}`);
|
|
137
134
|
}
|
|
138
135
|
/**
|
|
139
136
|
* Returns event path values from target to root.
|
|
@@ -142,24 +139,22 @@ var ReactorEvent = class _ReactorEvent {
|
|
|
142
139
|
composedPath() {
|
|
143
140
|
return getTrailRecords(this.root, this.path, true).map((r) => r[2]);
|
|
144
141
|
}
|
|
145
|
-
get canWarn() {
|
|
146
|
-
return this._warn !== NOOP;
|
|
147
|
-
}
|
|
148
142
|
};
|
|
149
143
|
|
|
150
144
|
// src/ts/core/reactor.ts
|
|
151
145
|
var Reactor = class {
|
|
146
|
+
/** Logger function for this reactor instance, override if desired, `this.canLog = false` resets. */
|
|
152
147
|
log = NOOP;
|
|
148
|
+
/** The core state object for this reactor instance. */
|
|
153
149
|
core;
|
|
154
150
|
// `?:`s | pay the ~800 byte price upfront for what u might never use
|
|
155
|
-
|
|
151
|
+
/** The modules being used by this reactor. */
|
|
152
|
+
modules;
|
|
153
|
+
/** Configuration options for this reactor instance. */
|
|
156
154
|
config;
|
|
155
|
+
/** Whether this reactor instance is currently batching updates, a window view into the engine timing */
|
|
157
156
|
isBatching = false;
|
|
158
157
|
// Async Batching
|
|
159
|
-
isCascading = false;
|
|
160
|
-
// Setter Cascading
|
|
161
|
-
isLogging = false;
|
|
162
|
-
// keeping track so API getter doesn't slow down internal iterations in any way
|
|
163
158
|
queue;
|
|
164
159
|
// Tasks to run after flush
|
|
165
160
|
batch;
|
|
@@ -192,7 +187,7 @@ var Reactor = class {
|
|
|
192
187
|
if (this.config.referenceTracking && parent && key && !this.link(target, parent, key, false)) return target;
|
|
193
188
|
const cached = this.proxyCache.get(target);
|
|
194
189
|
if (cached) return cached;
|
|
195
|
-
if (
|
|
190
|
+
if (!canHandle(target, this.config, false)) return target;
|
|
196
191
|
rejectable ||= target[REJECTABLE];
|
|
197
192
|
indiffable ||= target[INDIFFABLE];
|
|
198
193
|
const proxy = new Proxy(target, {
|
|
@@ -226,7 +221,7 @@ var Reactor = class {
|
|
|
226
221
|
safeValue = value?.[RAW] || value;
|
|
227
222
|
unchanged = this.config.equalityFunction(safeValue, safeOldValue);
|
|
228
223
|
}
|
|
229
|
-
if (!indiffable && unchanged && !
|
|
224
|
+
if (!indiffable && unchanged && !CTX.isCascading) return this.log(`\u{1F504} [Reactor \`set\` Trap] Unchanged for "${keyStr}" on "${paths}"`), true;
|
|
230
225
|
if (this.config.set) terminated = (value = this.config.set(object, key2, value, oldValue, receiver, paths)) === TERMINATOR;
|
|
231
226
|
if (this.setters) {
|
|
232
227
|
const wildcords = this.setters.get("*");
|
|
@@ -380,7 +375,7 @@ var Reactor = class {
|
|
|
380
375
|
if (this.queue?.size) for (const task of this.queue) task(), this.queue.delete(task);
|
|
381
376
|
}
|
|
382
377
|
wave(path, payload) {
|
|
383
|
-
const e = new ReactorEvent(payload, this
|
|
378
|
+
const e = new ReactorEvent(payload, this), chain = getTrailRecords(this.core, path);
|
|
384
379
|
e.eventPhase = ReactorEvent.CAPTURING_PHASE;
|
|
385
380
|
for (let i = 0; i <= chain.length - 2; i++) {
|
|
386
381
|
if (e.propagationStopped) break;
|
|
@@ -454,8 +449,8 @@ var Reactor = class {
|
|
|
454
449
|
return depth;
|
|
455
450
|
}
|
|
456
451
|
getContext(path) {
|
|
457
|
-
const
|
|
458
|
-
return { path, value, key: path.slice(
|
|
452
|
+
const last = path.lastIndexOf("."), value = getAny(this.core, path), object = last === -1 ? this.core : getAny(this.core, path.slice(0, last));
|
|
453
|
+
return { path, value, key: path.slice(last + 1) || "", hadKey: true, object };
|
|
459
454
|
}
|
|
460
455
|
bindSignal(cord, sig) {
|
|
461
456
|
if (sig) sig.aborted ? cord.clup() : sig.addEventListener("abort", cord.clup, { once: true });
|
|
@@ -471,7 +466,12 @@ var Reactor = class {
|
|
|
471
466
|
const clone = !raw ? this.config.preserveContext ? Object.create(Object.getPrototypeOf(obj)) : Array.isArray(obj) ? [] : {} : obj;
|
|
472
467
|
seen.set(obj, clone);
|
|
473
468
|
const keys = this.config.preserveContext ? Reflect.ownKeys(obj) : Object.keys(obj);
|
|
474
|
-
for (let i = 0, len = keys.length; i < len; i++)
|
|
469
|
+
for (let i = 0, len = keys.length; i < len; i++)
|
|
470
|
+
try {
|
|
471
|
+
clone[keys[i]] = this.cloned(obj[keys[i]], raw, seen);
|
|
472
|
+
} catch (e) {
|
|
473
|
+
if (e instanceof RangeError) throw e;
|
|
474
|
+
}
|
|
475
475
|
if (!raw && this.config.smartCloning) this.snapCache.set(obj, clone), obj[SSVERSION] = version;
|
|
476
476
|
return clone;
|
|
477
477
|
}
|
|
@@ -559,7 +559,7 @@ var Reactor = class {
|
|
|
559
559
|
* rtr.delete("cache.temp", () => TERMINATOR);
|
|
560
560
|
*/
|
|
561
561
|
delete(path, callback, options) {
|
|
562
|
-
return this.syncAdd("delete", path, callback, options, (imm) => (imm !== "auto" || inAny(this.core, path)) && deleteAny(this.core, path
|
|
562
|
+
return this.syncAdd("delete", path, callback, options, (imm) => (imm !== "auto" || inAny(this.core, path)) && deleteAny(this.core, path));
|
|
563
563
|
}
|
|
564
564
|
/** Registers a delete mediator for a path that only triggers once. */
|
|
565
565
|
donce(path, callback, options) {
|
|
@@ -576,7 +576,7 @@ var Reactor = class {
|
|
|
576
576
|
}
|
|
577
577
|
/**
|
|
578
578
|
* Registers a watcher for a path.
|
|
579
|
-
* Watch callbacks run synchronously with the operation.
|
|
579
|
+
* Watch callbacks run synchronously with the operation, use leaf paths for reliability as it sees exact sets; no bubbling here.
|
|
580
580
|
* @param path Path or wildcard path.
|
|
581
581
|
* @param callback Watch callback.
|
|
582
582
|
* @param options Sync options.
|
|
@@ -625,7 +625,7 @@ var Reactor = class {
|
|
|
625
625
|
cord = { cb: callback, capture, depth, once, clup: () => this.off(path, callback, options), lDepth: depth !== void 0 ? this.getDepth(path) : depth };
|
|
626
626
|
if (immediate && (immediate !== "auto" || inAny(this.core, path))) {
|
|
627
627
|
const target = this.getContext(path);
|
|
628
|
-
callback(new ReactorEvent({ type: "init", target, currentTarget: target, root: this.core, rejectable: false }, this
|
|
628
|
+
callback(new ReactorEvent({ type: "init", target, currentTarget: target, root: this.core, rejectable: false }, this));
|
|
629
629
|
}
|
|
630
630
|
(cords ?? (this.listeners.set(path, cords = []), cords)).push(cord);
|
|
631
631
|
return this.bindSignal(cord, signal);
|
|
@@ -656,56 +656,39 @@ var Reactor = class {
|
|
|
656
656
|
return this.cloned(arguments.length < 2 ? this.core : branch, raw);
|
|
657
657
|
}
|
|
658
658
|
/**
|
|
659
|
-
*
|
|
660
|
-
* @param
|
|
661
|
-
* @param
|
|
662
|
-
* @
|
|
663
|
-
* rtr.on("user", (event) => rtr.cascade(event));
|
|
664
|
-
* @example
|
|
665
|
-
* rtr.watch("user", (_value, payload) => rtr.cascade(payload));
|
|
666
|
-
*/
|
|
667
|
-
cascade({ type, currentTarget: { path, value: news, oldValue: olds } }, objectSafe = true) {
|
|
668
|
-
if (type !== "set" && type !== "delete" || !canHandle(news, this.config) || (objectSafe ? !canHandle(olds, this.config) : false)) return;
|
|
669
|
-
const obj = objectSafe ? mergeObjs(olds, news) : news, keys = Object.keys(obj);
|
|
670
|
-
this.isCascading = true;
|
|
671
|
-
for (let i = 0, len = keys.length; i < len; i++) setAny(this.core, path === "*" ? keys[i] : path + "." + keys[i], obj[keys[i]]);
|
|
672
|
-
this.isCascading = false;
|
|
673
|
-
}
|
|
674
|
-
/**
|
|
675
|
-
* Installs a plugin instance.
|
|
676
|
-
* @param plugin Plugin instance.
|
|
677
|
-
* @returns Current reactor for fluent chaining.
|
|
659
|
+
* Installs a module instance.
|
|
660
|
+
* @param target Module instance.
|
|
661
|
+
* @param id Optional identification tag for this instance in the module.
|
|
662
|
+
* @returns Current `Reactor` instance for fluent chaining.
|
|
678
663
|
*/
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
this.plugins?.get(name)?.destroy();
|
|
682
|
-
return (this.plugins ??= /* @__PURE__ */ new Map()).set(name, (plugin.setup(this), plugin)), this;
|
|
664
|
+
use(target, id) {
|
|
665
|
+
return (this.modules ??= /* @__PURE__ */ new Set()).add(target.setup(this, id)), this;
|
|
683
666
|
}
|
|
684
|
-
/** Resets
|
|
667
|
+
/** Resets this reactor instance to its initial state. */
|
|
685
668
|
reset() {
|
|
686
669
|
this.getters?.clear(), this.setters?.clear(), this.deleters?.clear(), this.watchers?.clear(), this.listeners?.clear();
|
|
687
670
|
this.batch?.clear(), this.queue?.clear(), this.isBatching = false;
|
|
688
671
|
}
|
|
689
672
|
destroy() {
|
|
690
|
-
if (this.
|
|
673
|
+
if (this.modules) for (const mdle of this.modules) mdle.destroy();
|
|
691
674
|
this.reset(), nuke(this);
|
|
692
675
|
}
|
|
693
676
|
get canLog() {
|
|
694
|
-
return this.
|
|
677
|
+
return this.log !== NOOP;
|
|
695
678
|
}
|
|
696
679
|
set canLog(value) {
|
|
697
|
-
this.log =
|
|
680
|
+
this.log = value ? RTR_LOG : NOOP;
|
|
698
681
|
}
|
|
699
|
-
get
|
|
700
|
-
return this.config.
|
|
682
|
+
get canLineageTrace() {
|
|
683
|
+
return this.config.lineageTracing && this.config.referenceTracking;
|
|
701
684
|
}
|
|
702
685
|
get canSmartClone() {
|
|
703
|
-
return this.config.
|
|
686
|
+
return this.config.smartCloning && this.config.referenceTracking;
|
|
704
687
|
}
|
|
705
688
|
};
|
|
706
689
|
|
|
707
690
|
// src/ts/core/mixins.ts
|
|
708
|
-
var methods = ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "snapshot", "
|
|
691
|
+
var methods = ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "snapshot", "use", "reset", "destroy"];
|
|
709
692
|
function reactive(target, build, preferences = NIL) {
|
|
710
693
|
if ("__Reactor__" in target) return target;
|
|
711
694
|
const descriptors = {}, rtr = getReactor(target, true, build), locks = { enumerable: false, configurable: true, writable: false }, hasAffix = !!(preferences.prefix || preferences.suffix);
|
|
@@ -713,7 +696,7 @@ function reactive(target, build, preferences = NIL) {
|
|
|
713
696
|
let key = methods[i];
|
|
714
697
|
if (hasAffix) (preferences.whitelist?.includes(key) ?? true) && (key = `${preferences.prefix || ""}${key}${preferences.suffix || ""}`);
|
|
715
698
|
else if (preferences.whitelist?.includes(key)) continue;
|
|
716
|
-
descriptors[key] = { value: rtr[
|
|
699
|
+
descriptors[key] = { value: rtr[methods[i]].bind(rtr), ...locks };
|
|
717
700
|
}
|
|
718
701
|
descriptors["__Reactor__"] = { value: rtr, ...locks };
|
|
719
702
|
return Object.defineProperties(rtr.core, descriptors), rtr.core;
|
|
@@ -724,7 +707,7 @@ function inert(target) {
|
|
|
724
707
|
function live(target) {
|
|
725
708
|
return delete getRaw(target)[INERTIA], target;
|
|
726
709
|
}
|
|
727
|
-
function isInert(target) {
|
|
710
|
+
function isInert(target = NIL) {
|
|
728
711
|
return !!getRaw(target)[INERTIA];
|
|
729
712
|
}
|
|
730
713
|
function intent(target) {
|
|
@@ -733,7 +716,7 @@ function intent(target) {
|
|
|
733
716
|
function state(target) {
|
|
734
717
|
return delete getRaw(target)[REJECTABLE], target;
|
|
735
718
|
}
|
|
736
|
-
function isIntent(target) {
|
|
719
|
+
function isIntent(target = NIL) {
|
|
737
720
|
return !!getRaw(target)[REJECTABLE];
|
|
738
721
|
}
|
|
739
722
|
function volatile(target) {
|
|
@@ -742,19 +725,19 @@ function volatile(target) {
|
|
|
742
725
|
function stable(target) {
|
|
743
726
|
return delete getRaw(target)[INDIFFABLE], target;
|
|
744
727
|
}
|
|
745
|
-
function isVolatile(target) {
|
|
728
|
+
function isVolatile(target = NIL) {
|
|
746
729
|
return !!getRaw(target)[INDIFFABLE];
|
|
747
730
|
}
|
|
748
731
|
function getReactor(target, create = false, build) {
|
|
749
732
|
return (target instanceof Reactor ? target : target.__Reactor__) || (create ? new Reactor(target, build) : void 0);
|
|
750
733
|
}
|
|
751
|
-
function getRaw(target) {
|
|
752
|
-
return target
|
|
734
|
+
function getRaw(target = NIL) {
|
|
735
|
+
return target[RAW] || target;
|
|
753
736
|
}
|
|
754
|
-
function getVersion(target) {
|
|
737
|
+
function getVersion(target = NIL) {
|
|
755
738
|
return getRaw(target)[VERSION] || 0;
|
|
756
739
|
}
|
|
757
|
-
function getSnapshotVersion(target) {
|
|
740
|
+
function getSnapshotVersion(target = NIL) {
|
|
758
741
|
return getRaw(target)[SSVERSION] || 0;
|
|
759
742
|
}
|
|
760
743
|
|