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.
@@ -1,5 +1,5 @@
1
- import { R as Reactive } from './index-BsH8KkqG.js';
2
- import { T as TimeTravelModule } from './index-D4DGBS2N.js';
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-BsH8KkqG.cjs';
2
- import { T as TimeTravelModule } from './index-DBx4TIVW.cjs';
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 {
@@ -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>Want 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: "tt-status-box" }), status = createEl("div", { className: "tt-status-row" }), filters = createEl("div", { className: "tt-status-row" }), filterBox = createEl("div", { className: "tt-status-box" }), whitelistLabel = createEl("span", { className: "muted", textContent: "Whitelist:" }), blacklistLabel = createEl("span", { className: "muted", textContent: "Blacklist:" }), whitelist = createEl("input", { className: "tt-filter-input 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: "tt-filter-input 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: "tt-speed", title: "Playback Speed", onchange: () => this.time.config.playbackRate = Number(speed.value) }), stride = createEl("input", { className: "tt-stride tt-button 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: "tt-stats" }), limit = createEl("input", { className: "tt-limit tt-mini-input 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: "tt-delay tt-mini-input 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: "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: "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: "tt-filter-row" }), filterRow2 = createEl("div", { className: "tt-filter-row" }), row1 = createEl("div", { className: "tt-row" }), row2 = createEl("div", { className: "tt-row" }), row3 = createEl("div", { className: "tt-row" }), row4 = createEl("div", { className: "tt-row" }), row5 = createEl("div", { className: "tt-row tt-config-row" });
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-BsH8KkqG.cjs';
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-DBx4TIVW.cjs';
4
- import { a as TimeTravelConsoleConfig } from '../TimeTravelConsole-nYAqg57U.cjs';
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.
@@ -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-BsH8KkqG.js';
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-D4DGBS2N.js';
4
- import { a as TimeTravelConsoleConfig } from '../TimeTravelConsole-DSifvt2z.js';
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.
@@ -2,8 +2,8 @@ import {
2
2
  Autotracker,
3
3
  TimeTravelConsole,
4
4
  withTracker
5
- } from "../chunk-GDTGCQ2Q.js";
6
- import "../chunk-FOD32N6J.js";
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-DCUPDG7B.js";
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>Want 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: "tt-status-box" }), status = createEl("div", { className: "tt-status-row" }), filters = createEl("div", { className: "tt-status-row" }), filterBox = createEl("div", { className: "tt-status-box" }), whitelistLabel = createEl("span", { className: "muted", textContent: "Whitelist:" }), blacklistLabel = createEl("span", { className: "muted", textContent: "Blacklist:" }), whitelist = createEl("input", { className: "tt-filter-input 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: "tt-filter-input 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: "tt-speed", title: "Playback Speed", onchange: () => this.time.config.playbackRate = Number(speed.value) }), stride = createEl("input", { className: "tt-stride tt-button 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: "tt-stats" }), limit = createEl("input", { className: "tt-limit tt-mini-input 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: "tt-delay tt-mini-input 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: "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: "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: "tt-filter-row" }), filterRow2 = createEl("div", { className: "tt-filter-row" }), row1 = createEl("div", { className: "tt-row" }), row2 = createEl("div", { className: "tt-row" }), row3 = createEl("div", { className: "tt-row" }), row4 = createEl("div", { className: "tt-row" }), row5 = createEl("div", { className: "tt-row tt-config-row" });
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-BsH8KkqG.cjs';
2
- export { A as Autotracker, w as withTracker } from '../index-BsH8KkqG.cjs';
3
- export { T as TimeTravelConsole, a as TimeTravelConsoleConfig } from '../TimeTravelConsole-nYAqg57U.cjs';
4
- import '../index-DBx4TIVW.cjs';
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-BsH8KkqG.js';
2
- export { A as Autotracker, w as withTracker } from '../index-BsH8KkqG.js';
3
- export { T as TimeTravelConsole, a as TimeTravelConsoleConfig } from '../TimeTravelConsole-DSifvt2z.js';
4
- import '../index-D4DGBS2N.js';
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.
@@ -3,10 +3,10 @@ import {
3
3
  TimeTravelConsole,
4
4
  effect,
5
5
  withTracker
6
- } from "../chunk-GDTGCQ2Q.js";
7
- import "../chunk-FOD32N6J.js";
6
+ } from "../chunk-ENEEV334.js";
7
+ import "../chunk-KPJ5SPXP.js";
8
8
  import "../chunk-ORK3EGB6.js";
9
- import "../chunk-DCUPDG7B.js";
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-FOD32N6J.js";
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-DCUPDG7B.js";
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>Want 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: "tt-status-box" }), status = createEl("div", { className: "tt-status-row" }), filters = createEl("div", { className: "tt-status-row" }), filterBox = createEl("div", { className: "tt-status-box" }), whitelistLabel = createEl("span", { className: "muted", textContent: "Whitelist:" }), blacklistLabel = createEl("span", { className: "muted", textContent: "Blacklist:" }), whitelist = createEl("input", { className: "tt-filter-input 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: "tt-filter-input 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: "tt-speed", title: "Playback Speed", onchange: () => this.time.config.playbackRate = Number(speed.value) }), stride = createEl("input", { className: "tt-stride tt-button 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: "tt-stats" }), limit = createEl("input", { className: "tt-limit tt-mini-input 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: "tt-delay tt-mini-input 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: "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: "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: "tt-filter-row" }), filterRow2 = createEl("div", { className: "tt-filter-row" }), row1 = createEl("div", { className: "tt-row" }), row2 = createEl("div", { className: "tt-row" }), row3 = createEl("div", { className: "tt-row" }), row4 = createEl("div", { className: "tt-row" }), row5 = createEl("div", { className: "tt-row tt-config-row" });
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) {
@@ -10,7 +10,7 @@ import {
10
10
  nuke,
11
11
  reactive,
12
12
  setPath
13
- } from "./chunk-DCUPDG7B.js";
13
+ } from "./chunk-LZJYX2LE.js";
14
14
 
15
15
  // src/ts/modules/base/index.ts
16
16
  var BaseReactorModule = class {
@@ -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, depth = isEvPd ? 1 : Infinity, keys = Object.keys(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 ((opts.atomic ?? true) && Array.isArray(val)) target2[key] = val, target2[key].length = target2[key].length;
185
- else depth > 1 && canHandle(val, opts) ? walk(target2[key] ||= {}, val, depth - 1) : (!opts.skipUndefined || val !== void 0) && (target2[key] = val);
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 ((opts.atomic ?? true) && Array.isArray(news) && isPath) setPath(state2, path, news), getPath(state2, path).length = news.length;
192
- else walk(target, opts.merge ? mergeObjs(olds, news, opts) : news, opts.depth === true ? Infinity : opts.depth);
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, opts.txLabel ?? `${path ? `Fanout -> '${path}'` : `Fanout`} (Tx ${txId + 1})`), CTX.usingForce || isEvPd);
195
+ force(() => transaction(func, txLabel ?? `${path ? `Fanout -> '${path}'` : `Fanout`} (Tx ${txId + 1})`), CTX.usingForce || isEvPd);
195
196
  }
196
- var fanoutOptsArr = ["merge", "depth", "atomic", "skipUndefined"];
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.skipUndefined ? { ...o1 } : { ...o1, ...o2 };
210
- if (config.skipUndefined) {
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 reactorA = getReactor(rA, true), reactorB = getReactor(rB, true);
304
+ const rtrA = getReactor(rA, true), rtrB = getReactor(rB, true);
304
305
  let origin = null;
305
- const sync = (srcOrigin, destCore, pSrc, pDest) => (val, payload) => {
306
- if (origin === (srcOrigin ^ 1)) return;
307
- const { path, object, key } = payload.target;
308
- if (pSrc && path !== pSrc && !path.startsWith(pSrc + ".")) return;
309
- origin = srcOrigin;
310
- const syncPath = Array.isArray(object) ? path.slice(0, -(key.length + 1)) : path, stripped = syncPath === pSrc ? "" : pSrc ? syncPath.slice(pSrc.length + 1) : syncPath;
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 initialA = prefixA ? getPath(reactorA.core, prefixA) : reactorA.core;
315
- if (initialA !== void 0) fanout(reactorB.core, prefixB || "*", deepClone(initialA), { depth: 1 });
316
- const clupA = reactorA.watch("*", sync(0, reactorB.core, prefixA, prefixB), { signal }), clupB = reactorB.watch("*", sync(1, reactorA.core, prefixB, prefixA), { signal });
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 turn set this to `false`. */
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
- skipUndefined?: boolean;
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", "skipUndefined"];
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 `skipUndefined` is true.
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
- skipUndefined?: boolean;
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-safe, echo-proof sync bridge between two S.I.A Reactors. Uses a synchronous origin lock to prevent infinite echo loops.
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 turn set this to `false`. */
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
- skipUndefined?: boolean;
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", "skipUndefined"];
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 `skipUndefined` is true.
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
- skipUndefined?: boolean;
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-safe, echo-proof sync bridge between two S.I.A Reactors. Uses a synchronous origin lock to prevent infinite echo loops.
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-BsH8KkqG.js';
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-BsH8KkqG.cjs';
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-BsH8KkqG.cjs';
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-BsH8KkqG.js';
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
@@ -30,7 +30,7 @@ import {
30
30
  stable,
31
31
  state,
32
32
  volatile
33
- } from "./chunk-DCUPDG7B.js";
33
+ } from "./chunk-LZJYX2LE.js";
34
34
  export {
35
35
  CTX,
36
36
  EVT_OPTS,
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, depth = isEvPd ? 1 : Infinity, keys = Object.keys(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 ((opts.atomic ?? true) && Array.isArray(val)) target2[key] = val, target2[key].length = target2[key].length;
224
- else depth > 1 && canHandle(val, opts) ? walk(target2[key] ||= {}, val, depth - 1) : (!opts.skipUndefined || val !== void 0) && (target2[key] = val);
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 ((opts.atomic ?? true) && Array.isArray(news) && isPath) setPath(state, path, news), getPath(state, path).length = news.length;
231
- else walk(target, opts.merge ? mergeObjs(olds, news, opts) : news, opts.depth === true ? Infinity : opts.depth);
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, opts.txLabel ?? `${path ? `Fanout -> '${path}'` : `Fanout`} (Tx ${txId + 1})`), CTX.usingForce || isEvPd);
234
+ force(() => transaction(func, txLabel ?? `${path ? `Fanout -> '${path}'` : `Fanout`} (Tx ${txId + 1})`), CTX.usingForce || isEvPd);
234
235
  }
235
- var fanoutOptsArr = ["merge", "depth", "atomic", "skipUndefined"];
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.skipUndefined ? { ...o1 } : { ...o1, ...o2 };
249
- if (config.skipUndefined) {
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, skipUndefined } = parseEvtOpts(this.config.fanout, fanoutOptsArr, "depth"), tick = true) {
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, skipUndefined, crossRealms: rtr.config.crossRealms } : void 0);
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++) {