@nice-code/state 0.3.3

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 (27) hide show
  1. package/README.md +1 -0
  2. package/build/devtools/browser/index.js +1653 -0
  3. package/build/index.js +241 -0
  4. package/build/react/index.js +315 -0
  5. package/build/types/core/Store.d.ts +135 -0
  6. package/build/types/core/index.d.ts +1 -0
  7. package/build/types/devtools/browser/NiceStateDevtools.d.ts +8 -0
  8. package/build/types/devtools/browser/components/ChangeDetailPanel.d.ts +5 -0
  9. package/build/types/devtools/browser/components/ChangeList.d.ts +9 -0
  10. package/build/types/devtools/browser/components/DiffView.d.ts +9 -0
  11. package/build/types/devtools/browser/components/JsonView.d.ts +7 -0
  12. package/build/types/devtools/browser/components/PanelChrome.d.ts +54 -0
  13. package/build/types/devtools/browser/components/SectionLabel.d.ts +4 -0
  14. package/build/types/devtools/browser/components/StateInspector.d.ts +16 -0
  15. package/build/types/devtools/browser/components/StoreTabs.d.ts +12 -0
  16. package/build/types/devtools/browser/components/utils.d.ts +29 -0
  17. package/build/types/devtools/browser/devtools_dock.d.ts +47 -0
  18. package/build/types/devtools/browser/index.d.ts +3 -0
  19. package/build/types/devtools/core/StateDevtools.types.d.ts +43 -0
  20. package/build/types/devtools/core/StateDevtoolsCore.d.ts +56 -0
  21. package/build/types/devtools/core/devtools_colors.d.ts +26 -0
  22. package/build/types/index.d.ts +1 -0
  23. package/build/types/react/InjectStoreState.d.ts +18 -0
  24. package/build/types/react/index.d.ts +3 -0
  25. package/build/types/react/useLocalStore.d.ts +8 -0
  26. package/build/types/react/useStoreState.d.ts +23 -0
  27. package/package.json +56 -0
package/build/index.js ADDED
@@ -0,0 +1,241 @@
1
+ // src/core/Store.ts
2
+ import { deepEqual } from "fast-equals";
3
+ import {
4
+ applyPatches,
5
+ enablePatches,
6
+ produce,
7
+ produceWithPatches
8
+ } from "immer";
9
+ enablePatches();
10
+ function makeSubscriptionFunction(store, watch, listener) {
11
+ let lastWatchState = watch(store.getRawState());
12
+ return () => {
13
+ const currentState = store.getRawState();
14
+ const nextWatchState = watch(currentState);
15
+ if (nextWatchState === lastWatchState) {
16
+ return;
17
+ }
18
+ if (deepEqual(nextWatchState, lastWatchState)) {
19
+ lastWatchState = nextWatchState;
20
+ return;
21
+ }
22
+ const previousWatched = lastWatchState;
23
+ lastWatchState = nextWatchState;
24
+ listener(nextWatchState, currentState, previousWatched);
25
+ };
26
+ }
27
+ function makeReactionFunctionCreator(watch, reaction) {
28
+ return (store) => {
29
+ let lastWatchState = watch(store.getRawState());
30
+ return (forceRun = false) => {
31
+ const currentState = store.getRawState();
32
+ const nextWatchState = watch(currentState);
33
+ if (!forceRun) {
34
+ if (nextWatchState === lastWatchState) {
35
+ return;
36
+ }
37
+ if (deepEqual(nextWatchState, lastWatchState)) {
38
+ lastWatchState = nextWatchState;
39
+ return;
40
+ }
41
+ }
42
+ const previousWatched = lastWatchState;
43
+ lastWatchState = nextWatchState;
44
+ if (store._hasPatchListeners()) {
45
+ const [nextState, patches, inversePatches] = produceWithPatches(currentState, (draft) => {
46
+ reaction(nextWatchState, draft, currentState, previousWatched);
47
+ });
48
+ store._updateStateWithoutReaction(nextState);
49
+ if (patches.length > 0) {
50
+ store._emitPatches(patches, inversePatches);
51
+ }
52
+ } else {
53
+ const nextState = produce(currentState, (draft) => {
54
+ reaction(nextWatchState, draft, currentState, previousWatched);
55
+ });
56
+ store._updateStateWithoutReaction(nextState);
57
+ }
58
+ };
59
+ };
60
+ }
61
+
62
+ class Store {
63
+ currentState;
64
+ createInitialState;
65
+ ssr = false;
66
+ listeners = new Set;
67
+ reactionCreators = [];
68
+ reactions = [];
69
+ clientSubscriptions = [];
70
+ _patchListeners = [];
71
+ constructor(initialState) {
72
+ if (initialState instanceof Function) {
73
+ this.createInitialState = initialState;
74
+ this.currentState = initialState();
75
+ } else {
76
+ this.createInitialState = () => initialState;
77
+ this.currentState = initialState;
78
+ }
79
+ }
80
+ _setInternalOptions({ ssr, reactionCreators = [] }) {
81
+ this.ssr = ssr;
82
+ this.reactionCreators = reactionCreators;
83
+ this.reactions = reactionCreators.map((rc) => rc(this));
84
+ }
85
+ _getReactionCreators() {
86
+ return this.reactionCreators;
87
+ }
88
+ _instantiateReactions() {
89
+ this.reactions = this.reactionCreators.map((rc) => rc(this));
90
+ }
91
+ _getInitialState() {
92
+ return this.createInitialState();
93
+ }
94
+ _hasPatchListeners() {
95
+ return this._patchListeners.length > 0;
96
+ }
97
+ _emitPatches(patches, inversePatches) {
98
+ for (const listener of this._patchListeners) {
99
+ listener(patches, inversePatches);
100
+ }
101
+ }
102
+ _updateStateWithoutReaction(nextState) {
103
+ this.currentState = nextState;
104
+ }
105
+ _updateState(nextState) {
106
+ this.currentState = nextState;
107
+ for (const runReaction of this.reactions) {
108
+ runReaction();
109
+ }
110
+ if (this.ssr) {
111
+ return;
112
+ }
113
+ for (const runSubscription of this.clientSubscriptions) {
114
+ runSubscription();
115
+ }
116
+ for (const listener of this.listeners) {
117
+ listener();
118
+ }
119
+ }
120
+ getRawState() {
121
+ return this.currentState;
122
+ }
123
+ subscribe(listener) {
124
+ this.listeners.add(listener);
125
+ return () => {
126
+ this.listeners.delete(listener);
127
+ };
128
+ }
129
+ watch(watch, listener) {
130
+ if (this.ssr) {
131
+ return () => {
132
+ console.warn(`@nice-code/state: Subscriptions made on the server side are not registered, so this unsubscribe call does nothing.`);
133
+ };
134
+ }
135
+ const run = makeSubscriptionFunction(this, watch, listener);
136
+ this.clientSubscriptions.push(run);
137
+ return () => {
138
+ this.clientSubscriptions = this.clientSubscriptions.filter((f) => f !== run);
139
+ };
140
+ }
141
+ createReaction(watch, reaction, { runNow = false, runNowWithSideEffects = false } = {}) {
142
+ const creator = makeReactionFunctionCreator(watch, reaction);
143
+ this.reactionCreators.push(creator);
144
+ const run = creator(this);
145
+ this.reactions.push(run);
146
+ if (runNow || runNowWithSideEffects) {
147
+ run(true);
148
+ if (runNowWithSideEffects && !this.ssr) {
149
+ this._updateState(this.currentState);
150
+ }
151
+ }
152
+ return () => {
153
+ this.reactions = this.reactions.filter((f) => f !== run);
154
+ this.reactionCreators = this.reactionCreators.filter((f) => f !== creator);
155
+ };
156
+ }
157
+ listenToPatches(patchListener) {
158
+ this._patchListeners.push(patchListener);
159
+ return () => {
160
+ this._patchListeners = this._patchListeners.filter((f) => f !== patchListener);
161
+ };
162
+ }
163
+ update(updater, patchesCallback) {
164
+ update(this, updater, patchesCallback);
165
+ }
166
+ replace(newState) {
167
+ if (newState !== this.currentState) {
168
+ this._updateState(newState);
169
+ }
170
+ }
171
+ replaceFromCurrent(replacer) {
172
+ const nextState = replacer(this.currentState);
173
+ if (nextState !== this.currentState) {
174
+ this._updateState(nextState);
175
+ }
176
+ }
177
+ applyPatches(patches) {
178
+ applyPatchesToStore(this, patches);
179
+ }
180
+ }
181
+ function applyPatchesToStore(store, patches) {
182
+ const currentState = store.getRawState();
183
+ const nextState = applyPatches(currentState, patches);
184
+ if (nextState !== currentState) {
185
+ store._updateState(nextState);
186
+ }
187
+ }
188
+ function applyUpdaterWithPatches(currentState, updater) {
189
+ if (typeof updater === "function") {
190
+ const [next, patches2, inversePatches2] = produceWithPatches(currentState, (draft) => {
191
+ updater(draft, currentState);
192
+ });
193
+ return [next, patches2, inversePatches2];
194
+ }
195
+ let state = currentState;
196
+ const patches = [];
197
+ const inversePatches = [];
198
+ for (const single of updater) {
199
+ const [next, p, ip] = produceWithPatches(state, (draft) => {
200
+ single(draft, state);
201
+ });
202
+ state = next;
203
+ patches.push(...p);
204
+ inversePatches.push(...ip);
205
+ }
206
+ return [state, patches, inversePatches];
207
+ }
208
+ function applyUpdater(currentState, updater) {
209
+ if (typeof updater === "function") {
210
+ return produce(currentState, (draft) => {
211
+ updater(draft, currentState);
212
+ });
213
+ }
214
+ return updater.reduce((previousState, single) => produce(previousState, (draft) => {
215
+ single(draft, previousState);
216
+ }), currentState);
217
+ }
218
+ function update(store, updater, patchesCallback) {
219
+ const currentState = store.getRawState();
220
+ let nextState;
221
+ if (store._hasPatchListeners() || patchesCallback != null) {
222
+ const [next, patches, inversePatches] = applyUpdaterWithPatches(currentState, updater);
223
+ if (patches.length > 0) {
224
+ if (patchesCallback != null) {
225
+ patchesCallback(patches, inversePatches);
226
+ }
227
+ store._emitPatches(patches, inversePatches);
228
+ }
229
+ nextState = next;
230
+ } else {
231
+ nextState = applyUpdater(currentState, updater);
232
+ }
233
+ if (nextState !== currentState) {
234
+ store._updateState(nextState);
235
+ }
236
+ }
237
+ export {
238
+ update,
239
+ applyPatchesToStore,
240
+ Store
241
+ };
@@ -0,0 +1,315 @@
1
+ // src/react/useStoreState.ts
2
+ import { useCallback, useRef, useSyncExternalStore } from "react";
3
+ function strictEqual(a, b) {
4
+ return a === b;
5
+ }
6
+ function useStoreState(store, getSubState, equalityFn = strictEqual) {
7
+ const selectorRef = useRef(getSubState);
8
+ const equalityRef = useRef(equalityFn);
9
+ selectorRef.current = getSubState;
10
+ equalityRef.current = equalityFn;
11
+ const cacheRef = useRef(null);
12
+ const getSnapshot = useCallback(() => {
13
+ const rawState = store.getRawState();
14
+ const selector = selectorRef.current;
15
+ const nextValue = selector ? selector(rawState) : rawState;
16
+ const cache = cacheRef.current;
17
+ if (cache === null) {
18
+ cacheRef.current = { value: nextValue };
19
+ return nextValue;
20
+ }
21
+ const lastValue = cache.value;
22
+ if (nextValue === lastValue) {
23
+ return lastValue;
24
+ }
25
+ if (equalityRef.current(lastValue, nextValue)) {
26
+ return lastValue;
27
+ }
28
+ cache.value = nextValue;
29
+ return nextValue;
30
+ }, [store]);
31
+ const subscribe = useCallback((onStoreChange) => store.subscribe(onStoreChange), [store]);
32
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
33
+ }
34
+
35
+ // src/react/InjectStoreState.ts
36
+ function InjectStoreState({
37
+ store,
38
+ on,
39
+ equalityFn,
40
+ children
41
+ }) {
42
+ const state = useStoreState(store, on ?? ((s) => s), equalityFn);
43
+ return children(state);
44
+ }
45
+ // src/react/useLocalStore.ts
46
+ import { useRef as useRef2 } from "react";
47
+
48
+ // src/core/Store.ts
49
+ import { deepEqual } from "fast-equals";
50
+ import {
51
+ applyPatches,
52
+ enablePatches,
53
+ produce,
54
+ produceWithPatches
55
+ } from "immer";
56
+ enablePatches();
57
+ function makeSubscriptionFunction(store, watch, listener) {
58
+ let lastWatchState = watch(store.getRawState());
59
+ return () => {
60
+ const currentState = store.getRawState();
61
+ const nextWatchState = watch(currentState);
62
+ if (nextWatchState === lastWatchState) {
63
+ return;
64
+ }
65
+ if (deepEqual(nextWatchState, lastWatchState)) {
66
+ lastWatchState = nextWatchState;
67
+ return;
68
+ }
69
+ const previousWatched = lastWatchState;
70
+ lastWatchState = nextWatchState;
71
+ listener(nextWatchState, currentState, previousWatched);
72
+ };
73
+ }
74
+ function makeReactionFunctionCreator(watch, reaction) {
75
+ return (store) => {
76
+ let lastWatchState = watch(store.getRawState());
77
+ return (forceRun = false) => {
78
+ const currentState = store.getRawState();
79
+ const nextWatchState = watch(currentState);
80
+ if (!forceRun) {
81
+ if (nextWatchState === lastWatchState) {
82
+ return;
83
+ }
84
+ if (deepEqual(nextWatchState, lastWatchState)) {
85
+ lastWatchState = nextWatchState;
86
+ return;
87
+ }
88
+ }
89
+ const previousWatched = lastWatchState;
90
+ lastWatchState = nextWatchState;
91
+ if (store._hasPatchListeners()) {
92
+ const [nextState, patches, inversePatches] = produceWithPatches(currentState, (draft) => {
93
+ reaction(nextWatchState, draft, currentState, previousWatched);
94
+ });
95
+ store._updateStateWithoutReaction(nextState);
96
+ if (patches.length > 0) {
97
+ store._emitPatches(patches, inversePatches);
98
+ }
99
+ } else {
100
+ const nextState = produce(currentState, (draft) => {
101
+ reaction(nextWatchState, draft, currentState, previousWatched);
102
+ });
103
+ store._updateStateWithoutReaction(nextState);
104
+ }
105
+ };
106
+ };
107
+ }
108
+
109
+ class Store {
110
+ currentState;
111
+ createInitialState;
112
+ ssr = false;
113
+ listeners = new Set;
114
+ reactionCreators = [];
115
+ reactions = [];
116
+ clientSubscriptions = [];
117
+ _patchListeners = [];
118
+ constructor(initialState) {
119
+ if (initialState instanceof Function) {
120
+ this.createInitialState = initialState;
121
+ this.currentState = initialState();
122
+ } else {
123
+ this.createInitialState = () => initialState;
124
+ this.currentState = initialState;
125
+ }
126
+ }
127
+ _setInternalOptions({ ssr, reactionCreators = [] }) {
128
+ this.ssr = ssr;
129
+ this.reactionCreators = reactionCreators;
130
+ this.reactions = reactionCreators.map((rc) => rc(this));
131
+ }
132
+ _getReactionCreators() {
133
+ return this.reactionCreators;
134
+ }
135
+ _instantiateReactions() {
136
+ this.reactions = this.reactionCreators.map((rc) => rc(this));
137
+ }
138
+ _getInitialState() {
139
+ return this.createInitialState();
140
+ }
141
+ _hasPatchListeners() {
142
+ return this._patchListeners.length > 0;
143
+ }
144
+ _emitPatches(patches, inversePatches) {
145
+ for (const listener of this._patchListeners) {
146
+ listener(patches, inversePatches);
147
+ }
148
+ }
149
+ _updateStateWithoutReaction(nextState) {
150
+ this.currentState = nextState;
151
+ }
152
+ _updateState(nextState) {
153
+ this.currentState = nextState;
154
+ for (const runReaction of this.reactions) {
155
+ runReaction();
156
+ }
157
+ if (this.ssr) {
158
+ return;
159
+ }
160
+ for (const runSubscription of this.clientSubscriptions) {
161
+ runSubscription();
162
+ }
163
+ for (const listener of this.listeners) {
164
+ listener();
165
+ }
166
+ }
167
+ getRawState() {
168
+ return this.currentState;
169
+ }
170
+ subscribe(listener) {
171
+ this.listeners.add(listener);
172
+ return () => {
173
+ this.listeners.delete(listener);
174
+ };
175
+ }
176
+ watch(watch, listener) {
177
+ if (this.ssr) {
178
+ return () => {
179
+ console.warn(`@nice-code/state: Subscriptions made on the server side are not registered, so this unsubscribe call does nothing.`);
180
+ };
181
+ }
182
+ const run = makeSubscriptionFunction(this, watch, listener);
183
+ this.clientSubscriptions.push(run);
184
+ return () => {
185
+ this.clientSubscriptions = this.clientSubscriptions.filter((f) => f !== run);
186
+ };
187
+ }
188
+ createReaction(watch, reaction, { runNow = false, runNowWithSideEffects = false } = {}) {
189
+ const creator = makeReactionFunctionCreator(watch, reaction);
190
+ this.reactionCreators.push(creator);
191
+ const run = creator(this);
192
+ this.reactions.push(run);
193
+ if (runNow || runNowWithSideEffects) {
194
+ run(true);
195
+ if (runNowWithSideEffects && !this.ssr) {
196
+ this._updateState(this.currentState);
197
+ }
198
+ }
199
+ return () => {
200
+ this.reactions = this.reactions.filter((f) => f !== run);
201
+ this.reactionCreators = this.reactionCreators.filter((f) => f !== creator);
202
+ };
203
+ }
204
+ listenToPatches(patchListener) {
205
+ this._patchListeners.push(patchListener);
206
+ return () => {
207
+ this._patchListeners = this._patchListeners.filter((f) => f !== patchListener);
208
+ };
209
+ }
210
+ update(updater, patchesCallback) {
211
+ update(this, updater, patchesCallback);
212
+ }
213
+ replace(newState) {
214
+ if (newState !== this.currentState) {
215
+ this._updateState(newState);
216
+ }
217
+ }
218
+ replaceFromCurrent(replacer) {
219
+ const nextState = replacer(this.currentState);
220
+ if (nextState !== this.currentState) {
221
+ this._updateState(nextState);
222
+ }
223
+ }
224
+ applyPatches(patches) {
225
+ applyPatchesToStore(this, patches);
226
+ }
227
+ }
228
+ function applyPatchesToStore(store, patches) {
229
+ const currentState = store.getRawState();
230
+ const nextState = applyPatches(currentState, patches);
231
+ if (nextState !== currentState) {
232
+ store._updateState(nextState);
233
+ }
234
+ }
235
+ function applyUpdaterWithPatches(currentState, updater) {
236
+ if (typeof updater === "function") {
237
+ const [next, patches2, inversePatches2] = produceWithPatches(currentState, (draft) => {
238
+ updater(draft, currentState);
239
+ });
240
+ return [next, patches2, inversePatches2];
241
+ }
242
+ let state = currentState;
243
+ const patches = [];
244
+ const inversePatches = [];
245
+ for (const single of updater) {
246
+ const [next, p, ip] = produceWithPatches(state, (draft) => {
247
+ single(draft, state);
248
+ });
249
+ state = next;
250
+ patches.push(...p);
251
+ inversePatches.push(...ip);
252
+ }
253
+ return [state, patches, inversePatches];
254
+ }
255
+ function applyUpdater(currentState, updater) {
256
+ if (typeof updater === "function") {
257
+ return produce(currentState, (draft) => {
258
+ updater(draft, currentState);
259
+ });
260
+ }
261
+ return updater.reduce((previousState, single) => produce(previousState, (draft) => {
262
+ single(draft, previousState);
263
+ }), currentState);
264
+ }
265
+ function update(store, updater, patchesCallback) {
266
+ const currentState = store.getRawState();
267
+ let nextState;
268
+ if (store._hasPatchListeners() || patchesCallback != null) {
269
+ const [next, patches, inversePatches] = applyUpdaterWithPatches(currentState, updater);
270
+ if (patches.length > 0) {
271
+ if (patchesCallback != null) {
272
+ patchesCallback(patches, inversePatches);
273
+ }
274
+ store._emitPatches(patches, inversePatches);
275
+ }
276
+ nextState = next;
277
+ } else {
278
+ nextState = applyUpdater(currentState, updater);
279
+ }
280
+ if (nextState !== currentState) {
281
+ store._updateState(nextState);
282
+ }
283
+ }
284
+
285
+ // src/react/useLocalStore.ts
286
+ function shallowEqualDeps(a, b) {
287
+ if (a === b) {
288
+ return true;
289
+ }
290
+ if (a == null || b == null || a.length !== b.length) {
291
+ return false;
292
+ }
293
+ for (let i = 0;i < a.length; i++) {
294
+ if (a[i] !== b[i]) {
295
+ return false;
296
+ }
297
+ }
298
+ return true;
299
+ }
300
+ function useLocalStore(initialState, deps) {
301
+ const storeRef = useRef2(null);
302
+ const depsRef = useRef2(deps);
303
+ if (storeRef.current === null) {
304
+ storeRef.current = new Store(initialState);
305
+ } else if (deps !== undefined && !shallowEqualDeps(depsRef.current, deps)) {
306
+ storeRef.current = new Store(initialState);
307
+ depsRef.current = deps;
308
+ }
309
+ return storeRef.current;
310
+ }
311
+ export {
312
+ useStoreState,
313
+ useLocalStore,
314
+ InjectStoreState
315
+ };
@@ -0,0 +1,135 @@
1
+ import { type Draft, type Patch, type PatchListener } from "immer";
2
+ /**
3
+ * A plain pub/sub listener. Fired (in the order added) every time the store's
4
+ * root state reference changes. This is the vanilla integration point that any
5
+ * ecosystem — including the React adapter's `useSyncExternalStore` — builds on.
6
+ */
7
+ export type TUpdateListener = () => void;
8
+ /**
9
+ * @typeParam S The store's state
10
+ * @param draft The mutable draft to change during this update (Immer proxy).
11
+ * @param original A readonly snapshot of the state as it was before this update.
12
+ */
13
+ export type TUpdateFunction<S> = (draft: Draft<S>, original: S) => void;
14
+ /**
15
+ * A selector that derives a watched slice `T` from the full store state `S`.
16
+ */
17
+ export type TStoreWatch<S extends object, T> = (state: S) => T;
18
+ /**
19
+ * Fired by {@link Store.watch} whenever the watched slice changes structurally.
20
+ */
21
+ export type TStoreSubscriptionListener<S extends object, T> = (watched: T, allState: S, previousWatched: T) => void;
22
+ /**
23
+ * Runs inside an Immer `produce` whenever a watched slice changes, letting the
24
+ * store derive further state from its own mutations.
25
+ */
26
+ export type TReactionFunction<S extends object, T> = (watched: T, draft: Draft<S>, original: S, previousWatched: T) => void;
27
+ export type TStoreActionUpdate<S extends object> = (updater: TUpdateFunction<S> | TUpdateFunction<S>[], patchesCallback?: TPatchesCallback) => void;
28
+ export type TStoreAction<S extends object> = (update: TStoreActionUpdate<S>) => void;
29
+ export type TPatchesCallback = (patches: Patch[], inversePatches: Patch[]) => void;
30
+ export interface IStoreInternalOptions<S extends object> {
31
+ ssr: boolean;
32
+ reactionCreators?: TReactionCreator<S>[];
33
+ }
34
+ export interface ICreateReactionOptions {
35
+ runNow?: boolean;
36
+ runNowWithSideEffects?: boolean;
37
+ }
38
+ /**
39
+ * A framework-agnostic, Immer-backed state container.
40
+ *
41
+ * The store owns a single immutable state value and a `Set` of plain
42
+ * listeners. Every mutation runs through Immer's `produce`, and listeners are
43
+ * only notified when the resulting root reference actually changes — making
44
+ * "no-op" updates genuinely free for subscribers.
45
+ *
46
+ * @typeParam S Your store's state interface.
47
+ */
48
+ export declare class Store<S extends object = object> {
49
+ private currentState;
50
+ private readonly createInitialState;
51
+ private ssr;
52
+ /** Plain pub/sub listeners — a Set both dedupes and dispatches fast. */
53
+ private readonly listeners;
54
+ private reactionCreators;
55
+ private reactions;
56
+ private clientSubscriptions;
57
+ constructor(initialState: S | (() => S));
58
+ /**
59
+ * Returns the raw state object contained within this store at this moment.
60
+ *
61
+ * ---
62
+ * ** WARNING **
63
+ *
64
+ * Most of the time, if you're using this in your app, there's probably a
65
+ * better way to do it (a selector subscription or the React adapter).
66
+ * ---
67
+ */
68
+ getRawState(): S;
69
+ /**
70
+ * Subscribe a plain listener to store mutations. The listener fires once per
71
+ * committed update (root reference change) and receives no arguments — read
72
+ * the latest value with {@link getRawState}.
73
+ *
74
+ * This is the low-level primitive that vanilla code and framework adapters
75
+ * (e.g. React's `useSyncExternalStore`) build upon.
76
+ *
77
+ * @returns An unsubscribe function.
78
+ */
79
+ subscribe(listener: TUpdateListener): () => void;
80
+ /**
81
+ * Subscribe to a derived slice of state. The `listener` only fires when the
82
+ * watched value changes structurally (per the Fast-Path rule).
83
+ *
84
+ * @returns An unsubscribe function.
85
+ */
86
+ watch<T>(watch: TStoreWatch<S, T>, listener: TStoreSubscriptionListener<S, T>): () => void;
87
+ /**
88
+ * Register a reaction: when the watched slice changes, the `reaction` recipe
89
+ * runs inside Immer to derive further state on the same store.
90
+ *
91
+ * @returns A function that removes the reaction.
92
+ */
93
+ createReaction<T>(watch: TStoreWatch<S, T>, reaction: TReactionFunction<S, T>, { runNow, runNowWithSideEffects }?: ICreateReactionOptions): () => void;
94
+ /**
95
+ * Subscribe to the Immer patches produced by each update.
96
+ *
97
+ * @returns An unsubscribe function.
98
+ */
99
+ listenToPatches(patchListener: PatchListener): () => void;
100
+ /**
101
+ * Mutate the store via one or more Immer update functions.
102
+ *
103
+ * @param updater A single update function, or an array applied in order.
104
+ * @param patchesCallback Optional callback receiving the patches for this update.
105
+ */
106
+ update(updater: TUpdateFunction<S> | TUpdateFunction<S>[], patchesCallback?: TPatchesCallback): void;
107
+ /**
108
+ * Replace the store's state entirely with a new state value.
109
+ */
110
+ replace(newState: S): void;
111
+ /**
112
+ * Replace the store's state by mapping from the current state.
113
+ */
114
+ replaceFromCurrent(replacer: (state: S) => S): void;
115
+ /**
116
+ * Apply a set of Immer patches to the store.
117
+ */
118
+ applyPatches(patches: Patch[]): void;
119
+ }
120
+ /**
121
+ * Apply Immer patches to a store, committing only if the root reference changes.
122
+ */
123
+ export declare function applyPatchesToStore<S extends object = object>(store: Store<S>, patches: Patch[]): void;
124
+ /**
125
+ * Mutate a store via one or more Immer update functions.
126
+ *
127
+ * Patches are only computed when there's a consumer for them (a registered
128
+ * patch listener or a `patchesCallback`), keeping the common path allocation-free.
129
+ * Listeners are notified only when the root reference actually changes.
130
+ *
131
+ * @param store The store to update.
132
+ * @param updater A single update function, or an array applied in order.
133
+ * @param patchesCallback Optional callback receiving the patches for this update.
134
+ */
135
+ export declare function update<S extends object = object>(store: Store<S>, updater: TUpdateFunction<S> | TUpdateFunction<S>[], patchesCallback?: TPatchesCallback): void;
@@ -0,0 +1 @@
1
+ export { applyPatchesToStore, type ICreateReactionOptions, type IStoreInternalOptions, Store, type TPatchesCallback, type TReactionFunction, type TStoreAction, type TStoreActionUpdate, type TStoreSubscriptionListener, type TStoreWatch, type TUpdateFunction, type TUpdateListener, update, } from "./Store";
@@ -0,0 +1,8 @@
1
+ import type { StateDevtoolsCore } from "../core/StateDevtoolsCore";
2
+ import type { TDevtoolsPosition } from "../core/StateDevtools.types";
3
+ export interface INiceStateDevtoolsProps {
4
+ core: StateDevtoolsCore;
5
+ position?: TDevtoolsPosition;
6
+ initialOpen?: boolean;
7
+ }
8
+ export declare function NiceStateDevtools(props: INiceStateDevtoolsProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,5 @@
1
+ import type { IDevtoolsStateChange } from "../../core/StateDevtools.types";
2
+ export declare function ChangeDetailPanel({ change, onRevert, }: {
3
+ change: IDevtoolsStateChange;
4
+ onRevert: (change: IDevtoolsStateChange) => void;
5
+ }): import("react/jsx-runtime").JSX.Element;