@veams/status-quo 1.1.0 → 1.3.0

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 (73) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +252 -18
  3. package/dist/config/status-quo-config.d.ts +21 -0
  4. package/dist/config/status-quo-config.js +48 -0
  5. package/dist/config/status-quo-config.js.map +1 -0
  6. package/dist/hooks/__tests__/state-selector.spec.d.ts +4 -0
  7. package/dist/hooks/__tests__/state-selector.spec.js +384 -0
  8. package/dist/hooks/__tests__/state-selector.spec.js.map +1 -0
  9. package/dist/hooks/__tests__/state-singleton.spec.d.ts +4 -0
  10. package/dist/hooks/__tests__/state-singleton.spec.js +97 -0
  11. package/dist/hooks/__tests__/state-singleton.spec.js.map +1 -0
  12. package/dist/hooks/index.d.ts +3 -0
  13. package/dist/hooks/index.js +3 -0
  14. package/dist/hooks/index.js.map +1 -1
  15. package/dist/hooks/state-actions.d.ts +2 -0
  16. package/dist/hooks/state-actions.js +5 -0
  17. package/dist/hooks/state-actions.js.map +1 -0
  18. package/dist/hooks/state-factory.d.ts +5 -0
  19. package/dist/hooks/state-factory.js +10 -6
  20. package/dist/hooks/state-factory.js.map +1 -1
  21. package/dist/hooks/state-handler.d.ts +2 -0
  22. package/dist/hooks/state-handler.js +9 -0
  23. package/dist/hooks/state-handler.js.map +1 -0
  24. package/dist/hooks/state-singleton.d.ts +4 -0
  25. package/dist/hooks/state-singleton.js +3 -5
  26. package/dist/hooks/state-singleton.js.map +1 -1
  27. package/dist/hooks/state-subscription-selector.d.ts +5 -0
  28. package/dist/hooks/state-subscription-selector.js +29 -0
  29. package/dist/hooks/state-subscription-selector.js.map +1 -0
  30. package/dist/hooks/state-subscription.d.ts +8 -1
  31. package/dist/hooks/state-subscription.js +49 -10
  32. package/dist/hooks/state-subscription.js.map +1 -1
  33. package/dist/index.d.ts +7 -5
  34. package/dist/index.js +4 -3
  35. package/dist/index.js.map +1 -1
  36. package/dist/store/__tests__/observable-state-handler.spec.js +68 -5
  37. package/dist/store/__tests__/observable-state-handler.spec.js.map +1 -1
  38. package/dist/store/__tests__/signal-state-handler.spec.js +64 -5
  39. package/dist/store/__tests__/signal-state-handler.spec.js.map +1 -1
  40. package/dist/store/index.d.ts +1 -1
  41. package/dist/store/observable-state-handler.d.ts +7 -2
  42. package/dist/store/observable-state-handler.js +17 -22
  43. package/dist/store/observable-state-handler.js.map +1 -1
  44. package/dist/store/signal-state-handler.d.ts +3 -1
  45. package/dist/store/signal-state-handler.js +5 -14
  46. package/dist/store/signal-state-handler.js.map +1 -1
  47. package/dist/store/state-singleton.d.ts +4 -1
  48. package/dist/store/state-singleton.js +11 -2
  49. package/dist/store/state-singleton.js.map +1 -1
  50. package/docs/assets/index-BBmpszOW.css +1 -0
  51. package/docs/assets/index-Cf8El_RO.js +194 -0
  52. package/docs/assets/statusquo-logo-8GVRbxpc.png +0 -0
  53. package/docs/index.html +13 -0
  54. package/package.json +1 -1
  55. package/playground/src/App.tsx +269 -48
  56. package/playground/src/styles.css +123 -0
  57. package/src/config/status-quo-config.ts +76 -0
  58. package/src/hooks/__tests__/state-selector.spec.tsx +607 -0
  59. package/src/hooks/__tests__/state-singleton.spec.tsx +151 -0
  60. package/src/hooks/index.ts +3 -0
  61. package/src/hooks/state-actions.tsx +7 -0
  62. package/src/hooks/state-factory.tsx +32 -6
  63. package/src/hooks/state-handler.tsx +16 -0
  64. package/src/hooks/state-singleton.tsx +17 -7
  65. package/src/hooks/state-subscription-selector.tsx +70 -0
  66. package/src/hooks/state-subscription.tsx +98 -21
  67. package/src/index.ts +23 -4
  68. package/src/store/__tests__/observable-state-handler.spec.ts +98 -11
  69. package/src/store/__tests__/signal-state-handler.spec.ts +92 -11
  70. package/src/store/index.ts +1 -1
  71. package/src/store/observable-state-handler.ts +25 -27
  72. package/src/store/signal-state-handler.ts +7 -16
  73. package/src/store/state-singleton.ts +21 -3
package/CHANGELOG.md CHANGED
@@ -4,6 +4,57 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [1.3.0] - 2026-02-25
8
+
9
+ ### Added
10
+ - `setupStatusQuo(config)` runtime setup for global distinct update behavior.
11
+
12
+ ### Changed
13
+ - Handler distinct comparison now supports global defaults (`setupStatusQuo`) with per-handler override precedence.
14
+
15
+ ## [1.2.0] - 2026-02-25
16
+
17
+ ### Added
18
+ - New composable hook APIs:
19
+ - `useStateHandler(factory, params?)`
20
+ - `useStateActions(handler)`
21
+ - `useStateSubscription(source, selector?, isEqual?)`
22
+ - Selector + equality support across shortcut hooks:
23
+ - `useStateFactory(factory, selector?, isEqual?, params?)`
24
+ - `useStateSingleton(singleton, selector?, isEqual?)`
25
+ - `StateSingletonOptions` with `destroyOnNoConsumers?: boolean` (default: `true`).
26
+ - Ref-counted singleton lifecycle handling so shared singleton instances are only destroyed when the last consumer unmounts.
27
+ - New hook test coverage for:
28
+ - composed API usage (`useStateHandler + useStateActions + useStateSubscription`)
29
+ - selector subscriptions with and without custom equality
30
+ - singleton subscription behavior and `destroyOnNoConsumers: false`
31
+ - full-snapshot subscription behavior.
32
+
33
+ ### Changed
34
+ - `useStateFactory` now composes `useStateHandler` + `useStateSubscription` internally.
35
+ - `useStateSubscription` now:
36
+ - accepts either `StateSubscriptionHandler` or `StateSingleton`
37
+ - returns `[selectedState, actions]`
38
+ - supports selector/equality without requiring separate selector-specific hook APIs.
39
+ - `useStateSingleton` is now a shortcut over `useStateSubscription(singleton, selector?, isEqual?)`.
40
+ - `makeStateSingleton` now accepts options and manages instance destruction through explicit lifecycle controls.
41
+ - Public exports extended:
42
+ - Added `useStateHandler`, `useStateActions`, `useStateSubscription`
43
+ - Added exported `StateSingletonOptions` type.
44
+ - Observable handler naming aligned with signal convention:
45
+ - Added `getObservable(key)` as the canonical API.
46
+
47
+ ### Deprecated
48
+ - `ObservableStateHandler#getObservableItem(key)` is now deprecated in favor of `getObservable(key)`.
49
+
50
+ ### Documentation
51
+ - README rewritten with a dedicated API guide that documents base composition, shortcut composition, singleton lifecycle options, and usage examples.
52
+ - Playground documentation significantly expanded:
53
+ - dedicated API section grouped by base composition, shortcut composition, and helper functions
54
+ - clearer singleton lifecycle explanation and examples
55
+ - improved card hierarchy and spacing for readability
56
+ - responsive/toggleable navigation for better mobile usage.
57
+
7
58
  ## [1.0.0] - 2026-02-17
8
59
 
9
60
  ### Added
@@ -27,4 +78,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
27
78
  - From: `super({ initialState, devTools: { ... } })`
28
79
  - To: `super({ initialState, options: { devTools: { ... } } })`
29
80
 
81
+ [1.3.0]: https://github.com/Veams/status-quo/compare/v1.2.0...v1.3.0
82
+ [1.2.0]: https://github.com/Veams/status-quo/compare/v1.0.0...v1.2.0
30
83
  [1.0.0]: https://github.com/Veams/status-quo/releases/tag/v1.0.0
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # @veams/status-quo
2
- [![npm version](https://img.shields.io/npm/v/@veams/status-quo)](https://www.npmjs.com/package/@veams/status-quo)
3
-
4
1
  <center>
5
2
  <img src="assets/statusquo-logo.png" width="200" alt="StatusQuo Logo" style="margin: 0 auto;">
6
3
  </center>
7
4
 
5
+ # @veams/status-quo
6
+ [![npm version](https://img.shields.io/npm/v/@veams/status-quo)](https://www.npmjs.com/package/@veams/status-quo)
7
+
8
8
  The manager to rule your state.
9
9
 
10
10
  This page mirrors the demo content and adds a full API reference.
@@ -19,10 +19,11 @@ This page mirrors the demo content and adds a full API reference.
19
19
  6. [Hooks](#hooks)
20
20
  7. [Singletons](#singletons)
21
21
  8. [Composition](#composition)
22
- 9. [Devtools](#devtools)
23
- 10. [Cleanup](#cleanup)
24
- 11. [API Reference](#api-reference)
25
- 12. [Migration](#migration)
22
+ 9. [API Guide](#api-guide)
23
+ 10. [Devtools](#devtools)
24
+ 11. [Cleanup](#cleanup)
25
+ 12. [API Reference](#api-reference)
26
+ 13. [Migration](#migration)
26
27
 
27
28
  ## Overview
28
29
 
@@ -76,6 +77,19 @@ class CounterStore extends ObservableStateHandler<CounterState, CounterActions>
76
77
  const [state, actions] = useStateFactory(() => new CounterStore(), []);
77
78
  ```
78
79
 
80
+ Optional global setup (e.g. with a custom deep-equality comparator):
81
+
82
+ ```ts
83
+ import equal from 'fast-deep-equal';
84
+ import { setupStatusQuo } from '@veams/status-quo';
85
+
86
+ setupStatusQuo({
87
+ distinct: {
88
+ comparator: equal,
89
+ },
90
+ });
91
+ ```
92
+
79
93
  ## Handlers
80
94
 
81
95
  StatusQuo provides two handler implementations with the same public interface:
@@ -87,22 +101,54 @@ Both are built on `BaseStateHandler`, which provides the shared lifecycle and de
87
101
 
88
102
  ## Hooks
89
103
 
90
- - `useStateFactory(factory, deps)`
91
- - Creates a handler instance per component and subscribes to its snapshot.
92
- - Suitable for per-component or per-instance state.
93
- - `useStateSingleton(singleton)`
94
- - Uses a shared singleton handler across components.
104
+ Use `useStateHandler + useStateActions + useStateSubscription` as the base composition.
105
+ `useStateFactory` and `useStateSingleton` are shortcut APIs over that composition.
106
+ For full signatures and practical examples, see [API Guide](#api-guide).
107
+
108
+ - `useStateHandler(factory, params)`
109
+ - Creates and memoizes one handler instance per component.
110
+ - `useStateActions(handler)`
111
+ - Returns actions without subscribing to state.
112
+ - `useStateSubscription(handlerOrSingleton, selector?, isEqual?)`
113
+ - Subscribes to full state or a selected slice and returns `[state, actions]`.
114
+ - `useStateFactory(factory, selector?, isEqual?, params?)`
115
+ - Shortcut for `useStateHandler + useStateSubscription`.
116
+ - `useStateSingleton(singleton, selector?, isEqual?)`
117
+ - Shortcut for `useStateSubscription(singleton, selector?, isEqual?)`.
118
+
119
+ Recommended composition:
120
+
121
+ ```ts
122
+ const handler = useStateHandler(createUserStore, []);
123
+ const actions = useStateActions(handler);
124
+ const [name] = useStateSubscription(handler, (state) => state.user.name);
125
+
126
+ const [singletonName] = useStateSubscription(UserSingleton, (state) => state.user.name);
127
+ ```
95
128
 
96
129
  ## Singletons
97
130
 
131
+ Use singletons for shared state across multiple components.
132
+
98
133
  ```ts
99
134
  import { makeStateSingleton, useStateSingleton } from '@veams/status-quo';
100
135
 
136
+ // Default behavior: singleton is destroyed when the last consumer unmounts.
101
137
  const CounterSingleton = makeStateSingleton(() => new CounterStore());
102
138
 
103
139
  const [state, actions] = useStateSingleton(CounterSingleton);
104
140
  ```
105
141
 
142
+ Keep a singleton instance alive across unmounts:
143
+
144
+ ```ts
145
+ const PersistentCounterSingleton = makeStateSingleton(() => new CounterStore(), {
146
+ destroyOnNoConsumers: false,
147
+ });
148
+ ```
149
+
150
+ Use this for app-level stores that should survive route/component unmounts. Keep the default for stores that should release resources when unused.
151
+
106
152
  ## Composition
107
153
 
108
154
  Use only the slice you need. RxJS makes multi-source composition powerful and declarative with operators like `combineLatest`, `switchMap`, or `debounceTime`. Signals can derive values with `computed` and wire them into a parent store via `bindSubscribable`.
@@ -155,6 +201,154 @@ class AppSignalStore extends SignalStateHandler<AppState, AppActions> {
155
201
  }
156
202
  ```
157
203
 
204
+ ## API Guide
205
+
206
+ This section documents the primary public API with behavior notes and usage examples.
207
+
208
+ ### `setupStatusQuo(config?)`
209
+
210
+ Sets global runtime defaults for distinct update behavior.
211
+ Per-handler options still override the global setup.
212
+
213
+ ```ts
214
+ type StatusQuoConfig = {
215
+ distinct?: {
216
+ enabled?: boolean; // default: true
217
+ comparator?: (previous: unknown, next: unknown) => boolean; // default: JSON compare
218
+ };
219
+ };
220
+ ```
221
+
222
+ ```ts
223
+ import equal from 'fast-deep-equal';
224
+ import { setupStatusQuo } from '@veams/status-quo';
225
+
226
+ setupStatusQuo({
227
+ distinct: {
228
+ comparator: equal,
229
+ },
230
+ });
231
+ ```
232
+
233
+ ### `useStateHandler(factory, params?)`
234
+
235
+ Creates one handler instance per component mount and returns it.
236
+
237
+ - `factory`: function returning a `StateSubscriptionHandler`
238
+ - `params`: optional factory params tuple
239
+ - lifecycle note: params are applied when the handler instance is created for that mount
240
+
241
+ ```ts
242
+ const handler = useStateHandler(createUserStore, []);
243
+ ```
244
+
245
+ ### `useStateActions(handler)`
246
+
247
+ Returns actions from a handler without subscribing to state changes.
248
+ Use this in action-only components to avoid rerenders from state updates.
249
+
250
+ ```ts
251
+ const handler = useStateHandler(createUserStore, []);
252
+ const actions = useStateActions(handler);
253
+ ```
254
+
255
+ ### `useStateSubscription(source, selector?, isEqual?)`
256
+
257
+ Subscribes to either a handler instance or a singleton and returns `[selectedState, actions]`.
258
+
259
+ - `source`: `StateSubscriptionHandler` or `StateSingleton`
260
+ - `selector`: optional projection function; defaults to identity
261
+ - `isEqual`: optional equality function; defaults to `Object.is`
262
+
263
+ Full snapshot subscription:
264
+
265
+ ```ts
266
+ const handler = useStateHandler(createUserStore, []);
267
+ const [state, actions] = useStateSubscription(handler);
268
+ ```
269
+
270
+ Selector subscription:
271
+
272
+ ```ts
273
+ const [name, actions] = useStateSubscription(
274
+ handler,
275
+ (state) => state.user.name
276
+ );
277
+ ```
278
+
279
+ Selector with custom equality:
280
+
281
+ ```ts
282
+ const [profile] = useStateSubscription(
283
+ handler,
284
+ (state) => state.user.profile,
285
+ (current, next) => current.id === next.id && current.role === next.role
286
+ );
287
+ ```
288
+
289
+ Singleton source:
290
+
291
+ ```ts
292
+ const [session, actions] = useStateSubscription(SessionSingleton);
293
+ ```
294
+
295
+ Lifecycle note for singleton sources:
296
+ - Consumers are ref-counted.
297
+ - The singleton instance is only destroyed when the last consumer unmounts and `destroyOnNoConsumers !== false`.
298
+
299
+ ### `useStateFactory(factory, selector?, isEqual?, params?)`
300
+
301
+ Shortcut API for `useStateHandler + useStateSubscription`.
302
+
303
+ - `useStateFactory(factory, params)`
304
+ - `useStateFactory(factory, selector, params)`
305
+ - `useStateFactory(factory, selector, isEqual, params)`
306
+
307
+ ```ts
308
+ const [state, actions] = useStateFactory(createUserStore, []);
309
+ const [name] = useStateFactory(createUserStore, (state) => state.user.name, []);
310
+ const [profile] = useStateFactory(
311
+ createUserStore,
312
+ (state) => state.user.profile,
313
+ (current, next) => current.id === next.id,
314
+ []
315
+ );
316
+ ```
317
+
318
+ ### `makeStateSingleton(factory, options?)`
319
+
320
+ Creates a shared singleton provider for a handler instance.
321
+
322
+ ```ts
323
+ const UserSingleton = makeStateSingleton(() => new UserStore());
324
+ ```
325
+
326
+ Options:
327
+
328
+ ```ts
329
+ type StateSingletonOptions = {
330
+ destroyOnNoConsumers?: boolean; // default: true
331
+ };
332
+ ```
333
+
334
+ - `true` (default): destroy instance after last consumer unmounts
335
+ - `false`: keep instance alive across periods with zero consumers
336
+
337
+ ```ts
338
+ const PersistentUserSingleton = makeStateSingleton(() => new UserStore(), {
339
+ destroyOnNoConsumers: false,
340
+ });
341
+ ```
342
+
343
+ ### `useStateSingleton(singleton, selector?, isEqual?)`
344
+
345
+ Shortcut API for `useStateSubscription(singleton, selector?, isEqual?)`.
346
+
347
+ ```ts
348
+ const [state, actions] = useStateSingleton(UserSingleton);
349
+ const [name] = useStateSingleton(UserSingleton, (state) => state.user.name);
350
+ ```
351
+
158
352
  ## Devtools
159
353
 
160
354
  Enable Redux Devtools integration with `options.devTools`:
@@ -241,6 +435,11 @@ protected constructor({
241
435
  initialState: S;
242
436
  options?: {
243
437
  devTools?: { enabled?: boolean; namespace: string };
438
+ distinct?: {
439
+ enabled?: boolean;
440
+ comparator?: (previous: S, next: S) => boolean;
441
+ };
442
+ useDistinctUntilChanged?: boolean; // optional override
244
443
  };
245
444
  })
246
445
  ```
@@ -249,11 +448,12 @@ Public methods:
249
448
 
250
449
  - `getStateAsObservable(options?: { useDistinctUntilChanged?: boolean }): Observable<S>`
251
450
  - `getStateItemAsObservable(key: keyof S): Observable<S[keyof S]>`
252
- - `getObservableItem(key: keyof S): Observable<S[keyof S]>`
451
+ - `getObservable(key: keyof S): Observable<S[keyof S]>`
253
452
  - `subscribe(listener: () => void): () => void`
254
453
 
255
454
  Notes:
256
- - The observable stream uses `distinctUntilChanged` by default (JSON compare).
455
+ - The observable stream uses `distinctUntilChanged` by default.
456
+ - Distinct behavior can be configured globally via `setupStatusQuo` or per handler via `options.distinct`.
257
457
  - `subscribe` does not fire for the initial value; it only fires on subsequent changes.
258
458
 
259
459
  ### `SignalStateHandler<S, A>`
@@ -270,6 +470,10 @@ protected constructor({
270
470
  initialState: S;
271
471
  options?: {
272
472
  devTools?: { enabled?: boolean; namespace: string };
473
+ distinct?: {
474
+ enabled?: boolean;
475
+ comparator?: (previous: S, next: S) => boolean;
476
+ };
273
477
  useDistinctUntilChanged?: boolean;
274
478
  };
275
479
  })
@@ -281,23 +485,53 @@ Public methods:
281
485
  - `subscribe(listener: () => void): () => void`
282
486
 
283
487
  Notes:
284
- - `useDistinctUntilChanged` defaults to `true` (JSON compare).
488
+ - Distinct behavior defaults to enabled.
489
+ - Configure it globally via `setupStatusQuo` or per handler via `options.distinct`.
490
+ - `useDistinctUntilChanged` remains available as a shorthand enable/disable override.
491
+
492
+ ### `setupStatusQuo`
493
+
494
+ ```ts
495
+ type StatusQuoConfig = {
496
+ distinct?: {
497
+ enabled?: boolean;
498
+ comparator?: (previous: unknown, next: unknown) => boolean;
499
+ };
500
+ };
501
+
502
+ function setupStatusQuo(config?: StatusQuoConfig): void
503
+ ```
285
504
 
286
505
  ### `makeStateSingleton`
287
506
 
288
507
  ```ts
508
+ type StateSingletonOptions = {
509
+ destroyOnNoConsumers?: boolean; // default: true
510
+ };
511
+
289
512
  function makeStateSingleton<S, A>(
290
- factory: () => StateSubscriptionHandler<S, A>
513
+ factory: () => StateSubscriptionHandler<S, A>,
514
+ options?: StateSingletonOptions
291
515
  ): {
292
516
  getInstance: () => StateSubscriptionHandler<S, A>;
293
517
  }
294
518
  ```
295
519
 
520
+ Lifecycle behavior:
521
+ - `destroyOnNoConsumers: true` (default): destroy and recreate singleton instances with mount lifecycle.
522
+ - `destroyOnNoConsumers: false`: keep the same singleton instance alive when no component is subscribed.
523
+
296
524
  ### Hooks
297
525
 
298
- - `useStateFactory<V, A, P extends unknown[]>(factory: (...args: P) => StateSubscriptionHandler<V, A>, params?: P)`
526
+ - `useStateHandler<V, A, P extends unknown[]>(factory: (...args: P) => StateSubscriptionHandler<V, A>, params?: P)`
527
+ - Returns `StateSubscriptionHandler<V, A>`.
528
+ - `useStateActions<V, A>(handler: StateSubscriptionHandler<V, A>)`
529
+ - Returns `A`.
530
+ - `useStateSubscription<V, A, Sel = V>(source: StateSubscriptionHandler<V, A> | StateSingleton<V, A>, selector?: (state: V) => Sel, isEqual?: (current: Sel, next: Sel) => boolean)`
531
+ - Returns `[state, actions]`.
532
+ - `useStateFactory<V, A, P extends unknown[], Sel = V>(factory: (...args: P) => StateSubscriptionHandler<V, A>, selector?: (state: V) => Sel, isEqual?: (current: Sel, next: Sel) => boolean, params?: P)`
299
533
  - Returns `[state, actions]`.
300
- - `useStateSingleton<V, A>(singleton: StateSingleton<V, A>)`
534
+ - `useStateSingleton<V, A, Sel = V>(singleton: StateSingleton<V, A>, selector?: (state: V) => Sel, isEqual?: (current: Sel, next: Sel) => boolean)`
301
535
  - Returns `[state, actions]`.
302
536
 
303
537
  ## Migration
@@ -0,0 +1,21 @@
1
+ export type DistinctComparator<T = unknown> = (previous: T, next: T) => boolean;
2
+ export type DistinctOptions<T = unknown> = {
3
+ enabled?: boolean;
4
+ comparator?: DistinctComparator<T>;
5
+ };
6
+ export type StatusQuoConfig<T = unknown> = {
7
+ distinct?: DistinctOptions<T>;
8
+ };
9
+ type ResolvedDistinctOptions<T = unknown> = {
10
+ enabled: boolean;
11
+ comparator: DistinctComparator<T>;
12
+ };
13
+ type ResolvedStatusQuoConfig = {
14
+ distinct: ResolvedDistinctOptions;
15
+ };
16
+ export declare function setupStatusQuo<T = unknown>(config?: StatusQuoConfig<T>): void;
17
+ export declare function resolveDistinctOptions<T>(options?: DistinctOptions<T>, useDistinctUntilChanged?: boolean): ResolvedDistinctOptions<T>;
18
+ export declare function getStatusQuoConfig(): ResolvedStatusQuoConfig;
19
+ /** @internal testing helper */
20
+ export declare function resetStatusQuoForTests(): void;
21
+ export {};
@@ -0,0 +1,48 @@
1
+ function distinctAsJson(previous, next) {
2
+ if (Object.is(previous, next)) {
3
+ return true;
4
+ }
5
+ try {
6
+ return JSON.stringify(previous) === JSON.stringify(next);
7
+ }
8
+ catch {
9
+ return false;
10
+ }
11
+ }
12
+ function createDefaultStatusQuoConfig() {
13
+ return {
14
+ distinct: {
15
+ enabled: true,
16
+ comparator: distinctAsJson,
17
+ },
18
+ };
19
+ }
20
+ let statusQuoConfig = createDefaultStatusQuoConfig();
21
+ export function setupStatusQuo(config = {}) {
22
+ statusQuoConfig = {
23
+ distinct: {
24
+ enabled: config.distinct?.enabled ?? true,
25
+ comparator: (config.distinct?.comparator ?? distinctAsJson),
26
+ },
27
+ };
28
+ }
29
+ export function resolveDistinctOptions(options, useDistinctUntilChanged) {
30
+ return {
31
+ enabled: options?.enabled ?? useDistinctUntilChanged ?? statusQuoConfig.distinct.enabled,
32
+ comparator: (options?.comparator ??
33
+ statusQuoConfig.distinct.comparator),
34
+ };
35
+ }
36
+ export function getStatusQuoConfig() {
37
+ return {
38
+ distinct: {
39
+ enabled: statusQuoConfig.distinct.enabled,
40
+ comparator: statusQuoConfig.distinct.comparator,
41
+ },
42
+ };
43
+ }
44
+ /** @internal testing helper */
45
+ export function resetStatusQuoForTests() {
46
+ statusQuoConfig = createDefaultStatusQuoConfig();
47
+ }
48
+ //# sourceMappingURL=status-quo-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-quo-config.js","sourceRoot":"","sources":["../../src/config/status-quo-config.ts"],"names":[],"mappings":"AAoBA,SAAS,cAAc,CAAC,QAAiB,EAAE,IAAa;IACtD,IAAI,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B;IACnC,OAAO;QACL,QAAQ,EAAE;YACR,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,cAAc;SAC3B;KACF,CAAC;AACJ,CAAC;AAED,IAAI,eAAe,GAAG,4BAA4B,EAAE,CAAC;AAErD,MAAM,UAAU,cAAc,CAAc,SAA6B,EAAE;IACzE,eAAe,GAAG;QAChB,QAAQ,EAAE;YACR,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,IAAI,IAAI;YACzC,UAAU,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,IAAI,cAAc,CAAuB;SAClF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,OAA4B,EAC5B,uBAAiC;IAEjC,OAAO;QACL,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,uBAAuB,IAAI,eAAe,CAAC,QAAQ,CAAC,OAAO;QACxF,UAAU,EAAE,CAAC,OAAO,EAAE,UAAU;YAC9B,eAAe,CAAC,QAAQ,CAAC,UAAU,CAA0B;KAChE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,QAAQ,EAAE;YACR,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC,OAAO;YACzC,UAAU,EAAE,eAAe,CAAC,QAAQ,CAAC,UAAU;SAChD;KACyB,CAAC;AAC/B,CAAC;AAED,+BAA+B;AAC/B,MAAM,UAAU,sBAAsB;IACpC,eAAe,GAAG,4BAA4B,EAAE,CAAC;AACnD,CAAC"}
@@ -0,0 +1,4 @@
1
+ declare global {
2
+ var IS_REACT_ACT_ENVIRONMENT: boolean;
3
+ }
4
+ export {};