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
@@ -1,8 +1,7 @@
1
+ import { E as EffectOptions, b as Reactor, R as Reactive, o as ReactorBuild, W as WildPaths, q as PathValue } from '../index-Oie9hhE8.cjs';
1
2
  import { useLayoutEffect } from 'react';
2
- import { E as EffectOptions, R as Reactor, l as Reactive, W as WildPaths, o as PathValue } from '../index-C2hyIh0K.cjs';
3
-
4
- /** Isomorphic layout effect alias (`useLayoutEffect` in browser, `useEffect` otherwise). */
5
- declare const useISOLayoutEffect: typeof useLayoutEffect;
3
+ import { T as TimeTravelPlugin } from '../timeTravel-WpgWmKu-.cjs';
4
+ import { T as TimeTravelConfig } from '../TimeTravelOverlay-CJv-S_Km.cjs';
6
5
 
7
6
  /**
8
7
  * Subscribes a component to desired Reactor state and returns it.
@@ -10,9 +9,10 @@ declare const useISOLayoutEffect: typeof useLayoutEffect;
10
9
  * @typeParam T Root state object type.
11
10
  * @param target Reactive object, Reactor instance, or plain object.
12
11
  * @param options Watcher options if `options.sync: false` else Listener options.
12
+ * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
13
13
  * @returns State for render usage if state is scoped locally or just desired.
14
14
  * @example
15
- * const a = useReactor({ user: { name: "Ada" } });
15
+ * const a = useReactor({ user: { name: "Ada" } }); // per-component scoped
16
16
  * @example
17
17
  * const state = reactive({ user: { name: "Ada" } });
18
18
  * const b = useReactor(state);
@@ -20,7 +20,7 @@ declare const useISOLayoutEffect: typeof useLayoutEffect;
20
20
  * const rtr = new Reactor({ user: { name: "Ada" } });
21
21
  * const c = useReactor(rtr);
22
22
  */
23
- declare function useReactor<T extends object>(target: T | Reactor<T> | Reactive<T>, options?: EffectOptions): T;
23
+ declare function useReactor<T extends object>(target: T | Reactor<T> | Reactive<T>, options?: EffectOptions, build?: ReactorBuild<T>): T;
24
24
  /**
25
25
  * Subscribes a component to any Reactor state.
26
26
  * The hook uses access tracking so re-renders occur only when accessed fields change.
@@ -29,6 +29,25 @@ declare function useReactor<T extends object>(target: T | Reactor<T> | Reactive<
29
29
  * useAnyReactor();
30
30
  */
31
31
  declare function useAnyReactor(options?: EffectOptions): void;
32
+ /**
33
+ * Subscribes a component to Reactor state and returns a tracked snapshot.
34
+ * Rule of thumb: read from snapshots, mutate the source.
35
+ * The hook uses access tracking so re-renders occur only when accessed fields change.
36
+ * @typeParam T Root state object type.
37
+ * @param target Reactive object, Reactor instance, or plain object.
38
+ * @param options Watcher options if `options.sync: false` else Listener options.
39
+ * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
40
+ * @returns Tracked snapshot snap for render usage.
41
+ * @example
42
+ * const a = useReactorSnapshot({ user: { name: "Ada" } }); // per-component scoped
43
+ * @example
44
+ * const state = reactive({ user: { name: "Ada" } });
45
+ * const b = useReactorSnapshot(state);
46
+ * @example
47
+ * const rtr = new Reactor({ user: { name: "Ada" } });
48
+ * const c = useReactorSnapshot(rtr);
49
+ */
50
+ declare function useReactorSnapshot<T extends object>(target: T | Reactor<T> | Reactive<T>, options?: EffectOptions, build?: ReactorBuild<T>): T;
32
51
 
33
52
  /**
34
53
  * Subscribes to a derived slice of Reactor state.
@@ -40,9 +59,10 @@ declare function useAnyReactor(options?: EffectOptions): void;
40
59
  * @param sel Slice selector.
41
60
  * @param eq Equality function used to compare consecutive selector results.
42
61
  * @param options Watcher options if `options.sync: false` else Listener options.
62
+ * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
43
63
  * @returns The selected slice.
44
64
  * @example
45
- * const a = useSelector({ user: { name: "Ada" } }, (s) => s.user.name);
65
+ * const a = useSelector({ user: { name: "Ada" } }, (s) => s.user.name); // per-component scoped
46
66
  * @example
47
67
  * const state = reactive({ user: { name: "Ada" } });
48
68
  * const b = useSelector(state, (s) => s.user.name);
@@ -50,7 +70,7 @@ declare function useAnyReactor(options?: EffectOptions): void;
50
70
  * const rtr = new Reactor({ user: { name: "Ada" } });
51
71
  * const c = useSelector(rtr, (s) => s.user.name);
52
72
  */
53
- declare function useSelector<T extends object, R>(target: T | Reactor<T> | Reactive<T>, sel: (state: T) => R, eq?: (value1: any, value2: any) => boolean, options?: EffectOptions): R;
73
+ declare function useSelector<T extends object, R>(target: T | Reactor<T> | Reactive<T>, sel: (state: T) => R, eq?: (prev: R | undefined, next: R) => boolean, options?: EffectOptions, build?: ReactorBuild<T>): R;
54
74
  /**
55
75
  * Subscribes to a derived slice of any Reactor state.
56
76
  * The selector runs against the live state and uses the provided equality function
@@ -62,6 +82,28 @@ declare function useSelector<T extends object, R>(target: T | Reactor<T> | React
62
82
  * @returns The selected slice.
63
83
  */
64
84
  declare function useAnySelector<R>(sel: () => R, eq?: (value1: any, value2: any) => boolean, options?: EffectOptions): R;
85
+ /**
86
+ * Subscribes to a derived slice of Reactor state.
87
+ * The selector runs against a tracked snapshot and uses the provided equality function
88
+ * to suppress unchanged results.
89
+ * @typeParam T Root state object type.
90
+ * @typeParam R Selector return type.
91
+ * @param target Reactive object, Reactor instance, or plain object.
92
+ * @param sel Slice selector.
93
+ * @param eq Equality function used to compare consecutive selector results.
94
+ * @param options Watcher options if `options.sync: false` else Listener options.
95
+ * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
96
+ * @returns The selected slice.
97
+ * @example
98
+ * const a = useSelectorSnapshot({ user: { name: "Ada" } }, (s) => s.user.name); // per-component scoped
99
+ * @example
100
+ * const state = reactive({ user: { name: "Ada" } });
101
+ * const b = useSelectorSnapshot(state, (s) => s.user.name);
102
+ * @example
103
+ * const rtr = new Reactor({ user: { name: "Ada" } });
104
+ * const c = useSelectorSnapshot(rtr, (s) => s.user.name);
105
+ */
106
+ declare function useSelectorSnapshot<T extends object, R>(target: T | Reactor<T> | Reactive<T>, sel: (state: T) => R, eq?: (value1: any, value2: any) => boolean, options?: EffectOptions, build?: ReactorBuild<T>): R;
65
107
 
66
108
  /**
67
109
  * Subscribes to a single path in Reactor state.
@@ -71,6 +113,7 @@ declare function useAnySelector<R>(sel: () => R, eq?: (value1: any, value2: any)
71
113
  * @param target Reactive object, Reactor instance, or plain object.
72
114
  * @param path Path to observe. Supports dotted paths and wildcard `"*"`.
73
115
  * @param options Watcher options if `options.sync: false` else Listener options.
116
+ * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
74
117
  * @returns Current value at the requested path.
75
118
  * @example
76
119
  * const a = usePath({ user: { profile: { name: "Ada" } } }, "user.profile.name");
@@ -83,6 +126,21 @@ declare function useAnySelector<R>(sel: () => R, eq?: (value1: any, value2: any)
83
126
  * @example
84
127
  * const wholeState = usePath(state, "*");
85
128
  */
86
- declare function usePath<T extends object, P extends WildPaths<T>>(target: T | Reactor<T> | Reactive<T>, path: P, options?: EffectOptions): PathValue<T, P>;
129
+ declare function usePath<T extends object, P extends WildPaths<T>>(target: T | Reactor<T> | Reactive<T>, path: P, options?: EffectOptions, build?: ReactorBuild<T>): PathValue<T, P>;
130
+
131
+ /** Isomorphic layout effect alias (`useLayoutEffect` in browser, `useEffect` otherwise). */
132
+ declare const useISOLayoutEffect: typeof useLayoutEffect;
133
+
134
+ /** React props for controlling the vanilla TimeTravel overlay. */
135
+ interface TimeTravelOverlayProps extends Partial<TimeTravelConfig> {
136
+ /** Plugin instance controlled by this overlay bridge. */
137
+ time: TimeTravelPlugin;
138
+ }
139
+ /** React bridge for mounting and controlling a vanilla TimeTravelOverlay instance.
140
+ * Instantiates a `TimeTravelOverlay` for the provided plugin, tears it down on unmount, and syncs prop changes into reactive `config`.
141
+ * Use this when your app is React but you want the overlay behavior with react-safe instance lifecycle management.
142
+ * @param props Overlay bridge props.
143
+ */
144
+ declare function TimeTravelOverlay(props: TimeTravelOverlayProps): null;
87
145
 
88
- export { useAnyReactor, useAnySelector, useISOLayoutEffect, usePath, useReactor, useSelector };
146
+ export { TimeTravelOverlay, type TimeTravelOverlayProps, useAnyReactor, useAnySelector, useISOLayoutEffect, usePath, useReactor, useReactorSnapshot, useSelector, useSelectorSnapshot };
@@ -1,8 +1,7 @@
1
+ import { E as EffectOptions, b as Reactor, R as Reactive, o as ReactorBuild, W as WildPaths, q as PathValue } from '../index-Oie9hhE8.js';
1
2
  import { useLayoutEffect } from 'react';
2
- import { E as EffectOptions, R as Reactor, l as Reactive, W as WildPaths, o as PathValue } from '../index-C2hyIh0K.js';
3
-
4
- /** Isomorphic layout effect alias (`useLayoutEffect` in browser, `useEffect` otherwise). */
5
- declare const useISOLayoutEffect: typeof useLayoutEffect;
3
+ import { T as TimeTravelPlugin } from '../timeTravel-B1vedDQc.js';
4
+ import { T as TimeTravelConfig } from '../TimeTravelOverlay-DxqJL0Zk.js';
6
5
 
7
6
  /**
8
7
  * Subscribes a component to desired Reactor state and returns it.
@@ -10,9 +9,10 @@ declare const useISOLayoutEffect: typeof useLayoutEffect;
10
9
  * @typeParam T Root state object type.
11
10
  * @param target Reactive object, Reactor instance, or plain object.
12
11
  * @param options Watcher options if `options.sync: false` else Listener options.
12
+ * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
13
13
  * @returns State for render usage if state is scoped locally or just desired.
14
14
  * @example
15
- * const a = useReactor({ user: { name: "Ada" } });
15
+ * const a = useReactor({ user: { name: "Ada" } }); // per-component scoped
16
16
  * @example
17
17
  * const state = reactive({ user: { name: "Ada" } });
18
18
  * const b = useReactor(state);
@@ -20,7 +20,7 @@ declare const useISOLayoutEffect: typeof useLayoutEffect;
20
20
  * const rtr = new Reactor({ user: { name: "Ada" } });
21
21
  * const c = useReactor(rtr);
22
22
  */
23
- declare function useReactor<T extends object>(target: T | Reactor<T> | Reactive<T>, options?: EffectOptions): T;
23
+ declare function useReactor<T extends object>(target: T | Reactor<T> | Reactive<T>, options?: EffectOptions, build?: ReactorBuild<T>): T;
24
24
  /**
25
25
  * Subscribes a component to any Reactor state.
26
26
  * The hook uses access tracking so re-renders occur only when accessed fields change.
@@ -29,6 +29,25 @@ declare function useReactor<T extends object>(target: T | Reactor<T> | Reactive<
29
29
  * useAnyReactor();
30
30
  */
31
31
  declare function useAnyReactor(options?: EffectOptions): void;
32
+ /**
33
+ * Subscribes a component to Reactor state and returns a tracked snapshot.
34
+ * Rule of thumb: read from snapshots, mutate the source.
35
+ * The hook uses access tracking so re-renders occur only when accessed fields change.
36
+ * @typeParam T Root state object type.
37
+ * @param target Reactive object, Reactor instance, or plain object.
38
+ * @param options Watcher options if `options.sync: false` else Listener options.
39
+ * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
40
+ * @returns Tracked snapshot snap for render usage.
41
+ * @example
42
+ * const a = useReactorSnapshot({ user: { name: "Ada" } }); // per-component scoped
43
+ * @example
44
+ * const state = reactive({ user: { name: "Ada" } });
45
+ * const b = useReactorSnapshot(state);
46
+ * @example
47
+ * const rtr = new Reactor({ user: { name: "Ada" } });
48
+ * const c = useReactorSnapshot(rtr);
49
+ */
50
+ declare function useReactorSnapshot<T extends object>(target: T | Reactor<T> | Reactive<T>, options?: EffectOptions, build?: ReactorBuild<T>): T;
32
51
 
33
52
  /**
34
53
  * Subscribes to a derived slice of Reactor state.
@@ -40,9 +59,10 @@ declare function useAnyReactor(options?: EffectOptions): void;
40
59
  * @param sel Slice selector.
41
60
  * @param eq Equality function used to compare consecutive selector results.
42
61
  * @param options Watcher options if `options.sync: false` else Listener options.
62
+ * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
43
63
  * @returns The selected slice.
44
64
  * @example
45
- * const a = useSelector({ user: { name: "Ada" } }, (s) => s.user.name);
65
+ * const a = useSelector({ user: { name: "Ada" } }, (s) => s.user.name); // per-component scoped
46
66
  * @example
47
67
  * const state = reactive({ user: { name: "Ada" } });
48
68
  * const b = useSelector(state, (s) => s.user.name);
@@ -50,7 +70,7 @@ declare function useAnyReactor(options?: EffectOptions): void;
50
70
  * const rtr = new Reactor({ user: { name: "Ada" } });
51
71
  * const c = useSelector(rtr, (s) => s.user.name);
52
72
  */
53
- declare function useSelector<T extends object, R>(target: T | Reactor<T> | Reactive<T>, sel: (state: T) => R, eq?: (value1: any, value2: any) => boolean, options?: EffectOptions): R;
73
+ declare function useSelector<T extends object, R>(target: T | Reactor<T> | Reactive<T>, sel: (state: T) => R, eq?: (prev: R | undefined, next: R) => boolean, options?: EffectOptions, build?: ReactorBuild<T>): R;
54
74
  /**
55
75
  * Subscribes to a derived slice of any Reactor state.
56
76
  * The selector runs against the live state and uses the provided equality function
@@ -62,6 +82,28 @@ declare function useSelector<T extends object, R>(target: T | Reactor<T> | React
62
82
  * @returns The selected slice.
63
83
  */
64
84
  declare function useAnySelector<R>(sel: () => R, eq?: (value1: any, value2: any) => boolean, options?: EffectOptions): R;
85
+ /**
86
+ * Subscribes to a derived slice of Reactor state.
87
+ * The selector runs against a tracked snapshot and uses the provided equality function
88
+ * to suppress unchanged results.
89
+ * @typeParam T Root state object type.
90
+ * @typeParam R Selector return type.
91
+ * @param target Reactive object, Reactor instance, or plain object.
92
+ * @param sel Slice selector.
93
+ * @param eq Equality function used to compare consecutive selector results.
94
+ * @param options Watcher options if `options.sync: false` else Listener options.
95
+ * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
96
+ * @returns The selected slice.
97
+ * @example
98
+ * const a = useSelectorSnapshot({ user: { name: "Ada" } }, (s) => s.user.name); // per-component scoped
99
+ * @example
100
+ * const state = reactive({ user: { name: "Ada" } });
101
+ * const b = useSelectorSnapshot(state, (s) => s.user.name);
102
+ * @example
103
+ * const rtr = new Reactor({ user: { name: "Ada" } });
104
+ * const c = useSelectorSnapshot(rtr, (s) => s.user.name);
105
+ */
106
+ declare function useSelectorSnapshot<T extends object, R>(target: T | Reactor<T> | Reactive<T>, sel: (state: T) => R, eq?: (value1: any, value2: any) => boolean, options?: EffectOptions, build?: ReactorBuild<T>): R;
65
107
 
66
108
  /**
67
109
  * Subscribes to a single path in Reactor state.
@@ -71,6 +113,7 @@ declare function useAnySelector<R>(sel: () => R, eq?: (value1: any, value2: any)
71
113
  * @param target Reactive object, Reactor instance, or plain object.
72
114
  * @param path Path to observe. Supports dotted paths and wildcard `"*"`.
73
115
  * @param options Watcher options if `options.sync: false` else Listener options.
116
+ * @param build Optional Reactor build options used when creating a scoped Reactor for plain objects.
74
117
  * @returns Current value at the requested path.
75
118
  * @example
76
119
  * const a = usePath({ user: { profile: { name: "Ada" } } }, "user.profile.name");
@@ -83,6 +126,21 @@ declare function useAnySelector<R>(sel: () => R, eq?: (value1: any, value2: any)
83
126
  * @example
84
127
  * const wholeState = usePath(state, "*");
85
128
  */
86
- declare function usePath<T extends object, P extends WildPaths<T>>(target: T | Reactor<T> | Reactive<T>, path: P, options?: EffectOptions): PathValue<T, P>;
129
+ declare function usePath<T extends object, P extends WildPaths<T>>(target: T | Reactor<T> | Reactive<T>, path: P, options?: EffectOptions, build?: ReactorBuild<T>): PathValue<T, P>;
130
+
131
+ /** Isomorphic layout effect alias (`useLayoutEffect` in browser, `useEffect` otherwise). */
132
+ declare const useISOLayoutEffect: typeof useLayoutEffect;
133
+
134
+ /** React props for controlling the vanilla TimeTravel overlay. */
135
+ interface TimeTravelOverlayProps extends Partial<TimeTravelConfig> {
136
+ /** Plugin instance controlled by this overlay bridge. */
137
+ time: TimeTravelPlugin;
138
+ }
139
+ /** React bridge for mounting and controlling a vanilla TimeTravelOverlay instance.
140
+ * Instantiates a `TimeTravelOverlay` for the provided plugin, tears it down on unmount, and syncs prop changes into reactive `config`.
141
+ * Use this when your app is React but you want the overlay behavior with react-safe instance lifecycle management.
142
+ * @param props Overlay bridge props.
143
+ */
144
+ declare function TimeTravelOverlay(props: TimeTravelOverlayProps): null;
87
145
 
88
- export { useAnyReactor, useAnySelector, useISOLayoutEffect, usePath, useReactor, useSelector };
146
+ export { TimeTravelOverlay, type TimeTravelOverlayProps, useAnyReactor, useAnySelector, useISOLayoutEffect, usePath, useReactor, useReactorSnapshot, useSelector, useSelectorSnapshot };
@@ -1,73 +1,124 @@
1
- import {
2
- Reactor
3
- } from "../chunk-Q2AKMIHN.js";
4
1
  import {
5
2
  Autotracker,
3
+ TimeTravelOverlay,
6
4
  withTracker
7
- } from "../chunk-FGUCKMLH.js";
5
+ } from "../chunk-TFLYCXK4.js";
6
+ import {
7
+ getReactor
8
+ } from "../chunk-2WBPGSRL.js";
9
+ import "../chunk-5A44QFT6.js";
10
+ import "../chunk-P37ADJMM.js";
8
11
  import {
9
12
  CTX,
10
13
  NIL,
11
14
  NOOP,
12
15
  getAny
13
- } from "../chunk-4MJUBEI7.js";
16
+ } from "../chunk-DP74DVRT.js";
17
+
18
+ // src/ts/adapters/react/hooks/useReactor.ts
19
+ import { useRef, useCallback, useSyncExternalStore, useMemo } from "react";
14
20
 
15
- // src/adapters/react/utils.ts
21
+ // src/ts/adapters/react/utils.ts
16
22
  import { useLayoutEffect, useEffect } from "react";
17
23
  var useISOLayoutEffect = "undefined" !== typeof window ? useLayoutEffect : useEffect;
18
24
 
19
- // src/adapters/react/hooks/useReactor.ts
20
- import { useRef, useReducer } from "react";
21
- function useReactor(target, options = NIL) {
22
- const [, reRender] = useReducer((s) => s + 1, 0), tgtRef = useRef(), rtrRef = useRef(), rtr = tgtRef.current !== target || !rtrRef.current ? (tgtRef.current = target, rtrRef.current = target instanceof Reactor ? target : target.__Reactor__ || new Reactor(target)) : rtrRef.current, atrkrRef = useRef(), prevTrkr = CTX.autotracker, atrkr = CTX.autotracker = atrkrRef.current ||= new Autotracker(), optsRef = useRef(options);
25
+ // src/ts/adapters/react/hooks/useReactor.ts
26
+ function useReactor(target, options = NIL, build) {
27
+ const versionRef = useRef(0), tgtRef = useRef(), rtrRef = useRef(), rtr = tgtRef.current !== target || !rtrRef.current ? (tgtRef.current = target, rtrRef.current = getReactor(target, true, build)) : rtrRef.current, atrkrRef = useRef(), prevTrkr = CTX.autotracker, atrkr = CTX.autotracker = atrkrRef.current ||= new Autotracker(), optsRef = useRef(options), notifyRef = useRef(NOOP);
23
28
  optsRef.current = options;
24
29
  atrkr.unblock(rtr), queueMicrotask(() => CTX.autotracker === atrkr && (CTX.autotracker = prevTrkr));
25
- return useISOLayoutEffect(() => (CTX.autotracker = prevTrkr, atrkr.callback(reRender, optsRef.current)), [atrkr]), rtr.core;
30
+ const subscribe = useCallback((notify) => atrkr.callback(notifyRef.current = () => (versionRef.current++, notify())), [atrkr]);
31
+ const getSnapshot = useCallback(() => versionRef.current, []);
32
+ useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
33
+ return useISOLayoutEffect(() => (CTX.autotracker = prevTrkr, atrkr.callback(notifyRef.current, optsRef.current)), [atrkr]), rtr.core;
26
34
  }
27
35
  function useAnyReactor(options = NIL) {
28
- const [, reRender] = useReducer((s) => s + 1, 0), atrkrRef = useRef(), prevTrkr = CTX.autotracker, atrkr = CTX.autotracker = atrkrRef.current ||= new Autotracker(), optsRef = useRef(options);
36
+ const versionRef = useRef(0), atrkrRef = useRef(), prevTrkr = CTX.autotracker, atrkr = CTX.autotracker = atrkrRef.current ||= new Autotracker(), optsRef = useRef(options), notifyRef = useRef(NOOP);
29
37
  optsRef.current = options;
30
38
  atrkr.unblock(), queueMicrotask(() => CTX.autotracker === atrkr && (CTX.autotracker = prevTrkr));
31
- useISOLayoutEffect(() => (CTX.autotracker = prevTrkr, atrkr.callback(reRender, optsRef.current)), [atrkr]);
39
+ const subscribe = useCallback((notify) => atrkr.callback(notifyRef.current = () => (versionRef.current++, notify())), [atrkr]);
40
+ const getSnapshot = useCallback(() => versionRef.current, []);
41
+ useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
42
+ useISOLayoutEffect(() => (CTX.autotracker = prevTrkr, atrkr.callback(notifyRef.current, optsRef.current)), [atrkr]);
43
+ }
44
+ function useReactorSnapshot(target, options, build = { referenceTracking: true, smartCloning: true }) {
45
+ const tgtRef = useRef(), rtrRef = useRef(), rtr = tgtRef.current !== target || !rtrRef.current ? (tgtRef.current = target, rtrRef.current = getReactor(target, true, build)) : rtrRef.current, atrkrRef = useRef(), atrkrRtrRef = useRef(), atrkr = atrkrRtrRef.current !== rtr || !atrkrRef.current ? (atrkrRtrRef.current = rtr, atrkrRef.current = new Autotracker(rtr)) : atrkrRef.current, notifyRef = useRef(NOOP), optsRef = useRef(options);
46
+ rtr.config.referenceTracking = rtr.config.smartCloning = true;
47
+ optsRef.current = options;
48
+ const subscribe = useCallback((notify) => (atrkr.callback(notifyRef.current = notify, optsRef.current), () => atrkr.cleanup()), [atrkr]);
49
+ const getSnapshot = () => rtr.snapshot();
50
+ const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
51
+ const proxy = useMemo(() => atrkr.tracked(snapshot), [atrkr, snapshot]);
52
+ return useISOLayoutEffect(() => atrkr.callback(notifyRef.current, optsRef.current), [atrkr, proxy]), proxy;
32
53
  }
33
54
 
34
- // src/adapters/react/hooks/useSelector.ts
35
- import { useSyncExternalStore, useRef as useRef2, useCallback } from "react";
36
- function useSelector(target, sel, eq = Object.is, options = NIL) {
37
- const rtrRef = useRef2(), tgtRef = useRef2(), rtr = tgtRef.current !== target || !rtrRef.current ? (tgtRef.current = target, rtrRef.current = target instanceof Reactor ? target : target.__Reactor__ || new Reactor(target)) : rtrRef.current, atrkrRef = useRef2(), atrkr = atrkrRef.current ||= new Autotracker(), notifyRef = useRef2(NOOP), sliceRef = useRef2(), selRef = useRef2(sel), eqRef = useRef2(eq), optsRef = useRef2(options);
55
+ // src/ts/adapters/react/hooks/useSelector.ts
56
+ import { useSyncExternalStore as useSyncExternalStore2, useRef as useRef2, useCallback as useCallback2 } from "react";
57
+ function useSelector(target, sel, eq = Object.is, options = NIL, build) {
58
+ const rtrRef = useRef2(), tgtRef = useRef2(), rtr = tgtRef.current !== target || !rtrRef.current ? (tgtRef.current = target, rtrRef.current = getReactor(target, true, build)) : rtrRef.current, atrkrRef = useRef2(), atrkr = atrkrRef.current ||= new Autotracker(), notifyRef = useRef2(NOOP), sliceRef = useRef2(), selRef = useRef2(sel), eqRef = useRef2(eq), optsRef = useRef2(options);
38
59
  selRef.current = sel, eqRef.current = eq, optsRef.current = options;
39
- const subscribe = useCallback((notify) => atrkr.callback(notifyRef.current = notify, optsRef.current), [atrkr]);
40
- const getSnapshot = useCallback(() => {
60
+ const subscribe = useCallback2((notify) => atrkr.callback(notifyRef.current = notify, optsRef.current), [atrkr]);
61
+ const getSnapshot = useCallback2(() => {
41
62
  const next = withTracker(atrkr, () => selRef.current(rtr.core), rtr);
42
63
  return eqRef.current(sliceRef.current, next) ? sliceRef.current : sliceRef.current = next;
43
64
  }, [atrkr, rtr]);
44
- const slice = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
65
+ const slice = useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
45
66
  return useISOLayoutEffect(() => atrkr.callback(notifyRef.current, optsRef.current), [atrkr, slice]), slice;
46
67
  }
47
68
  function useAnySelector(sel, eq = Object.is, options = NIL) {
48
69
  const atrkrRef = useRef2(), atrkr = atrkrRef.current ||= new Autotracker(), notifyRef = useRef2(NOOP), sliceRef = useRef2(), selRef = useRef2(sel), eqRef = useRef2(eq), optsRef = useRef2(options);
49
70
  selRef.current = sel, eqRef.current = eq, optsRef.current = options;
50
- const subscribe = useCallback((notify) => atrkr.callback(notifyRef.current = notify, optsRef.current), [atrkr]);
51
- const getSnapshot = useCallback(() => {
71
+ const subscribe = useCallback2((notify) => atrkr.callback(notifyRef.current = notify, optsRef.current), [atrkr]);
72
+ const getSnapshot = useCallback2(() => {
52
73
  const next = withTracker(atrkr, () => selRef.current());
53
74
  return eqRef.current(sliceRef.current, next) ? sliceRef.current : sliceRef.current = next;
54
75
  }, [atrkr]);
55
- const slice = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
76
+ const slice = useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
77
+ return useISOLayoutEffect(() => atrkr.callback(notifyRef.current, optsRef.current), [atrkr, slice]), slice;
78
+ }
79
+ function useSelectorSnapshot(target, sel, eq = Object.is, options, build = { referenceTracking: true, smartCloning: true }) {
80
+ const tgtRef = useRef2(), rtrRef = useRef2(), rtr = tgtRef.current !== target || !rtrRef.current ? (tgtRef.current = target, rtrRef.current = getReactor(target, true, build)) : rtrRef.current, atrkrRef = useRef2(), atrkrRtrRef = useRef2(), atrkr = atrkrRtrRef.current !== rtr || !atrkrRef.current ? (atrkrRtrRef.current = rtr, atrkrRef.current = new Autotracker(rtr)) : atrkrRef.current, notifyRef = useRef2(NOOP), sliceRef = useRef2(), selRef = useRef2(sel), eqRef = useRef2(eq), optsRef = useRef2(options);
81
+ rtr.config.referenceTracking = rtr.config.smartCloning = true;
82
+ optsRef.current = options, selRef.current = sel, eqRef.current = eq;
83
+ const subscribe = useCallback2((notify) => (atrkr.callback(notifyRef.current = notify, optsRef.current), () => atrkr.cleanup()), [atrkr]);
84
+ const getSnapshot = useCallback2(() => {
85
+ const next = selRef.current(atrkr.tracked(rtr.snapshot()));
86
+ return eqRef.current(sliceRef.current, next) ? sliceRef.current : sliceRef.current = next;
87
+ }, [atrkr]);
88
+ const slice = useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
56
89
  return useISOLayoutEffect(() => atrkr.callback(notifyRef.current, optsRef.current), [atrkr, slice]), slice;
57
90
  }
58
91
 
59
- // src/adapters/react/hooks/usePath.ts
60
- import { useRef as useRef3, useReducer as useReducer2 } from "react";
61
- function usePath(target, path, options = NIL) {
62
- const [, reRender] = useReducer2((s) => s + 1, 0), tgtRef = useRef3(), rtrRef = useRef3(), rtr = tgtRef.current !== target || !rtrRef.current ? (tgtRef.current = target, rtrRef.current = target instanceof Reactor ? target : target.__Reactor__ || new Reactor(target)) : rtrRef.current, optsRef = useRef3(options);
92
+ // src/ts/adapters/react/hooks/usePath.ts
93
+ import { useRef as useRef3, useSyncExternalStore as useSyncExternalStore3, useCallback as useCallback3 } from "react";
94
+ function usePath(target, path, options = NIL, build) {
95
+ const versionRef = useRef3(0), tgtRef = useRef3(), rtrRef = useRef3(), rtr = tgtRef.current !== target || !rtrRef.current ? (tgtRef.current = target, rtrRef.current = getReactor(target, true, build)) : rtrRef.current, optsRef = useRef3(options);
63
96
  optsRef.current = options;
64
- return useISOLayoutEffect(() => void rtr[optsRef.current.sync ? "watch" : "on"](path, reRender, optsRef.current), [rtr, path]), getAny(rtr.core, path);
97
+ const subscribe = useCallback3((notify) => rtr[optsRef.current.sync ? "watch" : "on"](path, () => (versionRef.current++, notify()), optsRef.current), [rtr, path]);
98
+ const getSnapshot = useCallback3(() => versionRef.current, []);
99
+ useSyncExternalStore3(subscribe, getSnapshot, getSnapshot);
100
+ return getAny(rtr.core, path);
101
+ }
102
+
103
+ // src/ts/adapters/react/TimeTravelOverlay.tsx
104
+ import { useRef as useRef4 } from "react";
105
+ function TimeTravelOverlay2(props) {
106
+ const vRef = useRef4(null), { time, title, color, devOnly, startOpen, container } = props;
107
+ useISOLayoutEffect(() => {
108
+ vRef.current = new TimeTravelOverlay(time, props);
109
+ return () => void (vRef.current?.destroy(), vRef.current = null);
110
+ }, [time]);
111
+ useISOLayoutEffect(() => void (vRef.current && (title !== void 0 && (vRef.current.config.title = title), vRef.current.config.color = color, vRef.current.config.devOnly = devOnly, vRef.current.config.container = container, vRef.current.state.open = startOpen)), [title, color, devOnly, container, startOpen]);
112
+ return null;
65
113
  }
66
114
  export {
115
+ TimeTravelOverlay2 as TimeTravelOverlay,
67
116
  useAnyReactor,
68
117
  useAnySelector,
69
118
  useISOLayoutEffect,
70
119
  usePath,
71
120
  useReactor,
72
- useSelector
121
+ useReactorSnapshot,
122
+ useSelector,
123
+ useSelectorSnapshot
73
124
  };