sia-reactor 0.0.44 → 0.0.45

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.
Files changed (36) hide show
  1. package/dist/{TimeTravelConsole-BwHB0LsE.d.ts → TimeTravelConsole-BQv0oWkM.d.ts} +2 -2
  2. package/dist/{TimeTravelConsole-Ck3GwvXR.d.cts → TimeTravelConsole-svHnyVJ5.d.cts} +2 -2
  3. package/dist/adapters/react.cjs +34 -34
  4. package/dist/adapters/react.d.cts +3 -3
  5. package/dist/adapters/react.d.ts +3 -3
  6. package/dist/adapters/react.js +3 -3
  7. package/dist/adapters/vanilla.cjs +34 -34
  8. package/dist/adapters/vanilla.d.cts +18 -4
  9. package/dist/adapters/vanilla.d.ts +18 -4
  10. package/dist/adapters/vanilla.js +3 -3
  11. package/dist/{chunk-4U7VB3JS.js → chunk-KSP2RS2U.js} +8 -8
  12. package/dist/{chunk-BOBAOEKS.js → chunk-TWHE4ZHF.js} +1 -1
  13. package/dist/{chunk-4SGW3Y6X.js → chunk-YITKWJ2E.js} +34 -32
  14. package/dist/{obj-CM05g1eW.d.cts → consts-CS2UoTQk.d.cts} +249 -249
  15. package/dist/{obj-CM05g1eW.d.ts → consts-CS2UoTQk.d.ts} +249 -249
  16. package/dist/{index-K1TE7RnF.d.ts → index-C2r5vx2_.d.cts} +3 -1
  17. package/dist/{index-FMuvzRw_.d.cts → index-D6S7TeWV.d.ts} +3 -1
  18. package/dist/index.d.cts +3 -107
  19. package/dist/index.d.ts +3 -107
  20. package/dist/modules.cjs +8 -8
  21. package/dist/modules.d.cts +379 -3
  22. package/dist/modules.d.ts +379 -3
  23. package/dist/modules.js +10 -10
  24. package/dist/super.d.ts +2357 -0
  25. package/dist/super.global.js +47 -45
  26. package/dist/utils.cjs +38 -34
  27. package/dist/utils.d.cts +211 -2
  28. package/dist/utils.d.ts +211 -2
  29. package/dist/utils.js +9 -5
  30. package/package.json +1 -1
  31. package/dist/modules-D7XeXgBN.d.ts +0 -431
  32. package/dist/modules-DdCv43H3.d.cts +0 -431
  33. package/dist/utils-09Fwruxy.d.cts +0 -260
  34. package/dist/utils-EAjy2rsz.d.ts +0 -260
  35. package/dist/vanilla-Bs-5iI0s.d.cts +0 -25
  36. package/dist/vanilla-KGPkYjU_.d.ts +0 -25
@@ -1,5 +1,5 @@
1
- import { V as Reactive } from './obj-CM05g1eW.js';
2
- import { g as TimeTravelModule } from './index-K1TE7RnF.js';
1
+ import { V as Reactive } from './consts-CS2UoTQk.js';
2
+ import { g as TimeTravelModule } from './index-D6S7TeWV.js';
3
3
 
4
4
  /** Reactive options for the TimeTravel overlay instance. */
5
5
  interface TimeTravelConsoleConfig {
@@ -1,5 +1,5 @@
1
- import { V as Reactive } from './obj-CM05g1eW.cjs';
2
- import { g as TimeTravelModule } from './index-FMuvzRw_.cjs';
1
+ import { V as Reactive } from './consts-CS2UoTQk.cjs';
2
+ import { g as TimeTravelModule } from './index-C2r5vx2_.cjs';
3
3
 
4
4
  /** Reactive options for the TimeTravel overlay instance. */
5
5
  interface TimeTravelConsoleConfig {
@@ -1166,47 +1166,44 @@ function getActiveEl(root, noBody = true) {
1166
1166
 
1167
1167
  // src/ts/utils/keys.ts
1168
1168
  var KEYS_BLOCKS = ["Ctrl+Tab", "Ctrl+Shift+Tab", "Ctrl+PageUp", "Ctrl+PageDown", "Cmd+Option+ArrowRight", "Cmd+Option+ArrowLeft", "Ctrl+1", "Ctrl+2", "Ctrl+3", "Ctrl+4", "Ctrl+5", "Ctrl+6", "Ctrl+7", "Ctrl+8", "Ctrl+9", "Cmd+1", "Cmd+2", "Cmd+3", "Cmd+4", "Cmd+5", "Cmd+6", "Cmd+7", "Cmd+8", "Cmd+9", "Alt+ArrowLeft", "Alt+ArrowRight", "Cmd+ArrowLeft", "Cmd+ArrowRight", "Ctrl+r", "Ctrl+Shift+r", "F5", "Shift+F5", "Cmd+r", "Cmd+Shift+r", "Ctrl+h", "Ctrl+j", "Ctrl+d", "Ctrl+f", "Cmd+y", "Cmd+Option+b", "Cmd+d", "Cmd+f", "Ctrl+Shift+i", "Ctrl+Shift+j", "Ctrl+Shift+c", "Ctrl+u", "F12", "Cmd+Option+i", "Cmd+Option+j", "Cmd+Option+c", "Cmd+Option+u", "Ctrl+=", "Ctrl+-", "Ctrl+0", "Cmd+=", "Cmd+-", "Cmd+0", "Ctrl+p", "Ctrl+s", "Ctrl+o", "Cmd+p", "Cmd+s", "Cmd+o"];
1169
+ var KEYS_MODS = ["ctrl", "shift", "alt", "meta"];
1170
+ var KEYS_ALIAS = { cmd: "meta", space: " " };
1169
1171
  function stringifyKeyEvent(e) {
1170
1172
  const parts = [];
1171
- if (e.ctrlKey) parts.push("ctrl");
1172
- if (e.altKey) parts.push("alt");
1173
- if (e.shiftKey) parts.push("shift");
1174
- if (e.metaKey) parts.push("meta");
1175
- parts.push(e.key?.toLowerCase() ?? "");
1173
+ e.ctrlKey && parts.push("ctrl"), e.altKey && parts.push("alt"), e.shiftKey && parts.push("shift"), e.metaKey && parts.push("meta"), parts.push(e.key?.toLowerCase() ?? "");
1176
1174
  return parts.join("+");
1177
1175
  }
1178
- function cleanKeyCombo(combo) {
1176
+ function cleanKeyCombo(combo, mods = KEYS_MODS) {
1179
1177
  const clean = (combo2) => {
1180
- const m = ["ctrl", "alt", "shift", "meta"], alias = { cmd: "meta", space: " " };
1181
1178
  if (combo2 === " " || combo2 === "+") return combo2;
1182
1179
  combo2 = combo2.replace(/\+\s*\+$/, "+plus");
1183
- const p = combo2.toLowerCase().split("+").filter((k) => k !== "").map((k) => alias[k] || (k === "plus" ? "+" : k.trim() || " "));
1184
- return [...p.filter((k) => m.includes(k)).sort((a, b) => m.indexOf(a) - m.indexOf(b)), ...p.filter((k) => !m.includes(k)) || ""].join("+");
1180
+ const p = combo2.toLowerCase().split("+").filter((k) => k !== "").map((k, _, __, tk = k.trim()) => KEYS_ALIAS[tk] || (tk === "plus" ? "+" : tk || " "));
1181
+ return [...p.filter((k) => mods.includes(k)).sort((a, b) => mods.indexOf(a) - mods.indexOf(b)), ...p.filter((k) => !mods.includes(k)) || ""].join("+");
1185
1182
  };
1186
1183
  return Array.isArray(combo) ? combo.map(clean) : clean(combo);
1187
1184
  }
1188
- function matchKeys(required, actual, strict = false, cleaned = false) {
1189
- if (!cleaned) actual = cleanKeyCombo(actual);
1190
- const match = (required2, actual2) => {
1191
- if (!cleaned) required2 = cleanKeyCombo(required2);
1192
- if (strict) return required2 === actual2;
1193
- const actualKeys = actual2.split("+");
1194
- return required2.split("+").every((k) => actualKeys.includes(k));
1185
+ function matchKeys(required, actual, strict = false, clean = true) {
1186
+ if (clean) actual = cleanKeyCombo(actual);
1187
+ const match = (req, actual2) => {
1188
+ req = cleanKeyCombo(req);
1189
+ if (strict) return req === actual2;
1190
+ const actuals = actual2.split("+");
1191
+ return req.split("+").every((k) => actuals.includes(k));
1195
1192
  };
1196
- return Array.isArray(required) ? required.some((required2) => match(required2, actual)) : match(required, actual);
1193
+ return Array.isArray(required) ? required.some((req) => match(req, actual)) : match(required, actual);
1197
1194
  }
1198
1195
  function getTermsForKey(combo, settings) {
1199
- const terms = { override: false, block: false, whitelisted: false, action: null }, { overrides = [], shortcuts = {}, blocks = [], strictMatch: s = false, rankedMatch = true, whitelist = [] } = settings || {};
1196
+ const terms = { override: false, block: false, whitelisted: false, action: null }, { overrides = [], shortcuts = {}, blocks = [], strictMatch: stm = false, rankedMatch: ram = true, whitelist = [] } = settings || {};
1200
1197
  combo = cleanKeyCombo(combo);
1201
- if (matchKeys(overrides, combo, s)) terms.override = true;
1202
- if (matchKeys(blocks, combo, s)) terms.block = true;
1203
- if (matchKeys(whitelist, combo)) terms.whitelisted = true;
1204
- if (!rankedMatch) return terms.action = Object.keys(shortcuts).find((key) => matchKeys(shortcuts[key], combo, s)) || null, terms;
1198
+ if (matchKeys(overrides, combo, stm, false)) terms.override = true;
1199
+ if (matchKeys(blocks, combo, stm, false)) terms.block = true;
1200
+ if (matchKeys(whitelist, combo, false)) terms.whitelisted = true;
1201
+ if (!ram) return terms.action = Object.keys(shortcuts).find((id) => shortcuts[id] && matchKeys(shortcuts[id], combo, stm, false)) || null, terms;
1205
1202
  let bestA = null, bestE = false, bestL = 0;
1206
- for (const action of Object.keys(shortcuts))
1207
- for (const c of Array.isArray(shortcuts[action]) ? shortcuts[action] : [shortcuts[action]]) {
1208
- const required = cleanKeyCombo(c), isE = required === combo, len = required.split("+").length;
1209
- if (matchKeys(required, combo, s, true) && (!bestA || isE && !bestE || isE === bestE && len > bestL)) bestA = action, bestE = isE, bestL = len;
1203
+ for (const id of Object.keys(shortcuts))
1204
+ for (const c of Array.isArray(shortcuts[id]) ? shortcuts[id] : [shortcuts[id]]) {
1205
+ const req = c && cleanKeyCombo(c), isE = req === combo, len = req ? req.split("+").length : 0;
1206
+ if (c && matchKeys(req, combo, stm, false) && (!bestA || isE && !bestE || isE === bestE && len > bestL)) bestA = id, bestE = isE, bestL = len;
1210
1207
  }
1211
1208
  return terms.action = bestA, terms;
1212
1209
  }
@@ -1222,10 +1219,13 @@ function keyEventAllowed(e, settings) {
1222
1219
  if (whitelisted) return e.key.toLowerCase();
1223
1220
  return false;
1224
1221
  }
1225
- var formatKeyForDisplay = (combo = "") => ` ${(Array.isArray(combo) ? combo : [combo]).map((c) => `(${cleanKeyCombo(c).replace(" ", "space")})`).join(" or ")}`;
1226
- function parseForARIAKS(s = "", formatted = true) {
1222
+ var formatKeyTooltip = (combo = "", keyFn = (c = "") => cleanKeyCombo(c).replace(" ", "space")) => {
1223
+ const combined = combo?.length ? Array.isArray(combo) ? combo.map(keyFn).join(" or ") : keyFn(combo) : "";
1224
+ return combined ? ` ( ${combined} )` : "";
1225
+ };
1226
+ function parseForARIAKS(s = "", format = true) {
1227
1227
  const m = { ctrl: "Control", cmd: "Meta", space: "Space", plus: "+" };
1228
- return (formatted && !Array.isArray(s) ? s : formatKeyForDisplay(s)).toLowerCase().replace(/[()]/g, "").replace(/\bor\b/g, " ").replace(/\w+/g, (k) => m[k] || k).replace(/\s+/g, " ").trim();
1228
+ return (!format && !Array.isArray(s) ? s : formatKeyTooltip(s)).toLowerCase().replace(/[()]/g, "").replace(/\bor\b/g, " ").replace(/\w+/g, (k) => m[k] || k).replace(/\s+/g, " ").trim();
1229
1229
  }
1230
1230
 
1231
1231
  // src/ts/adapters/vanilla/effect.ts
@@ -1245,7 +1245,7 @@ function effect(callback, options = NIL) {
1245
1245
  var keys = {
1246
1246
  blocks: KEYS_BLOCKS,
1247
1247
  overrides: ["Ctrl+z", "Cmd+z", "Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z", "Home", "End", "ArrowLeft", "ArrowRight", "Space", "Alt+Space", "Escape", "Delete"],
1248
- shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: "Home", trackUntrack: "t", ending: "End", prevFrame: ",", nextFrame: ".", skipBwd: "ArrowLeft", skipFwd: "ArrowRight", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
1248
+ shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: "Home", trackUntrack: "t", ending: "End", prevFrame: ",", nextFrame: ".", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
1249
1249
  };
1250
1250
  var TimeTravelConsole = class _TimeTravelConsole {
1251
1251
  static count = 0;
@@ -1266,13 +1266,13 @@ var TimeTravelConsole = class _TimeTravelConsole {
1266
1266
  this.config = reactive({ title: `Time Travel Console ${this.index = ++_TimeTravelConsole.count}`, ...build });
1267
1267
  this.state.open = !!this.config.startOpen;
1268
1268
  let wlLive = false, blLive = false;
1269
- 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" });
1269
+ 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${formatKeyTooltip(keys.shortcuts.clrHistory)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clrHistory), onclick: () => (this.time.clear(), this.state.import = "") }), undo = createEl("button", { textContent: `Undo${formatKeyTooltip(keys.shortcuts.undo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.undo), onclick: () => this.time.undo(this.state.stride) }), redo = createEl("button", { textContent: `Redo${formatKeyTooltip(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo), onclick: () => this.time.redo(this.state.stride) }), genesis = createEl("button", { textContent: `Genesis${formatKeyTooltip(keys.shortcuts.genesis)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.genesis), onclick: () => this.time.jumpTo(0) }), playPause = createEl("button", { onclick: () => this.time[s.paused ? "play" : "pause"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.playPause) }), rewind = createEl("button", { textContent: `Rewind${formatKeyTooltip(keys.shortcuts.rewind)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.rewind), onclick: this.time.rewind }), trackUntrack = createEl("button", { onclick: () => this.time[s.tracking ? "untrack" : "track"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.trackUntrack) }), 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${formatKeyTooltip(keys.shortcuts.export)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.export), onclick: () => this.state.import = this.time.export(null, 2) }), imp = createEl("button", { textContent: `Import${formatKeyTooltip(keys.shortcuts.import)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.import), onclick: () => this.state.import.trim().length && this.time.import(this.state.import) }), clr = createEl("button", { textContent: `Clear${formatKeyTooltip(keys.shortcuts.clear)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clear), 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" });
1270
1270
  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` })));
1271
1271
  status.append((box.append(frame), box), clrHistory);
1272
1272
  filters.append((filterBox.append((filterRow1.append(whitelistLabel, whitelist), filterRow1), (filterRow2.append(blacklistLabel, blacklist), filterRow2)), filterBox));
1273
1273
  panel.append(title, status, (row1.append(playPause, rewind, genesis), row1), (row2.append(undo, redo, trackUntrack, stride), row2), payload, (row3.append(speed, range), row3), filters, (row4.append(exp, imp, clr), row4), io, (row5.append(delay, limit, (read.append(readBox, " Read Mirror"), read), (write.append(writeBox, " Write Mirror"), write)), row5), (foot.prepend(stats), foot.append(link), foot));
1274
1274
  this.host.append(toggle, panel);
1275
- this.keydown = (e, can = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true), a = can && keyEventAllowed(e, keys)) => (a && e.stopImmediatePropagation(), a === "undo" ? this.time.undo(this.state.stride) : a === "redo" ? this.time.redo(this.state.stride) : a === "genesis" ? this.time.jumpTo(0) : a === "trackUntrack" ? this.time[s.tracking ? "untrack" : "track"]() : a === "ending" ? this.time.jumpTo(s.history.length) : a === "prevFrame" ? this.time.step(this.state.stride, false) : a === "nextFrame" ? this.time.step(this.state.stride, true) : a === "skipBwd" ? this.time.step(5 * this.state.stride, false) : a === "skipFwd" ? this.time.step(5 * this.state.stride, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = ""));
1275
+ this.keydown = (e, can = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true), a = can && keyEventAllowed(e, keys)) => (a && e.stopImmediatePropagation(), a === "undo" ? this.time.undo(this.state.stride) : a === "redo" ? this.time.redo(this.state.stride) : a === "genesis" ? this.time.jumpTo(0) : a === "trackUntrack" ? this.time[s.tracking ? "untrack" : "track"]() : a === "ending" ? this.time.jumpTo(s.history.length) : a === "prevFrame" ? this.time.step(this.state.stride, false) : a === "nextFrame" ? this.time.step(this.state.stride, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = ""));
1276
1276
  this.keyup = (e, can = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true), a = can && keyEventAllowed(e, keys)) => a && e.stopImmediatePropagation();
1277
1277
  window.addEventListener("keydown", this.keydown), window.addEventListener("keyup", this.keyup);
1278
1278
  const sync = [
@@ -1283,8 +1283,8 @@ var TimeTravelConsole = class _TimeTravelConsole {
1283
1283
  if (host.parentNode !== dock) dock.appendChild(host);
1284
1284
  }),
1285
1285
  effect(() => toggle.textContent = `${(panel.hidden = !this.state.open) ? "Show" : "Hide"} ${title.textContent = this.config.title ?? ""}`),
1286
- effect(() => playPause.textContent = `${s.paused ? "Play" : "Pause"}${formatKeyForDisplay(keys.shortcuts.playPause)}`),
1287
- effect(() => trackUntrack.textContent = `${s.tracking ? "Untrack" : "Track"}${formatKeyForDisplay(keys.shortcuts.trackUntrack)}`),
1286
+ effect(() => playPause.textContent = `${s.paused ? "Play" : "Pause"}${formatKeyTooltip(keys.shortcuts.playPause)}`),
1287
+ effect(() => trackUntrack.textContent = `${s.tracking ? "Untrack" : "Track"}${formatKeyTooltip(keys.shortcuts.trackUntrack)}`),
1288
1288
  effect((sets = 0, txs = 0) => {
1289
1289
  range.max = String(s.history.length);
1290
1290
  range.disabled = clrHistory.disabled = !s.history.length;
@@ -1,7 +1,7 @@
1
- import { k as EffectOptions, X as Reactor, V as Reactive, Y as ReactorBuild, e as DeepReadonly, ag as WildPaths, B as PathValue } from '../obj-CM05g1eW.cjs';
1
+ import { k as EffectOptions, X as Reactor, V as Reactive, Y as ReactorBuild, e as DeepReadonly, ag as WildPaths, B as PathValue } from '../consts-CS2UoTQk.cjs';
2
2
  import { useLayoutEffect } from 'react';
3
- import { g as TimeTravelModule } from '../index-FMuvzRw_.cjs';
4
- import { T as TimeTravelConsoleConfig } from '../TimeTravelConsole-Ck3GwvXR.cjs';
3
+ import { g as TimeTravelModule } from '../index-C2r5vx2_.cjs';
4
+ import { T as TimeTravelConsoleConfig } from '../TimeTravelConsole-svHnyVJ5.cjs';
5
5
 
6
6
  /**
7
7
  * Subscribes a component to desired Reactor state and returns it.
@@ -1,7 +1,7 @@
1
- import { k as EffectOptions, X as Reactor, V as Reactive, Y as ReactorBuild, e as DeepReadonly, ag as WildPaths, B as PathValue } from '../obj-CM05g1eW.js';
1
+ import { k as EffectOptions, X as Reactor, V as Reactive, Y as ReactorBuild, e as DeepReadonly, ag as WildPaths, B as PathValue } from '../consts-CS2UoTQk.js';
2
2
  import { useLayoutEffect } from 'react';
3
- import { g as TimeTravelModule } from '../index-K1TE7RnF.js';
4
- import { T as TimeTravelConsoleConfig } from '../TimeTravelConsole-BwHB0LsE.js';
3
+ import { g as TimeTravelModule } from '../index-D6S7TeWV.js';
4
+ import { T as TimeTravelConsoleConfig } from '../TimeTravelConsole-BQv0oWkM.js';
5
5
 
6
6
  /**
7
7
  * Subscribes a component to desired Reactor state and returns it.
@@ -2,9 +2,9 @@ import {
2
2
  Autotracker,
3
3
  TimeTravelConsole,
4
4
  withTracker
5
- } from "../chunk-4U7VB3JS.js";
6
- import "../chunk-BOBAOEKS.js";
7
- import "../chunk-4SGW3Y6X.js";
5
+ } from "../chunk-KSP2RS2U.js";
6
+ import "../chunk-TWHE4ZHF.js";
7
+ import "../chunk-YITKWJ2E.js";
8
8
  import {
9
9
  CTX,
10
10
  NIL,
@@ -1086,47 +1086,44 @@ function getActiveEl(root, noBody = true) {
1086
1086
 
1087
1087
  // src/ts/utils/keys.ts
1088
1088
  var KEYS_BLOCKS = ["Ctrl+Tab", "Ctrl+Shift+Tab", "Ctrl+PageUp", "Ctrl+PageDown", "Cmd+Option+ArrowRight", "Cmd+Option+ArrowLeft", "Ctrl+1", "Ctrl+2", "Ctrl+3", "Ctrl+4", "Ctrl+5", "Ctrl+6", "Ctrl+7", "Ctrl+8", "Ctrl+9", "Cmd+1", "Cmd+2", "Cmd+3", "Cmd+4", "Cmd+5", "Cmd+6", "Cmd+7", "Cmd+8", "Cmd+9", "Alt+ArrowLeft", "Alt+ArrowRight", "Cmd+ArrowLeft", "Cmd+ArrowRight", "Ctrl+r", "Ctrl+Shift+r", "F5", "Shift+F5", "Cmd+r", "Cmd+Shift+r", "Ctrl+h", "Ctrl+j", "Ctrl+d", "Ctrl+f", "Cmd+y", "Cmd+Option+b", "Cmd+d", "Cmd+f", "Ctrl+Shift+i", "Ctrl+Shift+j", "Ctrl+Shift+c", "Ctrl+u", "F12", "Cmd+Option+i", "Cmd+Option+j", "Cmd+Option+c", "Cmd+Option+u", "Ctrl+=", "Ctrl+-", "Ctrl+0", "Cmd+=", "Cmd+-", "Cmd+0", "Ctrl+p", "Ctrl+s", "Ctrl+o", "Cmd+p", "Cmd+s", "Cmd+o"];
1089
+ var KEYS_MODS = ["ctrl", "shift", "alt", "meta"];
1090
+ var KEYS_ALIAS = { cmd: "meta", space: " " };
1089
1091
  function stringifyKeyEvent(e) {
1090
1092
  const parts = [];
1091
- if (e.ctrlKey) parts.push("ctrl");
1092
- if (e.altKey) parts.push("alt");
1093
- if (e.shiftKey) parts.push("shift");
1094
- if (e.metaKey) parts.push("meta");
1095
- parts.push(e.key?.toLowerCase() ?? "");
1093
+ e.ctrlKey && parts.push("ctrl"), e.altKey && parts.push("alt"), e.shiftKey && parts.push("shift"), e.metaKey && parts.push("meta"), parts.push(e.key?.toLowerCase() ?? "");
1096
1094
  return parts.join("+");
1097
1095
  }
1098
- function cleanKeyCombo(combo) {
1096
+ function cleanKeyCombo(combo, mods = KEYS_MODS) {
1099
1097
  const clean = (combo2) => {
1100
- const m = ["ctrl", "alt", "shift", "meta"], alias = { cmd: "meta", space: " " };
1101
1098
  if (combo2 === " " || combo2 === "+") return combo2;
1102
1099
  combo2 = combo2.replace(/\+\s*\+$/, "+plus");
1103
- const p = combo2.toLowerCase().split("+").filter((k) => k !== "").map((k) => alias[k] || (k === "plus" ? "+" : k.trim() || " "));
1104
- return [...p.filter((k) => m.includes(k)).sort((a, b) => m.indexOf(a) - m.indexOf(b)), ...p.filter((k) => !m.includes(k)) || ""].join("+");
1100
+ const p = combo2.toLowerCase().split("+").filter((k) => k !== "").map((k, _, __, tk = k.trim()) => KEYS_ALIAS[tk] || (tk === "plus" ? "+" : tk || " "));
1101
+ return [...p.filter((k) => mods.includes(k)).sort((a, b) => mods.indexOf(a) - mods.indexOf(b)), ...p.filter((k) => !mods.includes(k)) || ""].join("+");
1105
1102
  };
1106
1103
  return Array.isArray(combo) ? combo.map(clean) : clean(combo);
1107
1104
  }
1108
- function matchKeys(required, actual, strict = false, cleaned = false) {
1109
- if (!cleaned) actual = cleanKeyCombo(actual);
1110
- const match = (required2, actual2) => {
1111
- if (!cleaned) required2 = cleanKeyCombo(required2);
1112
- if (strict) return required2 === actual2;
1113
- const actualKeys = actual2.split("+");
1114
- return required2.split("+").every((k) => actualKeys.includes(k));
1105
+ function matchKeys(required, actual, strict = false, clean = true) {
1106
+ if (clean) actual = cleanKeyCombo(actual);
1107
+ const match = (req, actual2) => {
1108
+ req = cleanKeyCombo(req);
1109
+ if (strict) return req === actual2;
1110
+ const actuals = actual2.split("+");
1111
+ return req.split("+").every((k) => actuals.includes(k));
1115
1112
  };
1116
- return Array.isArray(required) ? required.some((required2) => match(required2, actual)) : match(required, actual);
1113
+ return Array.isArray(required) ? required.some((req) => match(req, actual)) : match(required, actual);
1117
1114
  }
1118
1115
  function getTermsForKey(combo, settings) {
1119
- const terms = { override: false, block: false, whitelisted: false, action: null }, { overrides = [], shortcuts = {}, blocks = [], strictMatch: s = false, rankedMatch = true, whitelist = [] } = settings || {};
1116
+ const terms = { override: false, block: false, whitelisted: false, action: null }, { overrides = [], shortcuts = {}, blocks = [], strictMatch: stm = false, rankedMatch: ram = true, whitelist = [] } = settings || {};
1120
1117
  combo = cleanKeyCombo(combo);
1121
- if (matchKeys(overrides, combo, s)) terms.override = true;
1122
- if (matchKeys(blocks, combo, s)) terms.block = true;
1123
- if (matchKeys(whitelist, combo)) terms.whitelisted = true;
1124
- if (!rankedMatch) return terms.action = Object.keys(shortcuts).find((key) => matchKeys(shortcuts[key], combo, s)) || null, terms;
1118
+ if (matchKeys(overrides, combo, stm, false)) terms.override = true;
1119
+ if (matchKeys(blocks, combo, stm, false)) terms.block = true;
1120
+ if (matchKeys(whitelist, combo, false)) terms.whitelisted = true;
1121
+ if (!ram) return terms.action = Object.keys(shortcuts).find((id) => shortcuts[id] && matchKeys(shortcuts[id], combo, stm, false)) || null, terms;
1125
1122
  let bestA = null, bestE = false, bestL = 0;
1126
- for (const action of Object.keys(shortcuts))
1127
- for (const c of Array.isArray(shortcuts[action]) ? shortcuts[action] : [shortcuts[action]]) {
1128
- const required = cleanKeyCombo(c), isE = required === combo, len = required.split("+").length;
1129
- if (matchKeys(required, combo, s, true) && (!bestA || isE && !bestE || isE === bestE && len > bestL)) bestA = action, bestE = isE, bestL = len;
1123
+ for (const id of Object.keys(shortcuts))
1124
+ for (const c of Array.isArray(shortcuts[id]) ? shortcuts[id] : [shortcuts[id]]) {
1125
+ const req = c && cleanKeyCombo(c), isE = req === combo, len = req ? req.split("+").length : 0;
1126
+ if (c && matchKeys(req, combo, stm, false) && (!bestA || isE && !bestE || isE === bestE && len > bestL)) bestA = id, bestE = isE, bestL = len;
1130
1127
  }
1131
1128
  return terms.action = bestA, terms;
1132
1129
  }
@@ -1142,17 +1139,20 @@ function keyEventAllowed(e, settings) {
1142
1139
  if (whitelisted) return e.key.toLowerCase();
1143
1140
  return false;
1144
1141
  }
1145
- var formatKeyForDisplay = (combo = "") => ` ${(Array.isArray(combo) ? combo : [combo]).map((c) => `(${cleanKeyCombo(c).replace(" ", "space")})`).join(" or ")}`;
1146
- function parseForARIAKS(s = "", formatted = true) {
1142
+ var formatKeyTooltip = (combo = "", keyFn = (c = "") => cleanKeyCombo(c).replace(" ", "space")) => {
1143
+ const combined = combo?.length ? Array.isArray(combo) ? combo.map(keyFn).join(" or ") : keyFn(combo) : "";
1144
+ return combined ? ` ( ${combined} )` : "";
1145
+ };
1146
+ function parseForARIAKS(s = "", format = true) {
1147
1147
  const m = { ctrl: "Control", cmd: "Meta", space: "Space", plus: "+" };
1148
- return (formatted && !Array.isArray(s) ? s : formatKeyForDisplay(s)).toLowerCase().replace(/[()]/g, "").replace(/\bor\b/g, " ").replace(/\w+/g, (k) => m[k] || k).replace(/\s+/g, " ").trim();
1148
+ return (!format && !Array.isArray(s) ? s : formatKeyTooltip(s)).toLowerCase().replace(/[()]/g, "").replace(/\bor\b/g, " ").replace(/\w+/g, (k) => m[k] || k).replace(/\s+/g, " ").trim();
1149
1149
  }
1150
1150
 
1151
1151
  // src/ts/adapters/vanilla/TimeTravelConsole.ts
1152
1152
  var keys = {
1153
1153
  blocks: KEYS_BLOCKS,
1154
1154
  overrides: ["Ctrl+z", "Cmd+z", "Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z", "Home", "End", "ArrowLeft", "ArrowRight", "Space", "Alt+Space", "Escape", "Delete"],
1155
- shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: "Home", trackUntrack: "t", ending: "End", prevFrame: ",", nextFrame: ".", skipBwd: "ArrowLeft", skipFwd: "ArrowRight", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
1155
+ shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: "Home", trackUntrack: "t", ending: "End", prevFrame: ",", nextFrame: ".", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
1156
1156
  };
1157
1157
  var TimeTravelConsole = class _TimeTravelConsole {
1158
1158
  static count = 0;
@@ -1173,13 +1173,13 @@ var TimeTravelConsole = class _TimeTravelConsole {
1173
1173
  this.config = reactive({ title: `Time Travel Console ${this.index = ++_TimeTravelConsole.count}`, ...build });
1174
1174
  this.state.open = !!this.config.startOpen;
1175
1175
  let wlLive = false, blLive = false;
1176
- 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" });
1176
+ 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${formatKeyTooltip(keys.shortcuts.clrHistory)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clrHistory), onclick: () => (this.time.clear(), this.state.import = "") }), undo = createEl("button", { textContent: `Undo${formatKeyTooltip(keys.shortcuts.undo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.undo), onclick: () => this.time.undo(this.state.stride) }), redo = createEl("button", { textContent: `Redo${formatKeyTooltip(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo), onclick: () => this.time.redo(this.state.stride) }), genesis = createEl("button", { textContent: `Genesis${formatKeyTooltip(keys.shortcuts.genesis)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.genesis), onclick: () => this.time.jumpTo(0) }), playPause = createEl("button", { onclick: () => this.time[s.paused ? "play" : "pause"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.playPause) }), rewind = createEl("button", { textContent: `Rewind${formatKeyTooltip(keys.shortcuts.rewind)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.rewind), onclick: this.time.rewind }), trackUntrack = createEl("button", { onclick: () => this.time[s.tracking ? "untrack" : "track"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.trackUntrack) }), 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${formatKeyTooltip(keys.shortcuts.export)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.export), onclick: () => this.state.import = this.time.export(null, 2) }), imp = createEl("button", { textContent: `Import${formatKeyTooltip(keys.shortcuts.import)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.import), onclick: () => this.state.import.trim().length && this.time.import(this.state.import) }), clr = createEl("button", { textContent: `Clear${formatKeyTooltip(keys.shortcuts.clear)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clear), 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" });
1177
1177
  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` })));
1178
1178
  status.append((box.append(frame), box), clrHistory);
1179
1179
  filters.append((filterBox.append((filterRow1.append(whitelistLabel, whitelist), filterRow1), (filterRow2.append(blacklistLabel, blacklist), filterRow2)), filterBox));
1180
1180
  panel.append(title, status, (row1.append(playPause, rewind, genesis), row1), (row2.append(undo, redo, trackUntrack, stride), row2), payload, (row3.append(speed, range), row3), filters, (row4.append(exp, imp, clr), row4), io, (row5.append(delay, limit, (read.append(readBox, " Read Mirror"), read), (write.append(writeBox, " Write Mirror"), write)), row5), (foot.prepend(stats), foot.append(link), foot));
1181
1181
  this.host.append(toggle, panel);
1182
- this.keydown = (e, can = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true), a = can && keyEventAllowed(e, keys)) => (a && e.stopImmediatePropagation(), a === "undo" ? this.time.undo(this.state.stride) : a === "redo" ? this.time.redo(this.state.stride) : a === "genesis" ? this.time.jumpTo(0) : a === "trackUntrack" ? this.time[s.tracking ? "untrack" : "track"]() : a === "ending" ? this.time.jumpTo(s.history.length) : a === "prevFrame" ? this.time.step(this.state.stride, false) : a === "nextFrame" ? this.time.step(this.state.stride, true) : a === "skipBwd" ? this.time.step(5 * this.state.stride, false) : a === "skipFwd" ? this.time.step(5 * this.state.stride, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = ""));
1182
+ this.keydown = (e, can = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true), a = can && keyEventAllowed(e, keys)) => (a && e.stopImmediatePropagation(), a === "undo" ? this.time.undo(this.state.stride) : a === "redo" ? this.time.redo(this.state.stride) : a === "genesis" ? this.time.jumpTo(0) : a === "trackUntrack" ? this.time[s.tracking ? "untrack" : "track"]() : a === "ending" ? this.time.jumpTo(s.history.length) : a === "prevFrame" ? this.time.step(this.state.stride, false) : a === "nextFrame" ? this.time.step(this.state.stride, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = ""));
1183
1183
  this.keyup = (e, can = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true), a = can && keyEventAllowed(e, keys)) => a && e.stopImmediatePropagation();
1184
1184
  window.addEventListener("keydown", this.keydown), window.addEventListener("keyup", this.keyup);
1185
1185
  const sync = [
@@ -1190,8 +1190,8 @@ var TimeTravelConsole = class _TimeTravelConsole {
1190
1190
  if (host.parentNode !== dock) dock.appendChild(host);
1191
1191
  }),
1192
1192
  effect(() => toggle.textContent = `${(panel.hidden = !this.state.open) ? "Show" : "Hide"} ${title.textContent = this.config.title ?? ""}`),
1193
- effect(() => playPause.textContent = `${s.paused ? "Play" : "Pause"}${formatKeyForDisplay(keys.shortcuts.playPause)}`),
1194
- effect(() => trackUntrack.textContent = `${s.tracking ? "Untrack" : "Track"}${formatKeyForDisplay(keys.shortcuts.trackUntrack)}`),
1193
+ effect(() => playPause.textContent = `${s.paused ? "Play" : "Pause"}${formatKeyTooltip(keys.shortcuts.playPause)}`),
1194
+ effect(() => trackUntrack.textContent = `${s.tracking ? "Untrack" : "Track"}${formatKeyTooltip(keys.shortcuts.trackUntrack)}`),
1195
1195
  effect((sets = 0, txs = 0) => {
1196
1196
  range.max = String(s.history.length);
1197
1197
  range.disabled = clrHistory.disabled = !s.history.length;
@@ -1,4 +1,18 @@
1
- export { e as effect } from '../vanilla-Bs-5iI0s.cjs';
2
- export { b3 as Autotracker, b4 as withTracker } from '../obj-CM05g1eW.cjs';
3
- export { a as TimeTravelConsole, T as TimeTravelConsoleConfig } from '../TimeTravelConsole-Ck3GwvXR.cjs';
4
- import '../index-FMuvzRw_.cjs';
1
+ import { k as EffectOptions } from '../consts-CS2UoTQk.cjs';
2
+ export { b3 as Autotracker, b4 as withTracker } from '../consts-CS2UoTQk.cjs';
3
+ export { a as TimeTravelConsole, T as TimeTravelConsoleConfig } from '../TimeTravelConsole-svHnyVJ5.cjs';
4
+ import '../index-C2r5vx2_.cjs';
5
+
6
+ /**
7
+ * Runs a reactive side effect in vanilla JavaScript.
8
+ * The callback executes immediately, tracks accessed state, and re-runs when
9
+ * tracked dependencies change.
10
+ * @param callback Effect callback.
11
+ * @param options Listener options if `sync: false` else Watcher Options.
12
+ * @returns Cleanup function that stops tracking and releases resources.
13
+ * @example
14
+ * const stop = effect(() => console.log(state.count));
15
+ */
16
+ declare function effect(callback: () => void, options?: EffectOptions): () => void;
17
+
18
+ export { effect };
@@ -1,4 +1,18 @@
1
- export { e as effect } from '../vanilla-KGPkYjU_.js';
2
- export { b3 as Autotracker, b4 as withTracker } from '../obj-CM05g1eW.js';
3
- export { a as TimeTravelConsole, T as TimeTravelConsoleConfig } from '../TimeTravelConsole-BwHB0LsE.js';
4
- import '../index-K1TE7RnF.js';
1
+ import { k as EffectOptions } from '../consts-CS2UoTQk.js';
2
+ export { b3 as Autotracker, b4 as withTracker } from '../consts-CS2UoTQk.js';
3
+ export { a as TimeTravelConsole, T as TimeTravelConsoleConfig } from '../TimeTravelConsole-BQv0oWkM.js';
4
+ import '../index-D6S7TeWV.js';
5
+
6
+ /**
7
+ * Runs a reactive side effect in vanilla JavaScript.
8
+ * The callback executes immediately, tracks accessed state, and re-runs when
9
+ * tracked dependencies change.
10
+ * @param callback Effect callback.
11
+ * @param options Listener options if `sync: false` else Watcher Options.
12
+ * @returns Cleanup function that stops tracking and releases resources.
13
+ * @example
14
+ * const stop = effect(() => console.log(state.count));
15
+ */
16
+ declare function effect(callback: () => void, options?: EffectOptions): () => void;
17
+
18
+ export { effect };
@@ -3,9 +3,9 @@ import {
3
3
  TimeTravelConsole,
4
4
  effect,
5
5
  withTracker
6
- } from "../chunk-4U7VB3JS.js";
7
- import "../chunk-BOBAOEKS.js";
8
- import "../chunk-4SGW3Y6X.js";
6
+ } from "../chunk-KSP2RS2U.js";
7
+ import "../chunk-TWHE4ZHF.js";
8
+ import "../chunk-YITKWJ2E.js";
9
9
  import "../chunk-GH5QAGIC.js";
10
10
  export {
11
11
  Autotracker,
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  wpArr
3
- } from "./chunk-BOBAOEKS.js";
3
+ } from "./chunk-TWHE4ZHF.js";
4
4
  import {
5
5
  KEYS_BLOCKS,
6
6
  createEl,
7
- formatKeyForDisplay,
7
+ formatKeyTooltip,
8
8
  keyEventAllowed,
9
9
  parseForARIAKS
10
- } from "./chunk-4SGW3Y6X.js";
10
+ } from "./chunk-YITKWJ2E.js";
11
11
  import {
12
12
  CTX,
13
13
  NIL,
@@ -179,7 +179,7 @@ function effect(callback, options = NIL) {
179
179
  var keys = {
180
180
  blocks: KEYS_BLOCKS,
181
181
  overrides: ["Ctrl+z", "Cmd+z", "Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z", "Home", "End", "ArrowLeft", "ArrowRight", "Space", "Alt+Space", "Escape", "Delete"],
182
- shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: "Home", trackUntrack: "t", ending: "End", prevFrame: ",", nextFrame: ".", skipBwd: "ArrowLeft", skipFwd: "ArrowRight", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
182
+ shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: "Home", trackUntrack: "t", ending: "End", prevFrame: ",", nextFrame: ".", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
183
183
  };
184
184
  var TimeTravelConsole = class _TimeTravelConsole {
185
185
  static count = 0;
@@ -200,13 +200,13 @@ 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: "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" });
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${formatKeyTooltip(keys.shortcuts.clrHistory)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clrHistory), onclick: () => (this.time.clear(), this.state.import = "") }), undo = createEl("button", { textContent: `Undo${formatKeyTooltip(keys.shortcuts.undo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.undo), onclick: () => this.time.undo(this.state.stride) }), redo = createEl("button", { textContent: `Redo${formatKeyTooltip(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo), onclick: () => this.time.redo(this.state.stride) }), genesis = createEl("button", { textContent: `Genesis${formatKeyTooltip(keys.shortcuts.genesis)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.genesis), onclick: () => this.time.jumpTo(0) }), playPause = createEl("button", { onclick: () => this.time[s.paused ? "play" : "pause"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.playPause) }), rewind = createEl("button", { textContent: `Rewind${formatKeyTooltip(keys.shortcuts.rewind)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.rewind), onclick: this.time.rewind }), trackUntrack = createEl("button", { onclick: () => this.time[s.tracking ? "untrack" : "track"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.trackUntrack) }), 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${formatKeyTooltip(keys.shortcuts.export)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.export), onclick: () => this.state.import = this.time.export(null, 2) }), imp = createEl("button", { textContent: `Import${formatKeyTooltip(keys.shortcuts.import)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.import), onclick: () => this.state.import.trim().length && this.time.import(this.state.import) }), clr = createEl("button", { textContent: `Clear${formatKeyTooltip(keys.shortcuts.clear)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clear), 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));
207
207
  panel.append(title, status, (row1.append(playPause, rewind, genesis), row1), (row2.append(undo, redo, trackUntrack, stride), row2), payload, (row3.append(speed, range), row3), filters, (row4.append(exp, imp, clr), row4), io, (row5.append(delay, limit, (read.append(readBox, " Read Mirror"), read), (write.append(writeBox, " Write Mirror"), write)), row5), (foot.prepend(stats), foot.append(link), foot));
208
208
  this.host.append(toggle, panel);
209
- this.keydown = (e, can = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true), a = can && keyEventAllowed(e, keys)) => (a && e.stopImmediatePropagation(), a === "undo" ? this.time.undo(this.state.stride) : a === "redo" ? this.time.redo(this.state.stride) : a === "genesis" ? this.time.jumpTo(0) : a === "trackUntrack" ? this.time[s.tracking ? "untrack" : "track"]() : a === "ending" ? this.time.jumpTo(s.history.length) : a === "prevFrame" ? this.time.step(this.state.stride, false) : a === "nextFrame" ? this.time.step(this.state.stride, true) : a === "skipBwd" ? this.time.step(5 * this.state.stride, false) : a === "skipFwd" ? this.time.step(5 * this.state.stride, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = ""));
209
+ this.keydown = (e, can = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true), a = can && keyEventAllowed(e, keys)) => (a && e.stopImmediatePropagation(), a === "undo" ? this.time.undo(this.state.stride) : a === "redo" ? this.time.redo(this.state.stride) : a === "genesis" ? this.time.jumpTo(0) : a === "trackUntrack" ? this.time[s.tracking ? "untrack" : "track"]() : a === "ending" ? this.time.jumpTo(s.history.length) : a === "prevFrame" ? this.time.step(this.state.stride, false) : a === "nextFrame" ? this.time.step(this.state.stride, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = ""));
210
210
  this.keyup = (e, can = this.state.open && (this.config.devOnly ? CTX.isDevEnv : true), a = can && keyEventAllowed(e, keys)) => a && e.stopImmediatePropagation();
211
211
  window.addEventListener("keydown", this.keydown), window.addEventListener("keyup", this.keyup);
212
212
  const sync = [
@@ -217,8 +217,8 @@ var TimeTravelConsole = class _TimeTravelConsole {
217
217
  if (host.parentNode !== dock) dock.appendChild(host);
218
218
  }),
219
219
  effect(() => toggle.textContent = `${(panel.hidden = !this.state.open) ? "Show" : "Hide"} ${title.textContent = this.config.title ?? ""}`),
220
- effect(() => playPause.textContent = `${s.paused ? "Play" : "Pause"}${formatKeyForDisplay(keys.shortcuts.playPause)}`),
221
- effect(() => trackUntrack.textContent = `${s.tracking ? "Untrack" : "Track"}${formatKeyForDisplay(keys.shortcuts.trackUntrack)}`),
220
+ effect(() => playPause.textContent = `${s.paused ? "Play" : "Pause"}${formatKeyTooltip(keys.shortcuts.playPause)}`),
221
+ effect(() => trackUntrack.textContent = `${s.tracking ? "Untrack" : "Track"}${formatKeyTooltip(keys.shortcuts.trackUntrack)}`),
222
222
  effect((sets = 0, txs = 0) => {
223
223
  range.max = String(s.history.length);
224
224
  range.disabled = clrHistory.disabled = !s.history.length;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  guardAllMethods,
3
3
  guardMethod
4
- } from "./chunk-4SGW3Y6X.js";
4
+ } from "./chunk-YITKWJ2E.js";
5
5
  import {
6
6
  getPath,
7
7
  getReactor,