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
package/README.md CHANGED
@@ -100,7 +100,8 @@ import { setAny, getAny, mergeObjs } from 'sia-reactor/utils';
100
100
  import { reactive, Reactor } from 'sia-reactor';
101
101
  import 'sia-reactor/utils'; // deep object helpers (setAny/getAny/mergeObjs/...)
102
102
  import 'sia-reactor/plugins'; // built-in plugins + storage adapters
103
- import 'sia-reactor/adapters/vanilla'; // Autotracker + effect API
103
+ import 'sia-reactor/adapters/vanilla'; // Autotracker + effect API + TimeTravelOverlay class
104
+ import 'sia-reactor/adapters/vanilla/time-travel-overlay.css'; // TimeTravelOverlay CSS
104
105
  import 'sia-reactor/adapters/react'; // useReactor/useSelector/usePath hooks
105
106
  ```
106
107
 
@@ -125,25 +126,25 @@ import 'sia-reactor/adapters/react'; // useReactor/useSelector/usePath hooks
125
126
 
126
127
  ### Initialization (`reactive` & `Reactor`)
127
128
 
128
- The primary way to use the reactor is to wrap an object using `reactive()`, which directly mixes the reactor methods into your target object for a pristine, flat API.
129
+ The primary way to use the reactor is to wrap an object using `reactive(target, build, preferences)`, which directly mixes the reactor methods into your target object for a pristine, flat API.
129
130
 
130
131
  *NOTE: `.` and `*` are engine reserved so don't use them as object keys*
131
132
 
132
133
  ```javascript
133
134
  const state = reactive({ player: { volume: 50 } }, { smartCloning: true, referenceTracking: true });
134
135
 
135
- // Methods are attached directly to the object with `reactive()`!
136
+ // Public API Methods are attached directly to the object with `reactive()`!
136
137
  state.set("player.volume", (val) => Math.min(val, 100));
137
138
  state.on("player.volume", (e) => console.log(e.value));
138
139
 
139
140
  state.player.volume = 150; // Triggers mediation, clamps to 100, fires listener.
140
- state.__Reactor__ // Reference to the underlying reactor
141
+ getReactor(state); state.__Reactor__; // Reference to the underlying reactor
141
142
  ```
142
143
 
143
- Alternatively, you can instantiate the `Reactor` class directly to keep the API separate from your data:
144
+ Alternatively, you can instantiate the `Reactor` class directly to keep the API from interfering with your data or [try this](#reactive-preferences-method-naming):
144
145
  ```javascript
145
- const reactor = new Reactor({ player: { volume: 50 } }, { debug: true, referenceTracking: true });
146
- reactor.core.player.volume = 100;
146
+ const reactor = new Reactor({ player: { volume: 50 } }, { debug: true });
147
+ reactor.core.player.volume = 100; // re-assign core if desired
147
148
  ```
148
149
 
149
150
  ### Core Methods
@@ -166,27 +167,11 @@ All methods are available on `Reactor` instances or objects wrapped in `reactive
166
167
  #### **Lifecycle & Utilities**
167
168
  - **`tick(path)`**: Forces a synchronous flush of the batch queue for a specific path.
168
169
  - **`stall(task)` / `nostall(task)`**: Manually stall the queue to wait for calculations before rendering.
169
- - **`cascade(eventOrPayload, objectSafe)`**: Manually trigger deep-object event waves, bypassing strict unchanged-proxy traps. Perfect for dumping massive API payloads into the tree, `objectSafe` merges `value` with `oldValue`.
170
170
  - **`snapshot(raw)`**: Generates a strict, structurally-shared, un-proxied clone of the current state tree.
171
+ - **`cascade(eventOrPayload, objectSafe)`**: Manually trigger direct object values event waves, bypassing strict unchanged-proxy traps, `objectSafe` merges `value` with `oldValue`.
171
172
  - **`plugIn(new ReactorPlugin(config))`**: Allows extended behaviour with external logic.
172
173
  - **`reset()`**: Clears all records bringing everything back to a clean slate.
173
- - **`destroy()`**: Last resort destruction, nukes everything by nullifying it's properties for full disposal.
174
-
175
- ### Reactor Build Options
176
-
177
- These are some core build options accepted by `new Reactor(core, build)` and `reactive(core, build)`.
178
-
179
- - **`debug`**: 1-time set. Enables debug logging and diagnostics of core operations. (default: `false`)
180
- - **`crossRealms`**: Enables cross-realm object detection support by using slower but safer type checks. (e.g. iframes) (default: `false`).
181
- - **`smartCloning`**: Enables structural-sharing snapshot behavior (requires `referenceTracking: true`) (default: `false`).
182
- - **`eventBubbling`**: Enables event bubbling across ancestor paths (default: `true`) (default: `true`).
183
- - **`lineageTracing`**: Enables path lineage tracing for reference lookups on property access (requires `referenceTracking: true`) (default: `false`).
184
- - **`preserveContext`**: Preserves Reflect trap context; safer with ~8x slowdown in hot paths, allows more types to be proxied (e.g. classes) (default: `false`).
185
- - **`equalityFunction`**: Custom equality used by setters and adapter comparisons (default: `Object.is`).
186
- - **`batchingFunction`**: Custom batching scheduler for listener notification flushes (default: `queueMicrotask`)
187
- - **`referenceTracking`**: Enables identity/reference tracking features in the runtime. (default: `false`).
188
-
189
- *NOTE: those not marked as 1-time set are configurable via `Reactor.config`.*
174
+ - **`destroy()`**: Last resort destruction, nukes everything by nullifying it's properties for full disposal, lives on every class.
190
175
 
191
176
  ### Memory & Granular Control Flags
192
177
 
@@ -206,45 +191,19 @@ const data = reactive({
206
191
  });
207
192
  ```
208
193
 
209
- ### Plugins: The Extension Port
210
-
211
- The `Reactor` is designed to be a lightweight core. Extended capabilities are attached via Plugins. It ships with a suite of built-in plugins for common architectural needs. like a Persist and TimeTravel plugin.
212
-
213
- #### The Persistence Plugin
214
- Automatically syncs your State to LocalStorage, SessionStorage, Memory or IndexedDB. It respects the async nature of IDB while keeping your app synchronous.
215
-
216
- ```javascript
217
- import { reactive, Reactor } from 'sia-reactor';
218
- import { PersistPlugin, LocalStorageAdapter, IndexedDBAdapter } from 'sia-reactor/plugins';
219
-
220
- const state = reactive({ theme: "dark", volume: 50 });
221
- state.__Reactor__.plugIn(new PersistPlugin({
222
- key: "APP_PREFS",
223
- throttle: 5000,
224
- adapter: LocalStorageAdapter
225
- }); // Plug it in. State is now automatically hydrated and throttled-saved.
226
-
227
- const reactor = new Reactor({ theme: "dark", settings: { volume: 50, brightness: 30 } });
228
- reactor.plugIn(new PersistPlugin({
229
- key: "APP_PREFS",
230
- paths: ["theme", "settings.brightness"],
231
- adapter: new IndexedDBAdapter({ dbName: "Session", version: 1, onversionchange: () => location.reload() })
232
- }, reactor)); // Put Reactor as second arg if you want type inference, e.g. for the paths in the array.
233
- ```
234
-
235
194
  ### React Hooks & Effects
236
195
 
237
196
  The engine provides native React bindings utilizing `useSyncExternalStore` and an internal `Autotracker` for concurrent-safe, surgically precise component re-renders. All hooks natively accept a `Reactor` instance, a `reactive()` proxy, or a plain object (which will be auto-wrapped on the fly).
238
197
 
239
198
  ```javascript
240
199
  import { reactive } from 'sia-reactor';
241
- import { useReactor, useSelector, usePath, effect } from 'sia-reactor/react';
200
+ import { useReactor, useAnyReactor, useSelector, useAnySelector, usePath, effect } from 'sia-reactor/react';
242
201
 
243
202
  const state = reactive({ user: { name: "Ada", age: 25 }, theme: "dark" });
244
203
 
245
204
  // 1. The Tracked State (Valtio-style)
246
205
  function Profile() {
247
- const sameState = useReactor(state); // pass in a normal object for an auto-scoped instance
206
+ const sameState = useReactor(state); // `useReactorSnapshot()` if mutable issues arise
248
207
  useAnyReactor(); // use this when you just want to use any state from any reactor
249
208
  // Only re-renders if state.user.name mutates. Completely ignores age and theme!
250
209
  return <div>{sameState.user.name + otherState.user.name}</div>;
@@ -252,7 +211,7 @@ function Profile() {
252
211
 
253
212
  // 2. The Slice Selector (Zustand-style)
254
213
  function Theme() {
255
- const theme = useSelector(state, (s) => s.theme); // pass in a normal object for an auto-scoped instance
214
+ const theme = useSelector(state, (s) => s.theme); // `useSelectorSnapshot()` if mutable issues arise
256
215
  const newName = useAnySelector(() => state.user.name + spouseState.user.name); // use this when you just want to derive any state from any reactor
257
216
  return <div>Theme: {theme}</div>;
258
217
  }
@@ -264,9 +223,93 @@ function AgeObserver() {
264
223
  }
265
224
 
266
225
  // 4. Vanilla Side Effects (Runs anywhere, framework agnostic)
267
- const stopTracking = effect(() => {
268
- console.log("User name changed to:", state.user.name);
269
- });
226
+ const stopTracking = effect(() => console.log("User name changed to:", state.user.name)); // read or write as you wish
227
+ ```
228
+
229
+ ### Plugins: The Extension Port
230
+
231
+ The `Reactor` is designed to be a lightweight core. Extended capabilities are attached via Plugins. It ships with a suite of built-in plugins for common architectural needs.
232
+
233
+ #### The Persistence Plugin
234
+ Automatically syncs your State to LocalStorage, SessionStorage, Memory or IndexedDB. It respects the async nature of any adapter while keeping your app synchronous.
235
+
236
+ ```javascript
237
+ import { reactive, Reactor, getReactor } from 'sia-reactor';
238
+ import { PersistPlugin, LocalStorageAdapter, IndexedDBAdapter } from 'sia-reactor/plugins';
239
+
240
+ const state = reactive({ theme: "dark", settings: { volume: 50, brightness: 30 } });
241
+ state.plugIn(new PersistPlugin({ // Plug it in. State is now automatically hydrated and throttled-saved.
242
+ key: "APP_PREFS",
243
+ paths: ["theme", "settings.brightness"],
244
+ throttle: 5000,
245
+ adapter: new IndexedDBAdapter({ dbName: "Session", version: 1, onversionchange: () => location.reload() }) // or `LocalStorageAdapter` (instance or signature)
246
+ }, getReactor(state))); // Put Reactor as second arg if you want type inference, e.g. for the paths in the array.
247
+ ```
248
+
249
+ #### The Time Travel Plugin
250
+ Record state frames, step through history, and optionally attach a ready-to-use vanilla debug overlay.
251
+
252
+ ```javascript
253
+ import { reactive } from 'sia-reactor';
254
+ import { TimeTravelPlugin } from 'sia-reactor/plugins';
255
+ import { TimeTravelOverlay } from 'sia-reactor/adapters/vanilla';
256
+ import 'sia-reactor/css/time-travel-overlay.css';
257
+
258
+ const state = reactive({ count: 0, filter: "all" });
259
+ const time = new TimeTravelPlugin({ maxHistory: 300, loop: false, rate: 150 });
260
+ state.plugIn(time);
261
+ const overlay = new TimeTravelOverlay(time, { color: "#e26e02", startOpen: false, devOnly: true, container: document.body }); // optional debug interface for visulazation
262
+ ```
263
+ ```jsx
264
+ import { TimeTravelOverlay } from 'sia-reactor/adapters/react';
265
+
266
+ <TimeTravelOverlay time={time} color="#e26e02" startOpen devOnly /> // react-safe instance lifecycle management, e.g. for HMR predictability.
267
+ ```
268
+
269
+ Useful plugin methods: `play()`, `pause()`, `rewind()`, `clear()`, `undo()`, `redo()`, `step(n, forward)`, `jumpTo(frame)`, `export()`, `import(serialized)`.
270
+
271
+ ### Reactor Build Options
272
+
273
+ These are some core build options accepted by `new Reactor(core, build)` and `reactive(core, build, preferences)`.
274
+
275
+ - **`debug?`**: 1-time set. Enables debug logging and diagnostics of core operations. (default: `false`)
276
+ - **`crossRealms?`**: Enables cross-realm object detection support by using slower but safer type checks. (e.g. iframes) (default: `false`).
277
+ - **`smartCloning?`**: Enables structural-sharing snapshot behavior (requires `referenceTracking: true`) (default: `false`).
278
+ - **`eventBubbling?`**: Enables event bubbling across ancestor paths (default: `true`) (default: `true`).
279
+ - **`lineageTracing?`**: Enables path lineage tracing for reference lookups on property access (requires `referenceTracking: true`) (default: `false`).
280
+ - **`preserveContext?`**: Preserves Reflect trap context; safer with ~8x slowdown in hot paths, allows more types to be proxied (e.g. classes) (default: `false`).
281
+ - **`equalityFunction?`**: Custom equality used by setters and adapter comparisons (default: `Object.is`).
282
+ - **`batchingFunction?`**: Custom batching scheduler for listener notification flushes (default: `queueMicrotask`)
283
+ - **`referenceTracking?`**: Enables identity/reference tracking features in the runtime. (default: `false`).
284
+
285
+ *NOTE: those not marked as 1-time set are configurable via `Reactor.config`. Also, plugs and hooks turn on whatever they need automatically.*
286
+
287
+ ### Reactive Preferences (Method Naming)
288
+
289
+ `reactive(core, build, preferences)` also accepts method naming preferences so you can expose Reactor APIs with custom names.
290
+
291
+ - **`prefix?`**: Adds a prefix to exposed method names.
292
+ - **`suffix?`**: Adds a suffix to exposed method names.
293
+ - **`whitelist?`**: Keeps specific methods on their original names while others get affixed.
294
+
295
+ ```javascript
296
+ import { reactive } from 'sia-reactor';
297
+
298
+ const state = reactive(
299
+ { count: 0 },
300
+ { debug: false },
301
+ {
302
+ prefix: '$',
303
+ suffix: 'Now',
304
+ whitelist: ['set', 'get', 'on', 'off'] // keys you're sure won't interfere with your own key names
305
+ }
306
+ );
307
+ // Whitelisted methods keep original names
308
+ state.set('count', (v) => v + 1);
309
+ state.get('count', (v) => v);
310
+ // Non-whitelisted methods are affixed
311
+ state.$watchNow('count', (v) => console.log(v));
312
+ state.$snapshotNow();
270
313
  ```
271
314
 
272
315
  ### Migration: Method API to State/Event Protocol
@@ -333,9 +376,10 @@ The `target` and `currentTarget` objects give you absolute surgical awareness of
333
376
  ```javascript
334
377
  {
335
378
  path: "user.age", // The full dot-path being accessed
336
- key: "age", // The specific property key
337
379
  value: 26, // The NEW value attempting to be written
338
380
  oldValue: 25, // The CURRENT value sitting in memory
381
+ key: "age", // The specific property key
382
+ hadKey: true, // If the key existed on the parent object
339
383
  object: { age: 25 } // The actual memory reference of the parent object
340
384
  }
341
385
  ```
@@ -0,0 +1,41 @@
1
+ import { R as Reactive } from './index-Oie9hhE8.cjs';
2
+ import { T as TimeTravelPlugin } from './timeTravel-WpgWmKu-.cjs';
3
+
4
+ /** Reactive options for the TimeTravel overlay instance. */
5
+ interface TimeTravelConfig {
6
+ /** Header text shown at the top of the overlay panel. */
7
+ title: string;
8
+ /** Accent color used to derive panel theme variables. */
9
+ color: string;
10
+ /** Shows the overlay only in development when true. */
11
+ devOnly: boolean;
12
+ /** Initial open state applied when the overlay is created. */
13
+ startOpen: boolean;
14
+ /** Container element that owns the overlay layer and dock. */
15
+ container: HTMLElement;
16
+ }
17
+ /** Vanilla overlay controller for visual time-travel controls and timeline I/O.
18
+ * Mounts a docked HUD into the configured container, syncs its UI with plugin state, and forwards keyboard/button actions to the TimeTravelPlugin.
19
+ * Supports reactive `config` updates (title/color/container/devOnly) and maintains local overlay UI state (`open` and `import` payload text).
20
+ */
21
+ declare class TimeTravelOverlay {
22
+ static count: number;
23
+ index: number;
24
+ config: TimeTravelConfig;
25
+ readonly state: Reactive<{
26
+ open: boolean;
27
+ import: string;
28
+ }, undefined>;
29
+ readonly time: TimeTravelPlugin;
30
+ readonly els: Record<string, HTMLElement>;
31
+ private clups;
32
+ private keyup?;
33
+ /** Creates a docked TimeTravel overlay bound to a plugin instance.
34
+ * @param time TimeTravel plugin instance that owns timeline operations.
35
+ * @param build Optional initial overlay config overrides.
36
+ */
37
+ constructor(time: TimeTravelPlugin, build?: Partial<TimeTravelConfig>);
38
+ destroy(): void;
39
+ }
40
+
41
+ export { type TimeTravelConfig as T, TimeTravelOverlay as a };
@@ -0,0 +1,41 @@
1
+ import { R as Reactive } from './index-Oie9hhE8.js';
2
+ import { T as TimeTravelPlugin } from './timeTravel-B1vedDQc.js';
3
+
4
+ /** Reactive options for the TimeTravel overlay instance. */
5
+ interface TimeTravelConfig {
6
+ /** Header text shown at the top of the overlay panel. */
7
+ title: string;
8
+ /** Accent color used to derive panel theme variables. */
9
+ color: string;
10
+ /** Shows the overlay only in development when true. */
11
+ devOnly: boolean;
12
+ /** Initial open state applied when the overlay is created. */
13
+ startOpen: boolean;
14
+ /** Container element that owns the overlay layer and dock. */
15
+ container: HTMLElement;
16
+ }
17
+ /** Vanilla overlay controller for visual time-travel controls and timeline I/O.
18
+ * Mounts a docked HUD into the configured container, syncs its UI with plugin state, and forwards keyboard/button actions to the TimeTravelPlugin.
19
+ * Supports reactive `config` updates (title/color/container/devOnly) and maintains local overlay UI state (`open` and `import` payload text).
20
+ */
21
+ declare class TimeTravelOverlay {
22
+ static count: number;
23
+ index: number;
24
+ config: TimeTravelConfig;
25
+ readonly state: Reactive<{
26
+ open: boolean;
27
+ import: string;
28
+ }, undefined>;
29
+ readonly time: TimeTravelPlugin;
30
+ readonly els: Record<string, HTMLElement>;
31
+ private clups;
32
+ private keyup?;
33
+ /** Creates a docked TimeTravel overlay bound to a plugin instance.
34
+ * @param time TimeTravel plugin instance that owns timeline operations.
35
+ * @param build Optional initial overlay config overrides.
36
+ */
37
+ constructor(time: TimeTravelPlugin, build?: Partial<TimeTravelConfig>);
38
+ destroy(): void;
39
+ }
40
+
41
+ export { type TimeTravelConfig as T, TimeTravelOverlay as a };