sia-reactor 0.0.38 → 0.0.40
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/dist/{TimeTravelConsole-DSifvt2z.d.ts → TimeTravelConsole-BjDL0JjZ.d.ts} +2 -2
- package/dist/{TimeTravelConsole-nYAqg57U.d.cts → TimeTravelConsole-Dt8txKnt.d.cts} +2 -2
- package/dist/adapters/react.cjs +3 -3
- package/dist/adapters/react.d.cts +3 -3
- package/dist/adapters/react.d.ts +3 -3
- package/dist/adapters/react.js +3 -3
- package/dist/adapters/vanilla.cjs +3 -3
- 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-GDTGCQ2Q.js → chunk-ENEEV334.js} +5 -5
- package/dist/{chunk-FOD32N6J.js → chunk-KPJ5SPXP.js} +1 -1
- package/dist/{chunk-DCUPDG7B.js → chunk-LZJYX2LE.js} +20 -21
- package/dist/{index-BsH8KkqG.d.cts → index-BtHNGnRR.d.cts} +8 -6
- package/dist/{index-BsH8KkqG.d.ts → index-BtHNGnRR.d.ts} +8 -6
- package/dist/{index-D4DGBS2N.d.ts → index-CKHoDs6x.d.ts} +1 -1
- package/dist/{index-DBx4TIVW.d.cts → index-C_djeddc.d.cts} +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/modules.cjs +12 -11
- package/dist/modules.d.cts +5 -5
- package/dist/modules.d.ts +5 -5
- package/dist/modules.js +4 -4
- package/dist/styles/time-travel-console.css +271 -271
- package/dist/super.d.ts +9 -7
- package/dist/super.global.js +25 -26
- package/dist/utils.cjs +20 -21
- package/dist/utils.d.cts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as Reactive } from './index-
|
|
2
|
-
import { T as TimeTravelModule } from './index-
|
|
1
|
+
import { R as Reactive } from './index-BtHNGnRR.js';
|
|
2
|
+
import { T as TimeTravelModule } from './index-CKHoDs6x.js';
|
|
3
3
|
|
|
4
4
|
/** Reactive options for the TimeTravel overlay instance. */
|
|
5
5
|
interface TimeTravelConsoleConfig {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as Reactive } from './index-
|
|
2
|
-
import { T as TimeTravelModule } from './index-
|
|
1
|
+
import { R as Reactive } from './index-BtHNGnRR.cjs';
|
|
2
|
+
import { T as TimeTravelModule } from './index-C_djeddc.cjs';
|
|
3
3
|
|
|
4
4
|
/** Reactive options for the TimeTravel overlay instance. */
|
|
5
5
|
interface TimeTravelConsoleConfig {
|
package/dist/adapters/react.cjs
CHANGED
|
@@ -1260,7 +1260,7 @@ var TimeTravelConsole = class _TimeTravelConsole {
|
|
|
1260
1260
|
this.config = reactive({ title: `Time Travel Console ${this.index = ++_TimeTravelConsole.count}`, ...build });
|
|
1261
1261
|
this.state.open = !!this.config.startOpen;
|
|
1262
1262
|
let wlLive = false, blLive = false;
|
|
1263
|
-
const s = this.time.state, host = this.host = createEl("div", { className: "tt-console-host" }), toggle = createEl("button", { className: "tt-console-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "tt-console", 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(this.state.stride) }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: () => this.time.redo(this.state.stride) }), 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 }), trackUntrack = createEl("button", { onclick: () => this.time[s.tracking ? "untrack" : "track"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.trackUntrack, false) }), range = createEl("input", { type: "range", min: "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 History Entry" }), io = createEl("textarea", { className: "tt-io", placeholder: "timeline payload json", title: "Time History", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "tt-footnote", innerHTML: "<span>
|
|
1263
|
+
const s = this.time.state, host = this.host = createEl("div", { className: "sia-tt-console-host" }), toggle = createEl("button", { className: "sia-tt-console-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "sia-tt-console", 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(this.state.stride) }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: () => this.time.redo(this.state.stride) }), 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 }), trackUntrack = createEl("button", { onclick: () => this.time[s.tracking ? "untrack" : "track"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.trackUntrack, false) }), range = createEl("input", { type: "range", min: "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: "sia-tt-io", readOnly: true, placeholder: "current payload json", title: "Current History Entry" }), io = createEl("textarea", { className: "sia-tt-io", placeholder: "timeline payload json", title: "Time History", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "sia-tt-footnote", innerHTML: "<span>Try this in your app? </span>" }), link = createEl("a", { target: "_blank", rel: "noreferrer noopener", textContent: "sia-reactor", href: "https://www.npmjs.com/package/sia-reactor" }), box = createEl("div", { className: "sia-tt-status-box" }), status = createEl("div", { className: "sia-tt-status-row" }), filters = createEl("div", { className: "sia-tt-status-row" }), filterBox = createEl("div", { className: "sia-tt-status-box" }), whitelistLabel = createEl("span", { className: "muted", textContent: "Whitelist:" }), blacklistLabel = createEl("span", { className: "muted", textContent: "Blacklist:" }), whitelist = createEl("input", { className: "sia-tt-filter-input sia-tt-io", placeholder: 'a.b, c.d or {"0":["a.b"]}', title: "Whitelist paths", onfocus: () => wlLive = true, onblur: () => (wlLive = false, whitelist.value = formatPaths(this.time.config.whitelist, "*")), oninput: (_, parsed = parsePaths(whitelist.value)) => parsed !== null && (this.time.config.whitelist = parsed) }), blacklist = createEl("input", { className: "sia-tt-filter-input sia-tt-io", placeholder: 'a.b, c.d or {"0":["a.b"]}', title: "Blacklist paths", onfocus: () => blLive = true, onblur: () => (blLive = false, blacklist.value = formatPaths(this.time.config.blacklist, "")), oninput: (_, parsed = parsePaths(blacklist.value, true)) => parsed !== null && (this.time.config.blacklist = parsed) }), speed = createEl("select", { className: "sia-tt-speed", title: "Playback Speed", onchange: () => this.time.config.playbackRate = Number(speed.value) }), stride = createEl("input", { className: "sia-tt-stride sia-tt-button sia-tt-mini-input", type: "number", min: "1", title: "Skip Stride i.e. how many steps count as one unit", oninput: () => this.state.stride = Math.max(1, Number(stride.value) || 1) }), stats = createEl("span", { className: "sia-tt-stats" }), limit = createEl("input", { className: "sia-tt-limit sia-tt-mini-input sia-tt-button", type: "number", min: "1", title: "Maximum number of history entries kept in memory before older entries are discarded.", oninput: () => this.time.config.limit = Math.max(1, Number(limit.value) || 1) }), delay = createEl("input", { className: "sia-tt-delay sia-tt-mini-input sia-tt-button", type: "number", min: "0", step: "50", title: "Maximum playback delay between timeline frames in milliseconds.", oninput: () => this.time.config.maxPlaybackDelay = Math.max(0, Number(delay.value) || 0) }), read = createEl("label", { className: "sia-tt-check", title: "When recording intent mutations, read previous values from the matching state path instead of the intent path. Useful for accurate undo reconstruction of intent-driven flows." }), readBox = createEl("input", { type: "checkbox", checked: !!this.time.config.mirrorReads, onchange: () => this.time.config.mirrorReads = readBox.checked }), write = createEl("label", { className: "sia-tt-check", title: "During playback and teleportation, mirror state writes into matching intent paths to re-enact the recorded history. Useful for accurate reconstruction of the whole session." }), writeBox = createEl("input", { type: "checkbox", checked: !!this.time.config.mirrorWrites, onchange: () => this.time.config.mirrorWrites = writeBox.checked }), filterRow1 = createEl("div", { className: "sia-tt-filter-row" }), filterRow2 = createEl("div", { className: "sia-tt-filter-row" }), row1 = createEl("div", { className: "sia-tt-row" }), row2 = createEl("div", { className: "sia-tt-row" }), row3 = createEl("div", { className: "sia-tt-row" }), row4 = createEl("div", { className: "sia-tt-row" }), row5 = createEl("div", { className: "sia-tt-row sia-tt-config-row" });
|
|
1264
1264
|
speed.append(...[0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 4, 8, 16, 32].map((v) => createEl("option", { value: String(v), textContent: `${v}x` })));
|
|
1265
1265
|
status.append((box.append(frame), box), clrHistory);
|
|
1266
1266
|
filters.append((filterBox.append((filterRow1.append(whitelistLabel, whitelist), filterRow1), (filterRow2.append(blacklistLabel, blacklist), filterRow2)), filterBox));
|
|
@@ -1319,9 +1319,9 @@ var TimeTravelConsole = class _TimeTravelConsole {
|
|
|
1319
1319
|
function getDock(container) {
|
|
1320
1320
|
const host = container && container !== document.documentElement ? container : document.body;
|
|
1321
1321
|
if (host !== document.body && getComputedStyle(host).position === "static") host.style.position = "relative";
|
|
1322
|
-
const layer = host.querySelector(":scope > .tt-console-layer") || createEl("div", { className: "tt-console-layer" }, void 0, { position: host === document.body ? "fixed" : "absolute" });
|
|
1322
|
+
const layer = host.querySelector(":scope > .sia-tt-console-layer") || createEl("div", { className: "sia-tt-console-layer" }, void 0, { position: host === document.body ? "fixed" : "absolute" });
|
|
1323
1323
|
if (layer.parentElement !== host) host.appendChild(layer);
|
|
1324
|
-
const dock = layer.querySelector(":scope > .tt-console-dock") || createEl("div", { className: "tt-console-dock" });
|
|
1324
|
+
const dock = layer.querySelector(":scope > .sia-tt-console-dock") || createEl("div", { className: "sia-tt-console-dock" });
|
|
1325
1325
|
return dock.parentElement !== layer && layer.appendChild(dock), dock;
|
|
1326
1326
|
}
|
|
1327
1327
|
function formatPaths(paths, emptyText) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { E as EffectOptions, d as Reactor, R as Reactive, J as ReactorBuild, K as DeepReadonly, W as WildPaths, a as PathValue } from '../index-
|
|
1
|
+
import { E as EffectOptions, d as Reactor, R as Reactive, J as ReactorBuild, K as DeepReadonly, W as WildPaths, a as PathValue } from '../index-BtHNGnRR.cjs';
|
|
2
2
|
import { useLayoutEffect } from 'react';
|
|
3
|
-
import { T as TimeTravelModule } from '../index-
|
|
4
|
-
import { a as TimeTravelConsoleConfig } from '../TimeTravelConsole-
|
|
3
|
+
import { T as TimeTravelModule } from '../index-C_djeddc.cjs';
|
|
4
|
+
import { a as TimeTravelConsoleConfig } from '../TimeTravelConsole-Dt8txKnt.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Subscribes a component to desired Reactor state and returns it.
|
package/dist/adapters/react.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { E as EffectOptions, d as Reactor, R as Reactive, J as ReactorBuild, K as DeepReadonly, W as WildPaths, a as PathValue } from '../index-
|
|
1
|
+
import { E as EffectOptions, d as Reactor, R as Reactive, J as ReactorBuild, K as DeepReadonly, W as WildPaths, a as PathValue } from '../index-BtHNGnRR.js';
|
|
2
2
|
import { useLayoutEffect } from 'react';
|
|
3
|
-
import { T as TimeTravelModule } from '../index-
|
|
4
|
-
import { a as TimeTravelConsoleConfig } from '../TimeTravelConsole-
|
|
3
|
+
import { T as TimeTravelModule } from '../index-CKHoDs6x.js';
|
|
4
|
+
import { a as TimeTravelConsoleConfig } from '../TimeTravelConsole-BjDL0JjZ.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Subscribes a component to desired Reactor state and returns it.
|
package/dist/adapters/react.js
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
Autotracker,
|
|
3
3
|
TimeTravelConsole,
|
|
4
4
|
withTracker
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-ENEEV334.js";
|
|
6
|
+
import "../chunk-KPJ5SPXP.js";
|
|
7
7
|
import "../chunk-ORK3EGB6.js";
|
|
8
8
|
import {
|
|
9
9
|
CTX,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
NOOP,
|
|
12
12
|
getPath,
|
|
13
13
|
getReactor
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-LZJYX2LE.js";
|
|
15
15
|
|
|
16
16
|
// src/ts/adapters/react/hooks/useReactor.ts
|
|
17
17
|
import { useRef, useCallback, useSyncExternalStore, useMemo } from "react";
|
|
@@ -1167,7 +1167,7 @@ var TimeTravelConsole = class _TimeTravelConsole {
|
|
|
1167
1167
|
this.config = reactive({ title: `Time Travel Console ${this.index = ++_TimeTravelConsole.count}`, ...build });
|
|
1168
1168
|
this.state.open = !!this.config.startOpen;
|
|
1169
1169
|
let wlLive = false, blLive = false;
|
|
1170
|
-
const s = this.time.state, host = this.host = createEl("div", { className: "tt-console-host" }), toggle = createEl("button", { className: "tt-console-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "tt-console", 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(this.state.stride) }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: () => this.time.redo(this.state.stride) }), 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 }), trackUntrack = createEl("button", { onclick: () => this.time[s.tracking ? "untrack" : "track"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.trackUntrack, false) }), range = createEl("input", { type: "range", min: "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 History Entry" }), io = createEl("textarea", { className: "tt-io", placeholder: "timeline payload json", title: "Time History", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "tt-footnote", innerHTML: "<span>
|
|
1170
|
+
const s = this.time.state, host = this.host = createEl("div", { className: "sia-tt-console-host" }), toggle = createEl("button", { className: "sia-tt-console-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "sia-tt-console", 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(this.state.stride) }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: () => this.time.redo(this.state.stride) }), 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 }), trackUntrack = createEl("button", { onclick: () => this.time[s.tracking ? "untrack" : "track"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.trackUntrack, false) }), range = createEl("input", { type: "range", min: "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: "sia-tt-io", readOnly: true, placeholder: "current payload json", title: "Current History Entry" }), io = createEl("textarea", { className: "sia-tt-io", placeholder: "timeline payload json", title: "Time History", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "sia-tt-footnote", innerHTML: "<span>Try this in your app? </span>" }), link = createEl("a", { target: "_blank", rel: "noreferrer noopener", textContent: "sia-reactor", href: "https://www.npmjs.com/package/sia-reactor" }), box = createEl("div", { className: "sia-tt-status-box" }), status = createEl("div", { className: "sia-tt-status-row" }), filters = createEl("div", { className: "sia-tt-status-row" }), filterBox = createEl("div", { className: "sia-tt-status-box" }), whitelistLabel = createEl("span", { className: "muted", textContent: "Whitelist:" }), blacklistLabel = createEl("span", { className: "muted", textContent: "Blacklist:" }), whitelist = createEl("input", { className: "sia-tt-filter-input sia-tt-io", placeholder: 'a.b, c.d or {"0":["a.b"]}', title: "Whitelist paths", onfocus: () => wlLive = true, onblur: () => (wlLive = false, whitelist.value = formatPaths(this.time.config.whitelist, "*")), oninput: (_, parsed = parsePaths(whitelist.value)) => parsed !== null && (this.time.config.whitelist = parsed) }), blacklist = createEl("input", { className: "sia-tt-filter-input sia-tt-io", placeholder: 'a.b, c.d or {"0":["a.b"]}', title: "Blacklist paths", onfocus: () => blLive = true, onblur: () => (blLive = false, blacklist.value = formatPaths(this.time.config.blacklist, "")), oninput: (_, parsed = parsePaths(blacklist.value, true)) => parsed !== null && (this.time.config.blacklist = parsed) }), speed = createEl("select", { className: "sia-tt-speed", title: "Playback Speed", onchange: () => this.time.config.playbackRate = Number(speed.value) }), stride = createEl("input", { className: "sia-tt-stride sia-tt-button sia-tt-mini-input", type: "number", min: "1", title: "Skip Stride i.e. how many steps count as one unit", oninput: () => this.state.stride = Math.max(1, Number(stride.value) || 1) }), stats = createEl("span", { className: "sia-tt-stats" }), limit = createEl("input", { className: "sia-tt-limit sia-tt-mini-input sia-tt-button", type: "number", min: "1", title: "Maximum number of history entries kept in memory before older entries are discarded.", oninput: () => this.time.config.limit = Math.max(1, Number(limit.value) || 1) }), delay = createEl("input", { className: "sia-tt-delay sia-tt-mini-input sia-tt-button", type: "number", min: "0", step: "50", title: "Maximum playback delay between timeline frames in milliseconds.", oninput: () => this.time.config.maxPlaybackDelay = Math.max(0, Number(delay.value) || 0) }), read = createEl("label", { className: "sia-tt-check", title: "When recording intent mutations, read previous values from the matching state path instead of the intent path. Useful for accurate undo reconstruction of intent-driven flows." }), readBox = createEl("input", { type: "checkbox", checked: !!this.time.config.mirrorReads, onchange: () => this.time.config.mirrorReads = readBox.checked }), write = createEl("label", { className: "sia-tt-check", title: "During playback and teleportation, mirror state writes into matching intent paths to re-enact the recorded history. Useful for accurate reconstruction of the whole session." }), writeBox = createEl("input", { type: "checkbox", checked: !!this.time.config.mirrorWrites, onchange: () => this.time.config.mirrorWrites = writeBox.checked }), filterRow1 = createEl("div", { className: "sia-tt-filter-row" }), filterRow2 = createEl("div", { className: "sia-tt-filter-row" }), row1 = createEl("div", { className: "sia-tt-row" }), row2 = createEl("div", { className: "sia-tt-row" }), row3 = createEl("div", { className: "sia-tt-row" }), row4 = createEl("div", { className: "sia-tt-row" }), row5 = createEl("div", { className: "sia-tt-row sia-tt-config-row" });
|
|
1171
1171
|
speed.append(...[0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 4, 8, 16, 32].map((v) => createEl("option", { value: String(v), textContent: `${v}x` })));
|
|
1172
1172
|
status.append((box.append(frame), box), clrHistory);
|
|
1173
1173
|
filters.append((filterBox.append((filterRow1.append(whitelistLabel, whitelist), filterRow1), (filterRow2.append(blacklistLabel, blacklist), filterRow2)), filterBox));
|
|
@@ -1226,9 +1226,9 @@ var TimeTravelConsole = class _TimeTravelConsole {
|
|
|
1226
1226
|
function getDock(container) {
|
|
1227
1227
|
const host = container && container !== document.documentElement ? container : document.body;
|
|
1228
1228
|
if (host !== document.body && getComputedStyle(host).position === "static") host.style.position = "relative";
|
|
1229
|
-
const layer = host.querySelector(":scope > .tt-console-layer") || createEl("div", { className: "tt-console-layer" }, void 0, { position: host === document.body ? "fixed" : "absolute" });
|
|
1229
|
+
const layer = host.querySelector(":scope > .sia-tt-console-layer") || createEl("div", { className: "sia-tt-console-layer" }, void 0, { position: host === document.body ? "fixed" : "absolute" });
|
|
1230
1230
|
if (layer.parentElement !== host) host.appendChild(layer);
|
|
1231
|
-
const dock = layer.querySelector(":scope > .tt-console-dock") || createEl("div", { className: "tt-console-dock" });
|
|
1231
|
+
const dock = layer.querySelector(":scope > .sia-tt-console-dock") || createEl("div", { className: "sia-tt-console-dock" });
|
|
1232
1232
|
return dock.parentElement !== layer && layer.appendChild(dock), dock;
|
|
1233
1233
|
}
|
|
1234
1234
|
function formatPaths(paths, emptyText) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { E as EffectOptions } from '../index-
|
|
2
|
-
export { A as Autotracker, w as withTracker } from '../index-
|
|
3
|
-
export { T as TimeTravelConsole, a as TimeTravelConsoleConfig } from '../TimeTravelConsole-
|
|
4
|
-
import '../index-
|
|
1
|
+
import { E as EffectOptions } from '../index-BtHNGnRR.cjs';
|
|
2
|
+
export { A as Autotracker, w as withTracker } from '../index-BtHNGnRR.cjs';
|
|
3
|
+
export { T as TimeTravelConsole, a as TimeTravelConsoleConfig } from '../TimeTravelConsole-Dt8txKnt.cjs';
|
|
4
|
+
import '../index-C_djeddc.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Runs a reactive side effect in vanilla JavaScript.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { E as EffectOptions } from '../index-
|
|
2
|
-
export { A as Autotracker, w as withTracker } from '../index-
|
|
3
|
-
export { T as TimeTravelConsole, a as TimeTravelConsoleConfig } from '../TimeTravelConsole-
|
|
4
|
-
import '../index-
|
|
1
|
+
import { E as EffectOptions } from '../index-BtHNGnRR.js';
|
|
2
|
+
export { A as Autotracker, w as withTracker } from '../index-BtHNGnRR.js';
|
|
3
|
+
export { T as TimeTravelConsole, a as TimeTravelConsoleConfig } from '../TimeTravelConsole-BjDL0JjZ.js';
|
|
4
|
+
import '../index-CKHoDs6x.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Runs a reactive side effect in vanilla JavaScript.
|
package/dist/adapters/vanilla.js
CHANGED
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
TimeTravelConsole,
|
|
4
4
|
effect,
|
|
5
5
|
withTracker
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-ENEEV334.js";
|
|
7
|
+
import "../chunk-KPJ5SPXP.js";
|
|
8
8
|
import "../chunk-ORK3EGB6.js";
|
|
9
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-LZJYX2LE.js";
|
|
10
10
|
export {
|
|
11
11
|
Autotracker,
|
|
12
12
|
TimeTravelConsole,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
wpArr
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KPJ5SPXP.js";
|
|
4
4
|
import {
|
|
5
5
|
KEYS_BLOCKS,
|
|
6
6
|
createEl,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
canHandle,
|
|
16
16
|
nuke,
|
|
17
17
|
reactive
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-LZJYX2LE.js";
|
|
19
19
|
|
|
20
20
|
// src/ts/adapters/autotracker.ts
|
|
21
21
|
var Autotracker = class {
|
|
@@ -200,7 +200,7 @@ var TimeTravelConsole = class _TimeTravelConsole {
|
|
|
200
200
|
this.config = reactive({ title: `Time Travel Console ${this.index = ++_TimeTravelConsole.count}`, ...build });
|
|
201
201
|
this.state.open = !!this.config.startOpen;
|
|
202
202
|
let wlLive = false, blLive = false;
|
|
203
|
-
const s = this.time.state, host = this.host = createEl("div", { className: "tt-console-host" }), toggle = createEl("button", { className: "tt-console-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "tt-console", 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(this.state.stride) }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: () => this.time.redo(this.state.stride) }), 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 }), trackUntrack = createEl("button", { onclick: () => this.time[s.tracking ? "untrack" : "track"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.trackUntrack, false) }), range = createEl("input", { type: "range", min: "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 History Entry" }), io = createEl("textarea", { className: "tt-io", placeholder: "timeline payload json", title: "Time History", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "tt-footnote", innerHTML: "<span>
|
|
203
|
+
const s = this.time.state, host = this.host = createEl("div", { className: "sia-tt-console-host" }), toggle = createEl("button", { className: "sia-tt-console-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "sia-tt-console", 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(this.state.stride) }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: () => this.time.redo(this.state.stride) }), 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 }), trackUntrack = createEl("button", { onclick: () => this.time[s.tracking ? "untrack" : "track"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.trackUntrack, false) }), range = createEl("input", { type: "range", min: "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: "sia-tt-io", readOnly: true, placeholder: "current payload json", title: "Current History Entry" }), io = createEl("textarea", { className: "sia-tt-io", placeholder: "timeline payload json", title: "Time History", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "sia-tt-footnote", innerHTML: "<span>Try this in your app? </span>" }), link = createEl("a", { target: "_blank", rel: "noreferrer noopener", textContent: "sia-reactor", href: "https://www.npmjs.com/package/sia-reactor" }), box = createEl("div", { className: "sia-tt-status-box" }), status = createEl("div", { className: "sia-tt-status-row" }), filters = createEl("div", { className: "sia-tt-status-row" }), filterBox = createEl("div", { className: "sia-tt-status-box" }), whitelistLabel = createEl("span", { className: "muted", textContent: "Whitelist:" }), blacklistLabel = createEl("span", { className: "muted", textContent: "Blacklist:" }), whitelist = createEl("input", { className: "sia-tt-filter-input sia-tt-io", placeholder: 'a.b, c.d or {"0":["a.b"]}', title: "Whitelist paths", onfocus: () => wlLive = true, onblur: () => (wlLive = false, whitelist.value = formatPaths(this.time.config.whitelist, "*")), oninput: (_, parsed = parsePaths(whitelist.value)) => parsed !== null && (this.time.config.whitelist = parsed) }), blacklist = createEl("input", { className: "sia-tt-filter-input sia-tt-io", placeholder: 'a.b, c.d or {"0":["a.b"]}', title: "Blacklist paths", onfocus: () => blLive = true, onblur: () => (blLive = false, blacklist.value = formatPaths(this.time.config.blacklist, "")), oninput: (_, parsed = parsePaths(blacklist.value, true)) => parsed !== null && (this.time.config.blacklist = parsed) }), speed = createEl("select", { className: "sia-tt-speed", title: "Playback Speed", onchange: () => this.time.config.playbackRate = Number(speed.value) }), stride = createEl("input", { className: "sia-tt-stride sia-tt-button sia-tt-mini-input", type: "number", min: "1", title: "Skip Stride i.e. how many steps count as one unit", oninput: () => this.state.stride = Math.max(1, Number(stride.value) || 1) }), stats = createEl("span", { className: "sia-tt-stats" }), limit = createEl("input", { className: "sia-tt-limit sia-tt-mini-input sia-tt-button", type: "number", min: "1", title: "Maximum number of history entries kept in memory before older entries are discarded.", oninput: () => this.time.config.limit = Math.max(1, Number(limit.value) || 1) }), delay = createEl("input", { className: "sia-tt-delay sia-tt-mini-input sia-tt-button", type: "number", min: "0", step: "50", title: "Maximum playback delay between timeline frames in milliseconds.", oninput: () => this.time.config.maxPlaybackDelay = Math.max(0, Number(delay.value) || 0) }), read = createEl("label", { className: "sia-tt-check", title: "When recording intent mutations, read previous values from the matching state path instead of the intent path. Useful for accurate undo reconstruction of intent-driven flows." }), readBox = createEl("input", { type: "checkbox", checked: !!this.time.config.mirrorReads, onchange: () => this.time.config.mirrorReads = readBox.checked }), write = createEl("label", { className: "sia-tt-check", title: "During playback and teleportation, mirror state writes into matching intent paths to re-enact the recorded history. Useful for accurate reconstruction of the whole session." }), writeBox = createEl("input", { type: "checkbox", checked: !!this.time.config.mirrorWrites, onchange: () => this.time.config.mirrorWrites = writeBox.checked }), filterRow1 = createEl("div", { className: "sia-tt-filter-row" }), filterRow2 = createEl("div", { className: "sia-tt-filter-row" }), row1 = createEl("div", { className: "sia-tt-row" }), row2 = createEl("div", { className: "sia-tt-row" }), row3 = createEl("div", { className: "sia-tt-row" }), row4 = createEl("div", { className: "sia-tt-row" }), row5 = createEl("div", { className: "sia-tt-row sia-tt-config-row" });
|
|
204
204
|
speed.append(...[0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 4, 8, 16, 32].map((v) => createEl("option", { value: String(v), textContent: `${v}x` })));
|
|
205
205
|
status.append((box.append(frame), box), clrHistory);
|
|
206
206
|
filters.append((filterBox.append((filterRow1.append(whitelistLabel, whitelist), filterRow1), (filterRow2.append(blacklistLabel, blacklist), filterRow2)), filterBox));
|
|
@@ -259,9 +259,9 @@ var TimeTravelConsole = class _TimeTravelConsole {
|
|
|
259
259
|
function getDock(container) {
|
|
260
260
|
const host = container && container !== document.documentElement ? container : document.body;
|
|
261
261
|
if (host !== document.body && getComputedStyle(host).position === "static") host.style.position = "relative";
|
|
262
|
-
const layer = host.querySelector(":scope > .tt-console-layer") || createEl("div", { className: "tt-console-layer" }, void 0, { position: host === document.body ? "fixed" : "absolute" });
|
|
262
|
+
const layer = host.querySelector(":scope > .sia-tt-console-layer") || createEl("div", { className: "sia-tt-console-layer" }, void 0, { position: host === document.body ? "fixed" : "absolute" });
|
|
263
263
|
if (layer.parentElement !== host) host.appendChild(layer);
|
|
264
|
-
const dock = layer.querySelector(":scope > .tt-console-dock") || createEl("div", { className: "tt-console-dock" });
|
|
264
|
+
const dock = layer.querySelector(":scope > .sia-tt-console-dock") || createEl("div", { className: "sia-tt-console-dock" });
|
|
265
265
|
return dock.parentElement !== layer && layer.appendChild(dock), dock;
|
|
266
266
|
}
|
|
267
267
|
function formatPaths(paths, emptyText) {
|
|
@@ -176,24 +176,25 @@ function parseEvtOpts(options, opts, boolOpt = opts[0], result = {}) {
|
|
|
176
176
|
function fanout(a, b, c, d) {
|
|
177
177
|
const isEvPd = !!a?.target, isPath = !isEvPd && "string" === typeof b, [state2, path, olds, news, opts, type] = isEvPd ? [a.root, a.currentTarget.path, a.currentTarget.oldValue, a.currentTarget.value, b || NIL, a.type] : isPath ? [a, b, getPath(a, b), c, d || NIL, void 0] : [void 0, void 0, a, b, c || NIL, void 0], target = isEvPd ? getPath(a.root, a.currentTarget.path) : isPath ? getPath(state2, path) : olds;
|
|
178
178
|
if (isEvPd && type !== "set" && type !== "delete" || !target || !canHandle(news, opts)) return;
|
|
179
|
+
const { merge = false, depth, atomic = true, skipUndef = false, cloneSets = false, txLabel } = opts;
|
|
179
180
|
const func = () => {
|
|
180
|
-
const walk = (target2, obj,
|
|
181
|
+
const walk = (target2, obj, depth2 = isEvPd ? 1 : Infinity, keys = Object.keys(obj)) => {
|
|
181
182
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
182
183
|
const key = keys[i], val = obj[key];
|
|
183
184
|
try {
|
|
184
|
-
if (
|
|
185
|
-
else
|
|
185
|
+
if (atomic && Array.isArray(val)) target2[key] = cloneSets ? deepClone(val) : val, target2[key].length = target2[key].length;
|
|
186
|
+
else depth2 > 1 && canHandle(val, opts) ? walk(target2[key] ||= {}, val, depth2 - 1) : (!skipUndef || val !== void 0) && (target2[key] = cloneSets ? deepClone(val) : val);
|
|
186
187
|
} catch (e) {
|
|
187
188
|
if (e instanceof RangeError) throw e;
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
191
|
};
|
|
191
|
-
if (
|
|
192
|
-
else walk(target,
|
|
192
|
+
if (atomic && Array.isArray(news) && isPath) setPath(state2, path, cloneSets ? deepClone(news) : news), getPath(state2, path).length = news.length;
|
|
193
|
+
else walk(target, merge ? mergeObjs(olds, news, opts) : news, depth === true ? Infinity : depth);
|
|
193
194
|
};
|
|
194
|
-
force(() => transaction(func,
|
|
195
|
+
force(() => transaction(func, txLabel ?? `${path ? `Fanout -> '${path}'` : `Fanout`} (Tx ${txId + 1})`), CTX.usingForce || isEvPd);
|
|
195
196
|
}
|
|
196
|
-
var fanoutOptsArr = ["merge", "depth", "atomic", "
|
|
197
|
+
var fanoutOptsArr = ["merge", "depth", "atomic", "skipUndef"];
|
|
197
198
|
function force(task, bool = true) {
|
|
198
199
|
const prev = CTX.usingForce;
|
|
199
200
|
CTX.usingForce = bool;
|
|
@@ -206,8 +207,8 @@ function force(task, bool = true) {
|
|
|
206
207
|
function mergeObjs(o1, o2, config = NIL, pojocheck = true) {
|
|
207
208
|
if (pojocheck && (!isPOJO(o1 || NIL, config) || !isPOJO(o2 || NIL, config))) return o2;
|
|
208
209
|
o1 ||= {}, o2 ||= {};
|
|
209
|
-
const merged = config.
|
|
210
|
-
if (config.
|
|
210
|
+
const merged = config.skipUndef ? { ...o1 } : { ...o1, ...o2 };
|
|
211
|
+
if (config.skipUndef) {
|
|
211
212
|
const keys2 = Object.keys(o1);
|
|
212
213
|
for (let i = 0, len = keys2.length; i < len; i++) {
|
|
213
214
|
const key = keys2[i], val = o2[key];
|
|
@@ -300,20 +301,18 @@ function isLeafPath(obj, path, config = CTX.defaults, value = getPath(obj, path,
|
|
|
300
301
|
return path !== "*" && !canHandle(value, config);
|
|
301
302
|
}
|
|
302
303
|
function createReactorSync(rA, rB, prefixA, prefixB = "", signal) {
|
|
303
|
-
const
|
|
304
|
+
const rtrA = getReactor(rA, true), rtrB = getReactor(rB, true);
|
|
304
305
|
let origin = null;
|
|
305
|
-
const sync = (
|
|
306
|
-
if (origin === (
|
|
307
|
-
const { path, object, key } = payload.target;
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
setPath(destCore, pDest ? stripped ? `${pDest}.${stripped}` : pDest : stripped || "*", Array.isArray(object) ? object : val);
|
|
312
|
-
origin = null;
|
|
306
|
+
const sync = (src, dest, srcP, destP) => (val, payload) => {
|
|
307
|
+
if (origin === (src ^ 1)) return;
|
|
308
|
+
const { path, object: obj, key } = payload.target;
|
|
309
|
+
if (srcP && path !== srcP && !path.startsWith(srcP + ".")) return;
|
|
310
|
+
const isArr = Array.isArray(obj), origP = isArr ? path.slice(0, -(key.length + 1)) : path, syncP = origP === srcP ? "" : srcP ? origP.slice(srcP.length + 1) : origP;
|
|
311
|
+
origin = src, setPath(dest, destP ? syncP ? `${destP}.${syncP}` : destP : syncP || "*", isArr ? deepClone(obj) : val), origin = null;
|
|
313
312
|
};
|
|
314
|
-
const
|
|
315
|
-
if (
|
|
316
|
-
const clupA =
|
|
313
|
+
const initA = prefixA ? getPath(rtrA.core, prefixA) : rtrA.core;
|
|
314
|
+
if (initA !== void 0) fanout(rtrB.core, prefixB || "*", initA, { depth: 1, cloneSets: true, txLabel: `ReactorSync: ${prefixA}^ <-> ${prefixB}` });
|
|
315
|
+
const clupA = rtrA.watch("*", sync(0, rtrB.core, prefixA, prefixB), { signal }), clupB = rtrB.watch("*", sync(1, rtrA.core, prefixB, prefixA), { signal });
|
|
317
316
|
return () => (clupA(), clupB());
|
|
318
317
|
}
|
|
319
318
|
|
|
@@ -509,10 +509,12 @@ interface FanoutOptionsTuple extends Partial<Record<(typeof fanoutOptsArr)[numbe
|
|
|
509
509
|
depth?: number | boolean;
|
|
510
510
|
/** Whether to assign arrays as a whole and only touch `.length` for common cases. Only works with the `path` parameter overload or in nested levels.
|
|
511
511
|
* Arrays can lead to unnecessary work as more often than not, you won't be watching index paths but waiting on the parent bubble instead.
|
|
512
|
-
* If you happen to be watching, it might be more optimal to re-set it yourself if it's only a few indexes or just
|
|
512
|
+
* If you happen to be watching, it might be more optimal to re-set it yourself if it's only a few indexes or just set this to `false`. @default `true` */
|
|
513
513
|
atomic?: boolean;
|
|
514
514
|
/** Whether to skip `undefined` values during fanout. @default `false`. */
|
|
515
|
-
|
|
515
|
+
skipUndef?: boolean;
|
|
516
|
+
/** Whether to clone before setting any final values, prevents unintended reference sharing across the state tree. @default `false`. */
|
|
517
|
+
cloneSets?: boolean;
|
|
516
518
|
/** A label for the transaction that will be started, useful for debugging and tracking. @default `Fanout -> "${path}"` : `Fanout`} (Tx ${CTX.txId})`. */
|
|
517
519
|
txLabel?: string;
|
|
518
520
|
}
|
|
@@ -536,7 +538,7 @@ declare function fanout<T extends object>(target: T, value: Partial<T> | Partial
|
|
|
536
538
|
declare function fanout<T extends object, P extends WildPaths<T> = WildPaths<T>>(state: T, path: P, value: Partial<PathValue<T, P>>, options?: {
|
|
537
539
|
crossRealms?: boolean;
|
|
538
540
|
} & FanoutOptionsTuple): void;
|
|
539
|
-
declare const fanoutOptsArr: readonly ["merge", "depth", "atomic", "
|
|
541
|
+
declare const fanoutOptsArr: readonly ["merge", "depth", "atomic", "skipUndef"];
|
|
540
542
|
/**
|
|
541
543
|
* Executes a task while forcing all reactive writes to bypass equality checks.
|
|
542
544
|
* @param task The mutation logic to execute.
|
|
@@ -545,13 +547,13 @@ declare const fanoutOptsArr: readonly ["merge", "depth", "atomic", "skipUndefine
|
|
|
545
547
|
*/
|
|
546
548
|
declare function force<T>(task: () => T, bool?: boolean): T;
|
|
547
549
|
/**
|
|
548
|
-
* Deep-merges object-like values, does necessary checks so use without doubts. Only `o2` keys are checked when `
|
|
550
|
+
* Deep-merges object-like values, does necessary checks so use without doubts. Only `o2` keys are checked when `skipUndef` is true.
|
|
549
551
|
* @example
|
|
550
552
|
* const next = mergeObjs({ user: { name: "Kosi" } }, { user: { role: "admin" } }); // { ...o1, ...o2 } // o2 over o1 and deep!
|
|
551
553
|
*/
|
|
552
554
|
declare function mergeObjs<T1 extends object, T2 extends object>(o1?: T1 | null, o2?: T2 | null, config?: {
|
|
553
555
|
crossRealms?: boolean;
|
|
554
|
-
|
|
556
|
+
skipUndef?: boolean;
|
|
555
557
|
}, pojocheck?: boolean): DeepMerge<T1, T2>;
|
|
556
558
|
/** Returns [path, parent, value] records from root to the target path. */
|
|
557
559
|
declare function getTrailRecords<T extends object>(obj: T, path: WildPaths<T>, reverse?: boolean): [WildPaths<T>, PathBranchValue<T, WildPaths<T>>, PathValue<T, WildPaths<T>>][];
|
|
@@ -592,7 +594,7 @@ declare function isLeafPath<T extends object, const S extends string = ".", P ex
|
|
|
592
594
|
separator?: S;
|
|
593
595
|
} & typeof CTX.defaults, value?: PathValue<T, P, S>): boolean;
|
|
594
596
|
/**
|
|
595
|
-
* Creates a two-way, array-
|
|
597
|
+
* Creates a two-way, array-atomic, echo-proof sync bridge between two S.I.A Reactors. Uses a synchronous origin lock to prevent infinite echo loops.
|
|
596
598
|
* On setup, `rA` hydrates `rB` at `prefixB` with a deep clone of its current state at `prefixA` (primary drives initial truth).
|
|
597
599
|
* @param rA Primary reactor — source of truth. Its `prefixA` slice seeds `rB.prefixB` on setup.
|
|
598
600
|
* @param rB Secondary reactor — the wider store (e.g. `ctlr.config`). Holds the primary at a named path.
|
|
@@ -509,10 +509,12 @@ interface FanoutOptionsTuple extends Partial<Record<(typeof fanoutOptsArr)[numbe
|
|
|
509
509
|
depth?: number | boolean;
|
|
510
510
|
/** Whether to assign arrays as a whole and only touch `.length` for common cases. Only works with the `path` parameter overload or in nested levels.
|
|
511
511
|
* Arrays can lead to unnecessary work as more often than not, you won't be watching index paths but waiting on the parent bubble instead.
|
|
512
|
-
* If you happen to be watching, it might be more optimal to re-set it yourself if it's only a few indexes or just
|
|
512
|
+
* If you happen to be watching, it might be more optimal to re-set it yourself if it's only a few indexes or just set this to `false`. @default `true` */
|
|
513
513
|
atomic?: boolean;
|
|
514
514
|
/** Whether to skip `undefined` values during fanout. @default `false`. */
|
|
515
|
-
|
|
515
|
+
skipUndef?: boolean;
|
|
516
|
+
/** Whether to clone before setting any final values, prevents unintended reference sharing across the state tree. @default `false`. */
|
|
517
|
+
cloneSets?: boolean;
|
|
516
518
|
/** A label for the transaction that will be started, useful for debugging and tracking. @default `Fanout -> "${path}"` : `Fanout`} (Tx ${CTX.txId})`. */
|
|
517
519
|
txLabel?: string;
|
|
518
520
|
}
|
|
@@ -536,7 +538,7 @@ declare function fanout<T extends object>(target: T, value: Partial<T> | Partial
|
|
|
536
538
|
declare function fanout<T extends object, P extends WildPaths<T> = WildPaths<T>>(state: T, path: P, value: Partial<PathValue<T, P>>, options?: {
|
|
537
539
|
crossRealms?: boolean;
|
|
538
540
|
} & FanoutOptionsTuple): void;
|
|
539
|
-
declare const fanoutOptsArr: readonly ["merge", "depth", "atomic", "
|
|
541
|
+
declare const fanoutOptsArr: readonly ["merge", "depth", "atomic", "skipUndef"];
|
|
540
542
|
/**
|
|
541
543
|
* Executes a task while forcing all reactive writes to bypass equality checks.
|
|
542
544
|
* @param task The mutation logic to execute.
|
|
@@ -545,13 +547,13 @@ declare const fanoutOptsArr: readonly ["merge", "depth", "atomic", "skipUndefine
|
|
|
545
547
|
*/
|
|
546
548
|
declare function force<T>(task: () => T, bool?: boolean): T;
|
|
547
549
|
/**
|
|
548
|
-
* Deep-merges object-like values, does necessary checks so use without doubts. Only `o2` keys are checked when `
|
|
550
|
+
* Deep-merges object-like values, does necessary checks so use without doubts. Only `o2` keys are checked when `skipUndef` is true.
|
|
549
551
|
* @example
|
|
550
552
|
* const next = mergeObjs({ user: { name: "Kosi" } }, { user: { role: "admin" } }); // { ...o1, ...o2 } // o2 over o1 and deep!
|
|
551
553
|
*/
|
|
552
554
|
declare function mergeObjs<T1 extends object, T2 extends object>(o1?: T1 | null, o2?: T2 | null, config?: {
|
|
553
555
|
crossRealms?: boolean;
|
|
554
|
-
|
|
556
|
+
skipUndef?: boolean;
|
|
555
557
|
}, pojocheck?: boolean): DeepMerge<T1, T2>;
|
|
556
558
|
/** Returns [path, parent, value] records from root to the target path. */
|
|
557
559
|
declare function getTrailRecords<T extends object>(obj: T, path: WildPaths<T>, reverse?: boolean): [WildPaths<T>, PathBranchValue<T, WildPaths<T>>, PathValue<T, WildPaths<T>>][];
|
|
@@ -592,7 +594,7 @@ declare function isLeafPath<T extends object, const S extends string = ".", P ex
|
|
|
592
594
|
separator?: S;
|
|
593
595
|
} & typeof CTX.defaults, value?: PathValue<T, P, S>): boolean;
|
|
594
596
|
/**
|
|
595
|
-
* Creates a two-way, array-
|
|
597
|
+
* Creates a two-way, array-atomic, echo-proof sync bridge between two S.I.A Reactors. Uses a synchronous origin lock to prevent infinite echo loops.
|
|
596
598
|
* On setup, `rA` hydrates `rB` at `prefixB` with a deep clone of its current state at `prefixA` (primary drives initial truth).
|
|
597
599
|
* @param rA Primary reactor — source of truth. Its `prefixA` slice seeds `rB.prefixB` on setup.
|
|
598
600
|
* @param rB Secondary reactor — the wider store (e.g. `ctlr.config`). Holds the primary at a named path.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as Paths, a as PathValue, b as ReactorModuleId, c as ReactorModulePathConfig, B as BaseReactorModule, T as Transaction, d as Reactor, e as REvent, f as Payload } from './index-
|
|
1
|
+
import { P as Paths, a as PathValue, b as ReactorModuleId, c as ReactorModulePathConfig, B as BaseReactorModule, T as Transaction, d as Reactor, e as REvent, f as Payload } from './index-BtHNGnRR.js';
|
|
2
2
|
|
|
3
3
|
interface StorageAdapterConstructor<Config extends StorageAdapterConfig = StorageAdapterConfig> {
|
|
4
4
|
new (config?: Partial<Config>): StorageAdapter<any, Config>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as Paths, a as PathValue, b as ReactorModuleId, c as ReactorModulePathConfig, B as BaseReactorModule, T as Transaction, d as Reactor, e as REvent, f as Payload } from './index-
|
|
1
|
+
import { P as Paths, a as PathValue, b as ReactorModuleId, c as ReactorModulePathConfig, B as BaseReactorModule, T as Transaction, d as Reactor, e as REvent, f as Payload } from './index-BtHNGnRR.cjs';
|
|
2
2
|
|
|
3
3
|
interface StorageAdapterConstructor<Config extends StorageAdapterConfig = StorageAdapterConfig> {
|
|
4
4
|
new (config?: Partial<Config>): StorageAdapter<any, Config>;
|
package/dist/index.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { V as APIKey, X as AddDepth, Y as CTX, Z as ChildPaths, _ as DeepKeys, $ as DeepMerge, a0 as DeepPartial, K as DeepReadonly, a1 as DeepRequired, a2 as Deleter, a3 as DeleterRecord, a4 as DepthConfig, a5 as DirectPayload, a6 as EVT_OPTS, E as EffectOptions, a7 as Getter, a8 as GetterRecord, a9 as INDIFFABLE, aa as INERTIA, L as Inert, ab as Intent, ac as Listener, ad as ListenerOptions, ae as ListenerOptionsTuple, af as ListenerRecord, ag as Live, ah as MaxDepth, ai as NIL, aj as NOOP, ak as NextDepth, al as NoTraverse, am as PathBranch, an as PathBranchValue, ao as PathDepth, ap as PathKey, aq as PathLeaf, a as PathValue, P as Paths, f as Payload, ar as PrevDepth, as as Primitive, at as Pure, au as RAW, av as REJECTABLE, e as REvent, aw as RTR_BATCH, ax as RTR_LOG, R as Reactive, ay as ReactivePreferences, d as Reactor, J as ReactorBuild, az as ReactorEvent, aA as SSVERSION, aB as Setter, aC as SetterRecord, aD as Stable, aE as State, aF as StrictPathKey, aG as SubtractDepth, aH as SyncOptions, aI as SyncOptionsTuple, aJ as TERMINATOR, aK as Target, aL as Unflatten, aM as UnionToIntersection, aN as UpdatePayload, aO as VERSION, aP as Volatile, aQ as Watcher, aR as WatcherRecord, W as WildPaths, aS as getRaw, aT as getReactor, aU as getSnapshotVersion, aV as getVersion, aW as inert, aX as intent, aY as isInert, aZ as isIntent, a_ as isVolatile, a$ as live, b0 as methods, b1 as reactive, b2 as stable, b3 as state, b4 as volatile } from './index-
|
|
1
|
+
export { V as APIKey, X as AddDepth, Y as CTX, Z as ChildPaths, _ as DeepKeys, $ as DeepMerge, a0 as DeepPartial, K as DeepReadonly, a1 as DeepRequired, a2 as Deleter, a3 as DeleterRecord, a4 as DepthConfig, a5 as DirectPayload, a6 as EVT_OPTS, E as EffectOptions, a7 as Getter, a8 as GetterRecord, a9 as INDIFFABLE, aa as INERTIA, L as Inert, ab as Intent, ac as Listener, ad as ListenerOptions, ae as ListenerOptionsTuple, af as ListenerRecord, ag as Live, ah as MaxDepth, ai as NIL, aj as NOOP, ak as NextDepth, al as NoTraverse, am as PathBranch, an as PathBranchValue, ao as PathDepth, ap as PathKey, aq as PathLeaf, a as PathValue, P as Paths, f as Payload, ar as PrevDepth, as as Primitive, at as Pure, au as RAW, av as REJECTABLE, e as REvent, aw as RTR_BATCH, ax as RTR_LOG, R as Reactive, ay as ReactivePreferences, d as Reactor, J as ReactorBuild, az as ReactorEvent, aA as SSVERSION, aB as Setter, aC as SetterRecord, aD as Stable, aE as State, aF as StrictPathKey, aG as SubtractDepth, aH as SyncOptions, aI as SyncOptionsTuple, aJ as TERMINATOR, aK as Target, aL as Unflatten, aM as UnionToIntersection, aN as UpdatePayload, aO as VERSION, aP as Volatile, aQ as Watcher, aR as WatcherRecord, W as WildPaths, aS as getRaw, aT as getReactor, aU as getSnapshotVersion, aV as getVersion, aW as inert, aX as intent, aY as isInert, aZ as isIntent, a_ as isVolatile, a$ as live, b0 as methods, b1 as reactive, b2 as stable, b3 as state, b4 as volatile } from './index-BtHNGnRR.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { V as APIKey, X as AddDepth, Y as CTX, Z as ChildPaths, _ as DeepKeys, $ as DeepMerge, a0 as DeepPartial, K as DeepReadonly, a1 as DeepRequired, a2 as Deleter, a3 as DeleterRecord, a4 as DepthConfig, a5 as DirectPayload, a6 as EVT_OPTS, E as EffectOptions, a7 as Getter, a8 as GetterRecord, a9 as INDIFFABLE, aa as INERTIA, L as Inert, ab as Intent, ac as Listener, ad as ListenerOptions, ae as ListenerOptionsTuple, af as ListenerRecord, ag as Live, ah as MaxDepth, ai as NIL, aj as NOOP, ak as NextDepth, al as NoTraverse, am as PathBranch, an as PathBranchValue, ao as PathDepth, ap as PathKey, aq as PathLeaf, a as PathValue, P as Paths, f as Payload, ar as PrevDepth, as as Primitive, at as Pure, au as RAW, av as REJECTABLE, e as REvent, aw as RTR_BATCH, ax as RTR_LOG, R as Reactive, ay as ReactivePreferences, d as Reactor, J as ReactorBuild, az as ReactorEvent, aA as SSVERSION, aB as Setter, aC as SetterRecord, aD as Stable, aE as State, aF as StrictPathKey, aG as SubtractDepth, aH as SyncOptions, aI as SyncOptionsTuple, aJ as TERMINATOR, aK as Target, aL as Unflatten, aM as UnionToIntersection, aN as UpdatePayload, aO as VERSION, aP as Volatile, aQ as Watcher, aR as WatcherRecord, W as WildPaths, aS as getRaw, aT as getReactor, aU as getSnapshotVersion, aV as getVersion, aW as inert, aX as intent, aY as isInert, aZ as isIntent, a_ as isVolatile, a$ as live, b0 as methods, b1 as reactive, b2 as stable, b3 as state, b4 as volatile } from './index-
|
|
1
|
+
export { V as APIKey, X as AddDepth, Y as CTX, Z as ChildPaths, _ as DeepKeys, $ as DeepMerge, a0 as DeepPartial, K as DeepReadonly, a1 as DeepRequired, a2 as Deleter, a3 as DeleterRecord, a4 as DepthConfig, a5 as DirectPayload, a6 as EVT_OPTS, E as EffectOptions, a7 as Getter, a8 as GetterRecord, a9 as INDIFFABLE, aa as INERTIA, L as Inert, ab as Intent, ac as Listener, ad as ListenerOptions, ae as ListenerOptionsTuple, af as ListenerRecord, ag as Live, ah as MaxDepth, ai as NIL, aj as NOOP, ak as NextDepth, al as NoTraverse, am as PathBranch, an as PathBranchValue, ao as PathDepth, ap as PathKey, aq as PathLeaf, a as PathValue, P as Paths, f as Payload, ar as PrevDepth, as as Primitive, at as Pure, au as RAW, av as REJECTABLE, e as REvent, aw as RTR_BATCH, ax as RTR_LOG, R as Reactive, ay as ReactivePreferences, d as Reactor, J as ReactorBuild, az as ReactorEvent, aA as SSVERSION, aB as Setter, aC as SetterRecord, aD as Stable, aE as State, aF as StrictPathKey, aG as SubtractDepth, aH as SyncOptions, aI as SyncOptionsTuple, aJ as TERMINATOR, aK as Target, aL as Unflatten, aM as UnionToIntersection, aN as UpdatePayload, aO as VERSION, aP as Volatile, aQ as Watcher, aR as WatcherRecord, W as WildPaths, aS as getRaw, aT as getReactor, aU as getSnapshotVersion, aV as getVersion, aW as inert, aX as intent, aY as isInert, aZ as isIntent, a_ as isVolatile, a$ as live, b0 as methods, b1 as reactive, b2 as stable, b3 as state, b4 as volatile } from './index-BtHNGnRR.js';
|
package/dist/index.js
CHANGED
package/dist/modules.cjs
CHANGED
|
@@ -215,24 +215,25 @@ function parseEvtOpts(options, opts, boolOpt = opts[0], result = {}) {
|
|
|
215
215
|
function fanout(a, b, c, d) {
|
|
216
216
|
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, getPath(a, b), c, d || NIL, void 0] : [void 0, void 0, a, b, c || NIL, void 0], target = isEvPd ? getPath(a.root, a.currentTarget.path) : isPath ? getPath(state, path) : olds;
|
|
217
217
|
if (isEvPd && type !== "set" && type !== "delete" || !target || !canHandle(news, opts)) return;
|
|
218
|
+
const { merge = false, depth, atomic = true, skipUndef = false, cloneSets = false, txLabel } = opts;
|
|
218
219
|
const func = () => {
|
|
219
|
-
const walk = (target2, obj,
|
|
220
|
+
const walk = (target2, obj, depth2 = isEvPd ? 1 : Infinity, keys = Object.keys(obj)) => {
|
|
220
221
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
221
222
|
const key = keys[i], val = obj[key];
|
|
222
223
|
try {
|
|
223
|
-
if (
|
|
224
|
-
else
|
|
224
|
+
if (atomic && Array.isArray(val)) target2[key] = cloneSets ? deepClone(val) : val, target2[key].length = target2[key].length;
|
|
225
|
+
else depth2 > 1 && canHandle(val, opts) ? walk(target2[key] ||= {}, val, depth2 - 1) : (!skipUndef || val !== void 0) && (target2[key] = cloneSets ? deepClone(val) : val);
|
|
225
226
|
} catch (e) {
|
|
226
227
|
if (e instanceof RangeError) throw e;
|
|
227
228
|
}
|
|
228
229
|
}
|
|
229
230
|
};
|
|
230
|
-
if (
|
|
231
|
-
else walk(target,
|
|
231
|
+
if (atomic && Array.isArray(news) && isPath) setPath(state, path, cloneSets ? deepClone(news) : news), getPath(state, path).length = news.length;
|
|
232
|
+
else walk(target, merge ? mergeObjs(olds, news, opts) : news, depth === true ? Infinity : depth);
|
|
232
233
|
};
|
|
233
|
-
force(() => transaction(func,
|
|
234
|
+
force(() => transaction(func, txLabel ?? `${path ? `Fanout -> '${path}'` : `Fanout`} (Tx ${txId + 1})`), CTX.usingForce || isEvPd);
|
|
234
235
|
}
|
|
235
|
-
var fanoutOptsArr = ["merge", "depth", "atomic", "
|
|
236
|
+
var fanoutOptsArr = ["merge", "depth", "atomic", "skipUndef"];
|
|
236
237
|
function force(task, bool = true) {
|
|
237
238
|
const prev = CTX.usingForce;
|
|
238
239
|
CTX.usingForce = bool;
|
|
@@ -245,8 +246,8 @@ function force(task, bool = true) {
|
|
|
245
246
|
function mergeObjs(o1, o2, config = NIL, pojocheck = true) {
|
|
246
247
|
if (pojocheck && (!isPOJO(o1 || NIL, config) || !isPOJO(o2 || NIL, config))) return o2;
|
|
247
248
|
o1 ||= {}, o2 ||= {};
|
|
248
|
-
const merged = config.
|
|
249
|
-
if (config.
|
|
249
|
+
const merged = config.skipUndef ? { ...o1 } : { ...o1, ...o2 };
|
|
250
|
+
if (config.skipUndef) {
|
|
250
251
|
const keys2 = Object.keys(o1);
|
|
251
252
|
for (let i = 0, len = keys2.length; i < len; i++) {
|
|
252
253
|
const key = keys2[i], val = o2[key];
|
|
@@ -1650,9 +1651,9 @@ var PersistModule = class extends BaseReactorModule {
|
|
|
1650
1651
|
for (const [rid, rtr] of this.deps) this.attachPaths(rtr, rid);
|
|
1651
1652
|
value && this.adapter?.remove(this.config.key);
|
|
1652
1653
|
}
|
|
1653
|
-
hydrate(entry, rtr, rid = this.rids.get(rtr), { depth, merge = true, atomic,
|
|
1654
|
+
hydrate(entry, rtr, rid = this.rids.get(rtr), { depth, merge = true, atomic, skipUndef } = parseEvtOpts(this.config.fanout, fanoutOptsArr, "depth"), tick = true) {
|
|
1654
1655
|
if (!entry) return;
|
|
1655
|
-
const whites = this.getPaths(rid), blacks = this.getPaths(rid, this.config.blacklist, true), set = (p, curr, prev) => (depth ? fanout : setPath)(rtr.core, p, merge ? mergeObjs(curr, prev, rtr.config) : prev, depth ? { depth, atomic,
|
|
1656
|
+
const whites = this.getPaths(rid), blacks = this.getPaths(rid, this.config.blacklist, true), set = (p, curr, prev) => (depth ? fanout : setPath)(rtr.core, p, merge ? mergeObjs(curr, prev, rtr.config) : prev, depth ? { depth, atomic, skipUndef, crossRealms: rtr.config.crossRealms } : void 0);
|
|
1656
1657
|
let ticks = this.tickMap.get(rid);
|
|
1657
1658
|
for (let i = 0, len = blacks.length; i < len; i++) deletePath(entry, blacks[i]);
|
|
1658
1659
|
for (let i = 0, len = whites.length; i < len; i++) {
|