sia-reactor 0.0.19 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +102 -58
  2. package/dist/TimeTravelOverlay-CJv-S_Km.d.cts +41 -0
  3. package/dist/TimeTravelOverlay-DxqJL0Zk.d.ts +41 -0
  4. package/dist/adapters/react.cjs +308 -92
  5. package/dist/adapters/react.d.cts +68 -10
  6. package/dist/adapters/react.d.ts +68 -10
  7. package/dist/adapters/react.js +80 -29
  8. package/dist/adapters/vanilla.cjs +957 -10
  9. package/dist/adapters/vanilla.d.cts +4 -2
  10. package/dist/adapters/vanilla.d.ts +4 -2
  11. package/dist/adapters/vanilla.js +8 -12
  12. package/dist/{chunk-Q2AKMIHN.js → chunk-2WBPGSRL.js} +106 -48
  13. package/dist/chunk-5A44QFT6.js +93 -0
  14. package/dist/{chunk-4MJUBEI7.js → chunk-DP74DVRT.js} +4 -2
  15. package/dist/{chunk-UQIMMJTY.js → chunk-P37ADJMM.js} +3 -3
  16. package/dist/chunk-TFLYCXK4.js +251 -0
  17. package/dist/{index-C2hyIh0K.d.cts → index-Oie9hhE8.d.cts} +14 -10
  18. package/dist/{index-C2hyIh0K.d.ts → index-Oie9hhE8.d.ts} +14 -10
  19. package/dist/index.cjs +45 -52
  20. package/dist/index.d.cts +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +4 -6
  23. package/dist/plugins.cjs +72 -73
  24. package/dist/plugins.d.cts +4 -75
  25. package/dist/plugins.d.ts +4 -75
  26. package/dist/plugins.js +27 -22
  27. package/dist/styles/time-travel-overlay.css +189 -0
  28. package/dist/super.d.ts +79 -26
  29. package/dist/super.global.js +200 -105
  30. package/dist/timeTravel-B1vedDQc.d.ts +76 -0
  31. package/dist/timeTravel-WpgWmKu-.d.cts +76 -0
  32. package/dist/utils.cjs +34 -7
  33. package/dist/utils.d.cts +9 -2
  34. package/dist/utils.d.ts +9 -2
  35. package/dist/utils.js +17 -65
  36. package/package.json +3 -2
  37. package/dist/chunk-FGUCKMLH.js +0 -154
  38. package/dist/chunk-KIQP7G7W.js +0 -80
@@ -0,0 +1,251 @@
1
+ import {
2
+ reactive
3
+ } from "./chunk-2WBPGSRL.js";
4
+ import {
5
+ createEl,
6
+ formatKeyForDisplay,
7
+ keyEventAllowed,
8
+ parseForARIAKS
9
+ } from "./chunk-5A44QFT6.js";
10
+ import {
11
+ CTX,
12
+ NIL,
13
+ RAW,
14
+ canHandle,
15
+ nuke
16
+ } from "./chunk-DP74DVRT.js";
17
+
18
+ // src/ts/adapters/autotracker.ts
19
+ var Autotracker = class {
20
+ proxy;
21
+ deps = /* @__PURE__ */ new Map();
22
+ isTracking = true;
23
+ rtr;
24
+ /** only allows one reactor to autotrack when available */
25
+ autortr;
26
+ clups = [];
27
+ lastPath;
28
+ proxyCache = /* @__PURE__ */ new WeakMap();
29
+ /** @param rtr Reactor instance used for path subscriptions. */
30
+ constructor(rtr) {
31
+ this.autortr = this.rtr = rtr;
32
+ }
33
+ /**
34
+ * Starts a new tracking pass and returns a tracking proxy for `target` if `this` was instantiated with a `Reactor`.
35
+ * @param target Snapshot (or state branch) to track reads from.
36
+ * @returns Read-tracking proxy.
37
+ * @example
38
+ * const atrkr = new Autotracker(rtr);
39
+ * const state = atrkr.tracked(rtr.snapshot());
40
+ * const name = state.user.profile.name;
41
+ */
42
+ tracked(target) {
43
+ return this.unblock(), this.rtr ? this.proxy = this.proxied(target, "") : target;
44
+ }
45
+ proxied(obj, path) {
46
+ if (!obj || "object" !== typeof obj) return obj;
47
+ const cached = this.proxyCache.get(obj);
48
+ if (cached) return cached;
49
+ if (!canHandle(obj, this.rtr.config, false)) return obj;
50
+ const proxy = new Proxy(obj, {
51
+ // Minimal Proxy Handler
52
+ get: (object, key, receiver) => {
53
+ if (key === RAW) return this.rtr.log(`\u{1F440} [AutoTracker \`get\` Trap] Peeked at ${object}`), object;
54
+ const keyStr = String(key), fullPath = path ? `${path}.${keyStr}` : keyStr;
55
+ return this.rtr.log(`\u{1F50D} [AutoTracker \`get\` Trap] Initiated for "${keyStr}" on "${path}"`), this.track(fullPath), this.proxied(!this.rtr.config.preserveContext ? object[key] : Reflect.get(object, key, receiver), fullPath);
56
+ },
57
+ has: (object, key) => {
58
+ const keyStr = String(key), fullPath = path ? `${path}.${keyStr}` : keyStr;
59
+ return this.rtr.log(`\u2753 [AutoTracker \`has\` Trap] Initiated for "${keyStr}" on "${path}"`), this.track(fullPath), !this.rtr.config.preserveContext ? key in object : Reflect.has(object, key);
60
+ },
61
+ getOwnPropertyDescriptor: (object, key) => {
62
+ const keyStr = String(key), fullPath = path ? `${path}.${keyStr}` : keyStr;
63
+ return this.rtr.log(`\u{1F4CB} [AutoTracker \`getOwnPropertyDescriptor\` Trap] Initiated for "${keyStr}" on "${path}"`), this.track(fullPath), !this.rtr.config.preserveContext ? Object.getOwnPropertyDescriptor(object, key) : Reflect.getOwnPropertyDescriptor(object, key);
64
+ },
65
+ ownKeys: (object) => {
66
+ const safePath = path || "*";
67
+ return this.rtr.log(`\u{1F511} [AutoTracker \`ownKeys\` Trap] Initiated on "${safePath}"`), this.track(safePath), Reflect.ownKeys(object);
68
+ },
69
+ set: (_, key) => {
70
+ throw new Error(`\u{1F6E1}\uFE0F [AutoTracker \`set\` Trap] Blocked for "${String(key)}" on "${path}"`);
71
+ },
72
+ deleteProperty: (_, key) => {
73
+ throw new Error(`\u{1F6E1}\uFE0F [AutoTracker \`deleteProperty\` Trap] Blocked for "${String(key)}" on "${path}"`);
74
+ },
75
+ defineProperty: (_, key) => {
76
+ throw new Error(`\u{1F6E1}\uFE0F [AutoTracker \`defineProperty\` Trap] Blocked for "${String(key)}" on "${path}"`);
77
+ },
78
+ setPrototypeOf: (_, key) => {
79
+ throw new Error(`\u{1F6E1}\uFE0F [AutoTracker \`setPrototypeOf\` Trap] Blocked for "${String(key)}" on "${path}"`);
80
+ }
81
+ });
82
+ return this.proxyCache.set(obj, proxy), proxy;
83
+ }
84
+ /** Adds a path to the tracking set. */
85
+ track(path, rtr = this.rtr, prune = false) {
86
+ if (!this.isTracking || !path || this.autortr && this.autortr !== rtr) return path;
87
+ let paths = this.deps.get(rtr);
88
+ if (!prune && !paths) paths = (this.deps.set(rtr, paths = /* @__PURE__ */ new Set()), paths);
89
+ if (path.startsWith(this.lastPath + ".")) paths.delete(this.lastPath);
90
+ return !prune && paths.add(this.lastPath = path), path;
91
+ }
92
+ /** Removes a path from the tracking set. */
93
+ untrack(path, rtr = this.rtr) {
94
+ this.deps.get(rtr)?.delete(path);
95
+ }
96
+ /** Enables path tracking. */
97
+ unblock(rtr = this.rtr) {
98
+ this.deps.clear();
99
+ this.autortr = rtr;
100
+ this.isTracking = true;
101
+ this.lastPath = void 0;
102
+ }
103
+ /** Temporarily disables path tracking. */
104
+ block() {
105
+ this.autortr = void 0;
106
+ this.isTracking = false;
107
+ }
108
+ /**
109
+ * Subscribes an effect to tracked paths.
110
+ * Uses `watch` when `options.sync === true` (synchronous updates), otherwise
111
+ * uses `on` (batched/asynchronous listener wave).
112
+ * @param cb Effect callback.
113
+ * @param options Effect options.
114
+ * @returns Cleanup function for active subscriptions.
115
+ * @example
116
+ * const atrkr = new Autotracker(rtr);
117
+ * const view = atrkr.tracked(rtr.snapshot()); // tracked works if `rtr` was passed at instantiation
118
+ * view.user.name;
119
+ * const stop = atrkr.callback(() => console.log("changed")); // re-run after when ".user.name" changes
120
+ * @example Packaged Customization
121
+ * const atrkr = new Autotracker(); // no reactor passed
122
+ * withTracker(atrkr, () => state.user.name); // import `withTracker` first
123
+ * const stop = atrkr.callback(() => console.log("sync"), { sync: true }); // re-run immediately when ".user.name" changes, works on any path used from any reactor state
124
+ * @example Extensive customization
125
+ * atrkr.unblock();
126
+ * const prev = CTX.autotracker;
127
+ * CTX.autotracker = atrkr; // import CTX first
128
+ * state.user.name;
129
+ * CTX.autotracker = prev;
130
+ */
131
+ callback(cb, options = NIL) {
132
+ this.cleanup();
133
+ const method = options.sync ? "watch" : "on";
134
+ for (const [rtr, paths] of this.deps) {
135
+ if (!paths.size || paths.has("*")) rtr && this.clups.push(rtr[method]("*", cb, options));
136
+ else for (const path of paths) this.clups.push(rtr[method](path, cb, options));
137
+ }
138
+ return () => this.cleanup();
139
+ }
140
+ /** Clears active subscriptions and blocks tracking. */
141
+ cleanup() {
142
+ this.block();
143
+ for (let i = 0, len = this.clups.length; i < len; i++) this.clups[i]();
144
+ this.clups.length = 0;
145
+ }
146
+ destroy() {
147
+ this.deps.clear(), this.cleanup(), nuke(this);
148
+ }
149
+ };
150
+ function withTracker(tracker, run, rtr) {
151
+ const prev = CTX.autotracker;
152
+ CTX.autotracker = tracker;
153
+ try {
154
+ return tracker.unblock(rtr), run();
155
+ } finally {
156
+ CTX.autotracker = prev;
157
+ }
158
+ }
159
+
160
+ // src/ts/adapters/vanilla/effect.ts
161
+ function effect(callback, options) {
162
+ const atrkr = new Autotracker();
163
+ let destroyed = false;
164
+ (function execute() {
165
+ if (!destroyed) withTracker(atrkr, () => callback()), atrkr.callback(execute, options);
166
+ })();
167
+ return () => (destroyed = true, atrkr.destroy());
168
+ }
169
+
170
+ // src/ts/adapters/vanilla/TimeTravelOverlay.ts
171
+ var keys = {
172
+ overrides: ["Ctrl+z", "Cmd+z", "Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z", "Ctrl+g", "Cmd+g", ",", ".", "ArrowLeft", "ArrowRight", "Space", "Alt+Space", "Escape", "Delete", "e", "i", "c"],
173
+ shortcuts: { undo: ["Ctrl+z", "Cmd+z"], redo: ["Ctrl+y", "Cmd+y", "Ctrl+Shift+z", "Cmd+Shift+z"], genesis: ["Ctrl+g", "Cmd+g"], prevFrame: ",", nextFrame: ".", skipBwd: "ArrowLeft", skipFwd: "ArrowRight", playPause: "Space", rewind: "Alt+Space", closeOverlay: "Escape", clrHistory: "Delete", export: "e", import: "i", clear: "c" }
174
+ };
175
+ var TimeTravelOverlay = class _TimeTravelOverlay {
176
+ static count = 0;
177
+ index = _TimeTravelOverlay.count;
178
+ config;
179
+ state = reactive({ open: false, import: "" });
180
+ time;
181
+ els;
182
+ clups = [];
183
+ keyup;
184
+ /** Creates a docked TimeTravel overlay bound to a plugin instance.
185
+ * @param time TimeTravel plugin instance that owns timeline operations.
186
+ * @param build Optional initial overlay config overrides.
187
+ */
188
+ constructor(time, build = {}) {
189
+ this.time = time;
190
+ this.config = reactive({ title: `Time Travel Overlay ${this.index = ++_TimeTravelOverlay.count}`, ...build });
191
+ this.state.open = !!this.config.startOpen;
192
+ const s = this.time.state, host = createEl("div", { className: "tt-overlay-host" }), toggle = createEl("button", { className: "tt-overlay-toggle", type: "button", onclick: () => this.state.open = !this.state.open }), panel = createEl("aside", { className: "tt-overlay", ariaLabel: "time travel overlay" }), title = createEl("div", { className: "title" }), frame = createEl("span", { className: "muted" }), clrHistory = createEl("button", { textContent: `Clear History${formatKeyForDisplay(keys.shortcuts.clrHistory)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clrHistory, false), onclick: () => (this.time.clear(), this.state.import = "") }), undo = createEl("button", { textContent: `Undo${formatKeyForDisplay(keys.shortcuts.undo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.undo, false), onclick: this.time.undo }), redo = createEl("button", { textContent: `Redo${formatKeyForDisplay(keys.shortcuts.redo[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.redo, false), onclick: this.time.redo }), genesis = createEl("button", { textContent: `Genesis${formatKeyForDisplay(keys.shortcuts.genesis[0])}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.genesis, false), onclick: () => this.time.jumpTo(0) }), playPause = createEl("button", { onclick: () => this.time[s.paused ? "play" : "pause"](), ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.playPause, false) }), rewind = createEl("button", { textContent: `Rewind${formatKeyForDisplay(keys.shortcuts.rewind)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.rewind, false), onclick: this.time.rewind }), range = createEl("input", { type: "range", min: "0", max: "0", value: "0", title: "time travel frame", ariaLabel: "time travel frame", oninput: () => this.time.jumpTo(Number(range.value)) }), exp = createEl("button", { textContent: `Export${formatKeyForDisplay(keys.shortcuts.export)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.export, false), onclick: () => this.state.import = this.time.export(null, 2) }), imp = createEl("button", { textContent: `Import${formatKeyForDisplay(keys.shortcuts.import)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.import, false), onclick: () => this.state.import.trim().length && this.time.import(this.state.import) }), clr = createEl("button", { textContent: `Clear${formatKeyForDisplay(keys.shortcuts.clear)}`, ariaKeyShortcuts: parseForARIAKS(keys.shortcuts.clear, false), onclick: () => this.state.import = "" }), payload = createEl("textarea", { className: "tt-io", readOnly: true, placeholder: "current payload json", title: "current payload" }), io = createEl("textarea", { className: "tt-io", placeholder: "timeline payload json", oninput: () => this.state.import = io.value }), foot = createEl("p", { className: "tt-footnote", textContent: "Want this in your app? " }), link = createEl("a", { target: "_blank", rel: "noreferrer noopener", textContent: "sia-reactor", href: "https://www.npmjs.com/package/sia-reactor" }), box = createEl("div", { className: "tt-status-box" }), status = createEl("div", { className: "tt-status-row" }), row1 = createEl("div", { className: "tt-row" }), row2 = createEl("div", { className: "tt-row" }), row3 = createEl("div", { className: "tt-row" });
193
+ status.append((box.append(frame), box), clrHistory);
194
+ panel.append(title, status, (row1.append(undo, redo, genesis), row1), (row2.append(playPause, rewind), row2), payload, range, (row3.append(exp, imp, clr), row3), io, (foot.appendChild(link), foot));
195
+ host.append(toggle, panel);
196
+ this.els = { host, toggle, panel, title, frame, clrHistory, undo, redo, genesis, playPause, rewind, range, exp, imp, clr, payload, io };
197
+ this.keyup = (e) => {
198
+ const a = this.state.open && keyEventAllowed(e, keys);
199
+ a === "undo" ? this.time.undo() : a === "redo" ? this.time.redo() : a === "genesis" ? this.time.jumpTo(0) : a === "prevFrame" ? this.time.step(1, false) : a === "nextFrame" ? this.time.step(1, true) : a === "skipBwd" ? this.time.step(5, false) : a === "skipFwd" ? this.time.step(5, true) : a === "rewind" ? this.time.rewind() : a === "playPause" ? this.time[s.paused ? "play" : "pause"]() : a === "clrHistory" ? this.time.clear() : a === "closeOverlay" ? this.state.open = false : a === "export" ? this.state.import = this.time.export() : a === "import" ? this.state.import.trim().length && this.time.import(this.state.import) : a === "clear" && (this.state.import = "");
200
+ };
201
+ window.addEventListener("keydown", this.keyup);
202
+ const sync = [
203
+ effect(() => this.config.color ? host.style.setProperty("--sia-tt-color", this.config.color) : host.style.removeProperty("--sia-tt-color")),
204
+ effect(() => {
205
+ if (this.config.devOnly && !CTX.isDevEnv) return void host.remove();
206
+ const dock = getDock(this.config.container);
207
+ if (host.parentNode !== dock) dock.appendChild(host);
208
+ }),
209
+ effect(() => toggle.textContent = `${(panel.hidden = !this.state.open) ? "Show" : "Hide"} ${title.textContent = this.config.title ?? ""}`),
210
+ effect(() => playPause.textContent = `${s.paused ? "Play" : "Pause"}${formatKeyForDisplay(keys.shortcuts.playPause)}`),
211
+ effect(() => {
212
+ frame.textContent = `Frame: ${s.currentFrame} / ${s.history.length}`;
213
+ range.disabled = clrHistory.disabled = !s.history.length;
214
+ genesis.disabled = rewind.disabled = undo.disabled = !s.currentFrame;
215
+ playPause.disabled = redo.disabled = s.currentFrame >= s.history.length;
216
+ range.max = String(s.history.length);
217
+ range.value = String(Math.min(s.currentFrame, s.history.length));
218
+ payload.value = JSON.stringify(s.currentFrame ? s.history[s.currentFrame - 1] : { type: "genesis", value: s.initialState }, null, 2);
219
+ }),
220
+ effect(() => {
221
+ clr.disabled = imp.disabled = !this.state.import.trim().length;
222
+ io.value !== this.state.import && (io.value = this.state.import);
223
+ })
224
+ ];
225
+ this.clups.push(...sync);
226
+ }
227
+ destroy() {
228
+ this.clups.forEach((fn) => fn());
229
+ this.keyup && window.removeEventListener("keydown", this.keyup);
230
+ this.els.host.remove();
231
+ nuke(this), --_TimeTravelOverlay.count;
232
+ }
233
+ };
234
+ function getDirChild(parent, className) {
235
+ for (const child of parent.children) if (child instanceof HTMLElement && child.classList.contains(className)) return child;
236
+ }
237
+ function getDock(container) {
238
+ const host = container && container !== document.documentElement ? container : document.body;
239
+ if (host !== document.body && getComputedStyle(host).position === "static") host.style.position = "relative";
240
+ const layer = getDirChild(host, "tt-overlay-layer") || createEl("div", { className: "tt-overlay-layer" }, void 0, { position: host === document.body ? "fixed" : "absolute" });
241
+ if (layer.parentElement !== host) host.appendChild(layer);
242
+ const dock = getDirChild(layer, "tt-overlay-dock") || createEl("div", { className: "tt-overlay-dock" });
243
+ return dock.parentElement !== layer && layer.appendChild(dock), dock;
244
+ }
245
+
246
+ export {
247
+ Autotracker,
248
+ withTracker,
249
+ effect,
250
+ TimeTravelOverlay
251
+ };
@@ -172,7 +172,7 @@ type RDepth = 10; // current limit for state trees, observed ts max - 19; limit
172
172
  type RPrev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
173
173
 
174
174
  /** Reactor method names exposed on objects returned by {@link reactive}. */
175
- declare const methods: readonly ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "cascade", "snapshot", "reset", "destroy"];
175
+ declare const methods: readonly ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "snapshot", "cascade", "plugIn", "reset", "destroy"];
176
176
  type Method = (typeof methods)[number];
177
177
  type Prefix<P extends ReactivePreferences | undefined> = P extends {
178
178
  prefix?: infer X extends string;
@@ -203,6 +203,7 @@ type Reactive<T extends object, P extends ReactivePreferences | undefined = unde
203
203
  };
204
204
  /**
205
205
  * Attaches Reactor APIs to a state object and returns its reactive proxy.
206
+ * If an existing `reactive()` return value is passed, it is re-returned ignoring change in preferences.
206
207
  * @param target Source state object or an existing Reactor instance.
207
208
  * @param build Reactor initial configuration.
208
209
  * @param preferences Method naming preferences for exposed APIs.
@@ -326,7 +327,7 @@ interface Target<T, P extends WildPaths<T> = WildPaths<T>> {
326
327
  * Whether the key for the value existed on the parent object.
327
328
  * For accuracy on if `key` was in the `object` rather than checking `oldValue` against undefined
328
329
  */
329
- keyExisted: boolean;
330
+ hadKey: boolean;
330
331
  /** Parent-branch value for the path. */
331
332
  object: PathBranchValue<T, P>;
332
333
  }
@@ -363,7 +364,7 @@ interface UpdatePayload<T, P extends WildPaths<T> = WildPaths<T>> extends BasePa
363
364
  }
364
365
 
365
366
  /** Event union with payload-aware overrides for `type`, `path`, and value fields (Creates the IDE magic). */
366
- type REvent<T, P extends WildPaths<T> = WildPaths<T>> =
367
+ type REvent<T extends object, P extends WildPaths<T> = WildPaths<T>> =
367
368
  | (Omit<ReactorEvent<T, P>, OverrideEvtProp> &
368
369
  DirectPayload<T, P> &
369
370
  OverrideEvtPart<DirectPayload<T, P>>)
@@ -726,7 +727,7 @@ declare abstract class BaseReactorPlugin<T extends object = any, Config = any, S
726
727
  readonly signal: AbortSignal;
727
728
  rtr: Reactor<T>;
728
729
  config: Config extends object ? Reactive<Config> : Config;
729
- state: State extends object ? Reactive<State> : State;
730
+ readonly state: State extends object ? Reactive<State> : State;
730
731
  constructor(config?: Config, rtr?: Reactor<T>, state?: State);
731
732
  /** Entry point called to initialize plugin wiring. */
732
733
  setup(rtr?: Reactor<T>): void;
@@ -768,13 +769,13 @@ declare class Reactor<T extends object> {
768
769
  protected listeners?: Map<WildPaths<T>, Array<ListenerRecord<T>>>;
769
770
  /**
770
771
  * Creates a new Reactor instance.
771
- * @param object Initial state object.
772
+ * @param target Initial state target.
772
773
  * @param build Reactor bootstrap/build configuration.
773
774
  * @example
774
775
  * const rtr = new Reactor({ count: 0 });
775
776
  */
776
- constructor(object?: T, build?: ReactorBuild<T>);
777
- proxied<O extends object>(obj: O, rejectable?: boolean, indiffable?: boolean, parent?: object, key?: string, path?: string): O;
777
+ constructor(target?: T, build?: ReactorBuild<T>);
778
+ proxied<O extends object>(target: O, rejectable?: boolean, indiffable?: boolean, parent?: object, key?: string, path?: string): O;
778
779
  trace(target: object, path: string, paths?: string[], seen?: WeakSet<object>): Paths<T>[];
779
780
  protected link(target: any, parent: object, key: string, typecheck?: boolean, es?: (object | string)[]): boolean;
780
781
  protected unlink(target: any, parent: object, key: string): void;
@@ -814,7 +815,7 @@ declare class Reactor<T extends object> {
814
815
  getDepth(path: string, depth?: number): number;
815
816
  protected getContext<P extends WildPaths<T>>(path: P): Target<T, P>;
816
817
  protected bindSignal<Cb>(cord: GetterRecord<T> | SetterRecord<T> | DeleterRecord<T> | WatcherRecord<T> | ListenerRecord<T>, sig?: AbortSignal): Cb;
817
- protected cloned(obj: any, raw: boolean, seen?: WeakMap<WeakKey, any>): any;
818
+ protected cloned<O>(target: O, raw: boolean, seen?: WeakMap<WeakKey, any>): O;
818
819
  protected syncAdd<P extends WildPaths<T>>(key: "get" | "set" | "delete" | "watch", path: P, cb: any, opts: SyncOptions | undefined, onImmediate?: (immediate: boolean | "auto") => void): () => boolean | undefined;
819
820
  protected syncDrop<P extends WildPaths<T>>(store: Map<WildPaths<T>, any[]> | undefined, path: P, cb: any): boolean | undefined;
820
821
  /**
@@ -930,7 +931,8 @@ declare class Reactor<T extends object> {
930
931
  * @example
931
932
  * const snap = rtr.snapshot(false, rtr.core.history.past);
932
933
  */
933
- snapshot(raw?: boolean, branch?: T): T;
934
+ snapshot(raw?: boolean): T;
935
+ snapshot<B>(raw?: boolean, branch?: B): B;
934
936
  /**
935
937
  * Cascades object updates into direct child paths.
936
938
  * @param payload Event or payload source.
@@ -1032,6 +1034,8 @@ declare function withTracker<T>(tracker: Autotracker<any>, run: () => T, rtr?: R
1032
1034
 
1033
1035
  /** Global context object for sharing state across the reactor runtime. */
1034
1036
  declare const CTX: {
1037
+ /** Flag indicating whether the application is running in development mode. */
1038
+ isDevEnv: boolean;
1035
1039
  /** active `Autotracker` instance, override for automatic dependency collection on `Reactor` traps. */
1036
1040
  autotracker: Autotracker<any> | null;
1037
1041
  };
@@ -1065,4 +1069,4 @@ declare const NIL: any;
1065
1069
  /** Shared no-operation function. */
1066
1070
  declare const NOOP: () => void;
1067
1071
 
1068
- export { type Payload as $, Autotracker as A, BaseReactorPlugin as B, CTX as C, type DeepKeys as D, type EffectOptions as E, EVT_WARN as F, type Getter as G, type GetterRecord as H, type Inert as I, INDIFFABLE as J, INERTIA as K, type Intent as L, type Listener as M, type ListenerOptions as N, type ListenerOptionsTuple as O, type Paths as P, type ListenerRecord as Q, Reactor as R, type Live as S, NIL as T, NOOP as U, type NoTraverse as V, type WildPaths as W, type PathBranch as X, type PathBranchValue as Y, type PathKey as Z, type PathLeaf as _, type REvent as a, type Primitive as a0, RAW as a1, REJECTABLE as a2, RTR_BATCH as a3, RTR_LOG as a4, type ReactivePreferences as a5, type ReactorBuild as a6, ReactorEvent as a7, SSVERSION as a8, type Setter as a9, stable as aA, state as aB, volatile as aC, type SetterRecord as aa, type Stable as ab, type State as ac, type StrictPathKey as ad, type SyncOptions as ae, type SyncOptionsTuple as af, TERMINATOR as ag, type Target as ah, type Unflatten as ai, type UnionToIntersection as aj, type UpdatePayload as ak, VERSION as al, type Volatile as am, type Watcher as an, type WatcherRecord as ao, getRaw as ap, getSnapshotVersion as aq, getVersion as ar, inert as as, intent as at, isInert as au, isIntent as av, isVolatile as aw, live as ax, methods as ay, reactive as az, type ReactorPluginConstructor as b, canHandle as c, deepClone as d, deleteAny as e, getTrailRecords as f, getAny as g, isObj as h, inAny as i, isPOJO as j, parseEvtOpts as k, type Reactive as l, mergeObjs as m, nuke as n, type PathValue as o, parseAnyObj as p, type ChildPaths as q, type DeepMerge as r, setAny as s, type DeepPartial as t, type DeepRequired as u, type Deleter as v, withTracker as w, type DeleterRecord as x, type DirectPayload as y, EVT_OPTS as z };
1072
+ export { type PathLeaf as $, Autotracker as A, BaseReactorPlugin as B, CTX as C, type DeepKeys as D, type EffectOptions as E, EVT_OPTS as F, EVT_WARN as G, type Getter as H, type Inert as I, type GetterRecord as J, INDIFFABLE as K, INERTIA as L, type Intent as M, type Listener as N, type ListenerOptions as O, type Paths as P, type ListenerOptionsTuple as Q, type Reactive as R, type ListenerRecord as S, type Live as T, NIL as U, NOOP as V, type WildPaths as W, type NoTraverse as X, type PathBranch as Y, type PathBranchValue as Z, type PathKey as _, type REvent as a, type Payload as a0, type Primitive as a1, RAW as a2, REJECTABLE as a3, RTR_BATCH as a4, RTR_LOG as a5, type ReactivePreferences as a6, ReactorEvent as a7, SSVERSION as a8, type Setter as a9, stable as aA, state as aB, volatile as aC, type SetterRecord as aa, type Stable as ab, type State as ac, type StrictPathKey as ad, type SyncOptions as ae, type SyncOptionsTuple as af, TERMINATOR as ag, type Target as ah, type Unflatten as ai, type UnionToIntersection as aj, type UpdatePayload as ak, VERSION as al, type Volatile as am, type Watcher as an, type WatcherRecord as ao, getRaw as ap, getSnapshotVersion as aq, getVersion as ar, inert as as, intent as at, isInert as au, isIntent as av, isVolatile as aw, live as ax, methods as ay, reactive as az, Reactor as b, type ReactorPluginConstructor as c, canHandle as d, deepClone as e, deleteAny as f, getAny as g, getTrailRecords as h, inAny as i, isObj as j, isPOJO as k, parseEvtOpts as l, mergeObjs as m, nuke as n, type ReactorBuild as o, parseAnyObj as p, type PathValue as q, type ChildPaths as r, setAny as s, type DeepMerge as t, type DeepPartial as u, type DeepRequired as v, withTracker as w, type Deleter as x, type DeleterRecord as y, type DirectPayload as z };
@@ -172,7 +172,7 @@ type RDepth = 10; // current limit for state trees, observed ts max - 19; limit
172
172
  type RPrev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
173
173
 
174
174
  /** Reactor method names exposed on objects returned by {@link reactive}. */
175
- declare const methods: readonly ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "cascade", "snapshot", "reset", "destroy"];
175
+ declare const methods: readonly ["tick", "stall", "nostall", "get", "gonce", "noget", "set", "sonce", "noset", "delete", "donce", "nodelete", "watch", "wonce", "nowatch", "on", "once", "off", "snapshot", "cascade", "plugIn", "reset", "destroy"];
176
176
  type Method = (typeof methods)[number];
177
177
  type Prefix<P extends ReactivePreferences | undefined> = P extends {
178
178
  prefix?: infer X extends string;
@@ -203,6 +203,7 @@ type Reactive<T extends object, P extends ReactivePreferences | undefined = unde
203
203
  };
204
204
  /**
205
205
  * Attaches Reactor APIs to a state object and returns its reactive proxy.
206
+ * If an existing `reactive()` return value is passed, it is re-returned ignoring change in preferences.
206
207
  * @param target Source state object or an existing Reactor instance.
207
208
  * @param build Reactor initial configuration.
208
209
  * @param preferences Method naming preferences for exposed APIs.
@@ -326,7 +327,7 @@ interface Target<T, P extends WildPaths<T> = WildPaths<T>> {
326
327
  * Whether the key for the value existed on the parent object.
327
328
  * For accuracy on if `key` was in the `object` rather than checking `oldValue` against undefined
328
329
  */
329
- keyExisted: boolean;
330
+ hadKey: boolean;
330
331
  /** Parent-branch value for the path. */
331
332
  object: PathBranchValue<T, P>;
332
333
  }
@@ -363,7 +364,7 @@ interface UpdatePayload<T, P extends WildPaths<T> = WildPaths<T>> extends BasePa
363
364
  }
364
365
 
365
366
  /** Event union with payload-aware overrides for `type`, `path`, and value fields (Creates the IDE magic). */
366
- type REvent<T, P extends WildPaths<T> = WildPaths<T>> =
367
+ type REvent<T extends object, P extends WildPaths<T> = WildPaths<T>> =
367
368
  | (Omit<ReactorEvent<T, P>, OverrideEvtProp> &
368
369
  DirectPayload<T, P> &
369
370
  OverrideEvtPart<DirectPayload<T, P>>)
@@ -726,7 +727,7 @@ declare abstract class BaseReactorPlugin<T extends object = any, Config = any, S
726
727
  readonly signal: AbortSignal;
727
728
  rtr: Reactor<T>;
728
729
  config: Config extends object ? Reactive<Config> : Config;
729
- state: State extends object ? Reactive<State> : State;
730
+ readonly state: State extends object ? Reactive<State> : State;
730
731
  constructor(config?: Config, rtr?: Reactor<T>, state?: State);
731
732
  /** Entry point called to initialize plugin wiring. */
732
733
  setup(rtr?: Reactor<T>): void;
@@ -768,13 +769,13 @@ declare class Reactor<T extends object> {
768
769
  protected listeners?: Map<WildPaths<T>, Array<ListenerRecord<T>>>;
769
770
  /**
770
771
  * Creates a new Reactor instance.
771
- * @param object Initial state object.
772
+ * @param target Initial state target.
772
773
  * @param build Reactor bootstrap/build configuration.
773
774
  * @example
774
775
  * const rtr = new Reactor({ count: 0 });
775
776
  */
776
- constructor(object?: T, build?: ReactorBuild<T>);
777
- proxied<O extends object>(obj: O, rejectable?: boolean, indiffable?: boolean, parent?: object, key?: string, path?: string): O;
777
+ constructor(target?: T, build?: ReactorBuild<T>);
778
+ proxied<O extends object>(target: O, rejectable?: boolean, indiffable?: boolean, parent?: object, key?: string, path?: string): O;
778
779
  trace(target: object, path: string, paths?: string[], seen?: WeakSet<object>): Paths<T>[];
779
780
  protected link(target: any, parent: object, key: string, typecheck?: boolean, es?: (object | string)[]): boolean;
780
781
  protected unlink(target: any, parent: object, key: string): void;
@@ -814,7 +815,7 @@ declare class Reactor<T extends object> {
814
815
  getDepth(path: string, depth?: number): number;
815
816
  protected getContext<P extends WildPaths<T>>(path: P): Target<T, P>;
816
817
  protected bindSignal<Cb>(cord: GetterRecord<T> | SetterRecord<T> | DeleterRecord<T> | WatcherRecord<T> | ListenerRecord<T>, sig?: AbortSignal): Cb;
817
- protected cloned(obj: any, raw: boolean, seen?: WeakMap<WeakKey, any>): any;
818
+ protected cloned<O>(target: O, raw: boolean, seen?: WeakMap<WeakKey, any>): O;
818
819
  protected syncAdd<P extends WildPaths<T>>(key: "get" | "set" | "delete" | "watch", path: P, cb: any, opts: SyncOptions | undefined, onImmediate?: (immediate: boolean | "auto") => void): () => boolean | undefined;
819
820
  protected syncDrop<P extends WildPaths<T>>(store: Map<WildPaths<T>, any[]> | undefined, path: P, cb: any): boolean | undefined;
820
821
  /**
@@ -930,7 +931,8 @@ declare class Reactor<T extends object> {
930
931
  * @example
931
932
  * const snap = rtr.snapshot(false, rtr.core.history.past);
932
933
  */
933
- snapshot(raw?: boolean, branch?: T): T;
934
+ snapshot(raw?: boolean): T;
935
+ snapshot<B>(raw?: boolean, branch?: B): B;
934
936
  /**
935
937
  * Cascades object updates into direct child paths.
936
938
  * @param payload Event or payload source.
@@ -1032,6 +1034,8 @@ declare function withTracker<T>(tracker: Autotracker<any>, run: () => T, rtr?: R
1032
1034
 
1033
1035
  /** Global context object for sharing state across the reactor runtime. */
1034
1036
  declare const CTX: {
1037
+ /** Flag indicating whether the application is running in development mode. */
1038
+ isDevEnv: boolean;
1035
1039
  /** active `Autotracker` instance, override for automatic dependency collection on `Reactor` traps. */
1036
1040
  autotracker: Autotracker<any> | null;
1037
1041
  };
@@ -1065,4 +1069,4 @@ declare const NIL: any;
1065
1069
  /** Shared no-operation function. */
1066
1070
  declare const NOOP: () => void;
1067
1071
 
1068
- export { type Payload as $, Autotracker as A, BaseReactorPlugin as B, CTX as C, type DeepKeys as D, type EffectOptions as E, EVT_WARN as F, type Getter as G, type GetterRecord as H, type Inert as I, INDIFFABLE as J, INERTIA as K, type Intent as L, type Listener as M, type ListenerOptions as N, type ListenerOptionsTuple as O, type Paths as P, type ListenerRecord as Q, Reactor as R, type Live as S, NIL as T, NOOP as U, type NoTraverse as V, type WildPaths as W, type PathBranch as X, type PathBranchValue as Y, type PathKey as Z, type PathLeaf as _, type REvent as a, type Primitive as a0, RAW as a1, REJECTABLE as a2, RTR_BATCH as a3, RTR_LOG as a4, type ReactivePreferences as a5, type ReactorBuild as a6, ReactorEvent as a7, SSVERSION as a8, type Setter as a9, stable as aA, state as aB, volatile as aC, type SetterRecord as aa, type Stable as ab, type State as ac, type StrictPathKey as ad, type SyncOptions as ae, type SyncOptionsTuple as af, TERMINATOR as ag, type Target as ah, type Unflatten as ai, type UnionToIntersection as aj, type UpdatePayload as ak, VERSION as al, type Volatile as am, type Watcher as an, type WatcherRecord as ao, getRaw as ap, getSnapshotVersion as aq, getVersion as ar, inert as as, intent as at, isInert as au, isIntent as av, isVolatile as aw, live as ax, methods as ay, reactive as az, type ReactorPluginConstructor as b, canHandle as c, deepClone as d, deleteAny as e, getTrailRecords as f, getAny as g, isObj as h, inAny as i, isPOJO as j, parseEvtOpts as k, type Reactive as l, mergeObjs as m, nuke as n, type PathValue as o, parseAnyObj as p, type ChildPaths as q, type DeepMerge as r, setAny as s, type DeepPartial as t, type DeepRequired as u, type Deleter as v, withTracker as w, type DeleterRecord as x, type DirectPayload as y, EVT_OPTS as z };
1072
+ export { type PathLeaf as $, Autotracker as A, BaseReactorPlugin as B, CTX as C, type DeepKeys as D, type EffectOptions as E, EVT_OPTS as F, EVT_WARN as G, type Getter as H, type Inert as I, type GetterRecord as J, INDIFFABLE as K, INERTIA as L, type Intent as M, type Listener as N, type ListenerOptions as O, type Paths as P, type ListenerOptionsTuple as Q, type Reactive as R, type ListenerRecord as S, type Live as T, NIL as U, NOOP as V, type WildPaths as W, type NoTraverse as X, type PathBranch as Y, type PathBranchValue as Z, type PathKey as _, type REvent as a, type Payload as a0, type Primitive as a1, RAW as a2, REJECTABLE as a3, RTR_BATCH as a4, RTR_LOG as a5, type ReactivePreferences as a6, ReactorEvent as a7, SSVERSION as a8, type Setter as a9, stable as aA, state as aB, volatile as aC, type SetterRecord as aa, type Stable as ab, type State as ac, type StrictPathKey as ad, type SyncOptions as ae, type SyncOptionsTuple as af, TERMINATOR as ag, type Target as ah, type Unflatten as ai, type UnionToIntersection as aj, type UpdatePayload as ak, VERSION as al, type Volatile as am, type Watcher as an, type WatcherRecord as ao, getRaw as ap, getSnapshotVersion as aq, getVersion as ar, inert as as, intent as at, isInert as au, isIntent as av, isVolatile as aw, live as ax, methods as ay, reactive as az, Reactor as b, type ReactorPluginConstructor as c, canHandle as d, deepClone as e, deleteAny as f, getAny as g, getTrailRecords as h, inAny as i, isObj as j, isPOJO as k, parseEvtOpts as l, mergeObjs as m, nuke as n, type ReactorBuild as o, parseAnyObj as p, type PathValue as q, type ChildPaths as r, setAny as s, type DeepMerge as t, type DeepPartial as u, type DeepRequired as v, withTracker as w, type Deleter as x, type DeleterRecord as y, type DirectPayload as z };