sia-reactor 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -50
- package/dist/TimeTravelOverlay-BYSnHBXx.d.cts +41 -0
- package/dist/TimeTravelOverlay-DoNrZwvX.d.ts +41 -0
- package/dist/adapters/react.cjs +289 -55
- package/dist/adapters/react.d.cts +25 -8
- package/dist/adapters/react.d.ts +25 -8
- package/dist/adapters/react.js +55 -28
- package/dist/adapters/vanilla.cjs +1001 -10
- package/dist/adapters/vanilla.d.cts +4 -2
- package/dist/adapters/vanilla.d.ts +4 -2
- package/dist/adapters/vanilla.js +8 -12
- package/dist/chunk-5A44QFT6.js +93 -0
- package/dist/{chunk-4MJUBEI7.js → chunk-DP74DVRT.js} +4 -2
- package/dist/{chunk-UQIMMJTY.js → chunk-P37ADJMM.js} +3 -3
- package/dist/chunk-RFQ2JJSV.js +283 -0
- package/dist/{chunk-Q2AKMIHN.js → chunk-VPR5SP3E.js} +83 -13
- package/dist/{index-JdV5I0R3.d.cts → index-DCG3sacH.d.cts} +14 -19
- package/dist/{index-JdV5I0R3.d.ts → index-DCG3sacH.d.ts} +14 -19
- package/dist/index.cjs +22 -17
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -6
- package/dist/plugins.cjs +32 -28
- package/dist/plugins.d.cts +5 -76
- package/dist/plugins.d.ts +5 -76
- package/dist/plugins.js +10 -12
- package/dist/styles/time-travel-overlay.css +189 -0
- package/dist/super.d.ts +1559 -0
- package/dist/super.global.js +192 -60
- package/dist/timeTravel-Bv_u5M1D.d.ts +75 -0
- package/dist/timeTravel-L8CEhHIo.d.cts +75 -0
- package/dist/utils.cjs +34 -7
- package/dist/utils.d.cts +9 -2
- package/dist/utils.d.ts +9 -2
- package/dist/utils.js +17 -65
- package/package.json +3 -2
- package/dist/chunk-FGUCKMLH.js +0 -154
- 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,22 +126,22 @@ 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
|
|
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
146
|
const reactor = new Reactor({ player: { volume: 50 } }, { debug: true, referenceTracking: true });
|
|
146
147
|
reactor.core.player.volume = 100;
|
|
@@ -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,32 +191,6 @@ 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).
|
|
@@ -269,6 +228,92 @@ const stopTracking = effect(() => {
|
|
|
269
228
|
});
|
|
270
229
|
```
|
|
271
230
|
|
|
231
|
+
### Plugins: The Extension Port
|
|
232
|
+
|
|
233
|
+
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.
|
|
234
|
+
|
|
235
|
+
#### The Persistence Plugin
|
|
236
|
+
Automatically syncs your State to LocalStorage, SessionStorage, Memory or IndexedDB. It respects the async nature of any adapter while keeping your app synchronous.
|
|
237
|
+
|
|
238
|
+
```javascript
|
|
239
|
+
import { reactive, Reactor, getReactor } from 'sia-reactor';
|
|
240
|
+
import { PersistPlugin, LocalStorageAdapter, IndexedDBAdapter } from 'sia-reactor/plugins';
|
|
241
|
+
|
|
242
|
+
const state = reactive({ theme: "dark", settings: { volume: 50, brightness: 30 } });
|
|
243
|
+
state.plugIn(new PersistPlugin({ // Plug it in. State is now automatically hydrated and throttled-saved.
|
|
244
|
+
key: "APP_PREFS",
|
|
245
|
+
paths: ["theme", "settings.brightness"],
|
|
246
|
+
throttle: 5000,
|
|
247
|
+
adapter: new IndexedDBAdapter({ dbName: "Session", version: 1, onversionchange: () => location.reload() }) // or `LocalStorageAdapter` (instance or signature)
|
|
248
|
+
}, getReactor(state))); // Put Reactor as second arg if you want type inference, e.g. for the paths in the array.
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### The Time Travel Plugin
|
|
252
|
+
Record state frames, step through history, and optionally attach a ready-to-use vanilla debug overlay.
|
|
253
|
+
|
|
254
|
+
```javascript
|
|
255
|
+
import { reactive } from 'sia-reactor';
|
|
256
|
+
import { TimeTravelPlugin } from 'sia-reactor/plugins';
|
|
257
|
+
import { TimeTravelOverlay } from 'sia-reactor/adapters/vanilla';
|
|
258
|
+
import 'sia-reactor/css/time-travel-overlay.css';
|
|
259
|
+
|
|
260
|
+
const state = reactive({ count: 0, filter: "all" });
|
|
261
|
+
const time = new TimeTravelPlugin({ maxHistory: 300, loop: false, rate: 150 });
|
|
262
|
+
state.plugIn(time);
|
|
263
|
+
const overlay = new TimeTravelOverlay(time, { color: "#e26e02", startOpen: false, devOnly: true, container: document.body }); // optional debug interface for visulazation
|
|
264
|
+
```
|
|
265
|
+
```jsx
|
|
266
|
+
import { TimeTravelOverlay } from 'sia-reactor/adapters/react';
|
|
267
|
+
|
|
268
|
+
<TimeTravelOverlay time={time} color="#e26e02" startOpen devOnly /> // react-safe instance lifecycle management, e.g. for HMR predictability.
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Useful plugin methods: `play()`, `pause()`, `rewind()`, `clear()`, `undo()`, `redo()`, `step(n, forward)`, `jumpTo(frame)`, `export()`, `import(serialized)`.
|
|
272
|
+
|
|
273
|
+
### Reactor Build Options
|
|
274
|
+
|
|
275
|
+
These are some core build options accepted by `new Reactor(core, build)` and `reactive(core, build, preferences)`.
|
|
276
|
+
|
|
277
|
+
- **`debug?`**: 1-time set. Enables debug logging and diagnostics of core operations. (default: `false`)
|
|
278
|
+
- **`crossRealms?`**: Enables cross-realm object detection support by using slower but safer type checks. (e.g. iframes) (default: `false`).
|
|
279
|
+
- **`smartCloning?`**: Enables structural-sharing snapshot behavior (requires `referenceTracking: true`) (default: `false`).
|
|
280
|
+
- **`eventBubbling?`**: Enables event bubbling across ancestor paths (default: `true`) (default: `true`).
|
|
281
|
+
- **`lineageTracing?`**: Enables path lineage tracing for reference lookups on property access (requires `referenceTracking: true`) (default: `false`).
|
|
282
|
+
- **`preserveContext?`**: Preserves Reflect trap context; safer with ~8x slowdown in hot paths, allows more types to be proxied (e.g. classes) (default: `false`).
|
|
283
|
+
- **`equalityFunction?`**: Custom equality used by setters and adapter comparisons (default: `Object.is`).
|
|
284
|
+
- **`batchingFunction?`**: Custom batching scheduler for listener notification flushes (default: `queueMicrotask`)
|
|
285
|
+
- **`referenceTracking?`**: Enables identity/reference tracking features in the runtime. (default: `false`).
|
|
286
|
+
|
|
287
|
+
*NOTE: those not marked as 1-time set are configurable via `Reactor.config`. Also, plugs and hooks turn on whatever they need automatically.*
|
|
288
|
+
|
|
289
|
+
### Reactive Preferences (Method Naming)
|
|
290
|
+
|
|
291
|
+
`reactive(core, build, preferences)` also accepts method naming preferences so you can expose Reactor APIs with custom names.
|
|
292
|
+
|
|
293
|
+
- **`prefix?`**: Adds a prefix to exposed method names.
|
|
294
|
+
- **`suffix?`**: Adds a suffix to exposed method names.
|
|
295
|
+
- **`whitelist?`**: Keeps specific methods on their original names while others get affixed.
|
|
296
|
+
|
|
297
|
+
```javascript
|
|
298
|
+
import { reactive } from 'sia-reactor';
|
|
299
|
+
|
|
300
|
+
const state = reactive(
|
|
301
|
+
{ count: 0 },
|
|
302
|
+
{ debug: false },
|
|
303
|
+
{
|
|
304
|
+
prefix: '$',
|
|
305
|
+
suffix: 'Now',
|
|
306
|
+
whitelist: ['set', 'get', 'on', 'off'] // keys you're sure won't interfere with your own key names
|
|
307
|
+
}
|
|
308
|
+
);
|
|
309
|
+
// Whitelisted methods keep original names
|
|
310
|
+
state.set('count', (v) => v + 1);
|
|
311
|
+
state.get('count', (v) => v);
|
|
312
|
+
// Non-whitelisted methods are affixed
|
|
313
|
+
state.$watchNow('count', (v) => console.log(v));
|
|
314
|
+
state.$snapshotNow();
|
|
315
|
+
```
|
|
316
|
+
|
|
272
317
|
### Migration: Method API to State/Event Protocol
|
|
273
318
|
|
|
274
319
|
If you are moving from command-style APIs (`play()`, `pause()`, `setVolume(x)`), map them into intent/state flows.
|
|
@@ -333,9 +378,10 @@ The `target` and `currentTarget` objects give you absolute surgical awareness of
|
|
|
333
378
|
```javascript
|
|
334
379
|
{
|
|
335
380
|
path: "user.age", // The full dot-path being accessed
|
|
336
|
-
key: "age", // The specific property key
|
|
337
381
|
value: 26, // The NEW value attempting to be written
|
|
338
382
|
oldValue: 25, // The CURRENT value sitting in memory
|
|
383
|
+
key: "age", // The specific property key
|
|
384
|
+
hadKey: true, // If the key existed on the parent object
|
|
339
385
|
object: { age: 25 } // The actual memory reference of the parent object
|
|
340
386
|
}
|
|
341
387
|
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { R as Reactive } from './index-DCG3sacH.cjs';
|
|
2
|
+
import { T as TimeTravelPlugin } from './timeTravel-L8CEhHIo.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-DCG3sacH.js';
|
|
2
|
+
import { T as TimeTravelPlugin } from './timeTravel-Bv_u5M1D.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 };
|