@veams/status-quo 1.2.0 → 1.3.1
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/CHANGELOG.md +9 -0
- package/README.md +65 -2
- package/dist/config/status-quo-config.d.ts +21 -0
- package/dist/config/status-quo-config.js +48 -0
- package/dist/config/status-quo-config.js.map +1 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/store/__tests__/observable-state-handler.spec.js +64 -5
- package/dist/store/__tests__/observable-state-handler.spec.js.map +1 -1
- package/dist/store/__tests__/signal-state-handler.spec.js +119 -5
- package/dist/store/__tests__/signal-state-handler.spec.js.map +1 -1
- package/dist/store/observable-state-handler.d.ts +5 -2
- package/dist/store/observable-state-handler.js +12 -21
- package/dist/store/observable-state-handler.js.map +1 -1
- package/dist/store/signal-state-handler.d.ts +3 -3
- package/dist/store/signal-state-handler.js +19 -28
- package/dist/store/signal-state-handler.js.map +1 -1
- package/docs/assets/{index-WFTLEHd3.css → index-BBmpszOW.css} +1 -1
- package/docs/assets/{index-Ci4A1zSh.js → index-Cf8El_RO.js} +19 -12
- package/docs/index.html +2 -2
- package/package.json +1 -1
- package/playground/src/App.tsx +24 -4
- package/playground/src/styles.css +0 -4
- package/src/config/status-quo-config.ts +76 -0
- package/src/index.ts +14 -4
- package/src/store/__tests__/observable-state-handler.spec.ts +92 -11
- package/src/store/__tests__/signal-state-handler.spec.ts +167 -11
- package/src/store/observable-state-handler.ts +19 -26
- package/src/store/signal-state-handler.ts +23 -32
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@ 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
|
+
|
|
7
15
|
## [1.2.0] - 2026-02-25
|
|
8
16
|
|
|
9
17
|
### Added
|
|
@@ -70,5 +78,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
70
78
|
- From: `super({ initialState, devTools: { ... } })`
|
|
71
79
|
- To: `super({ initialState, options: { devTools: { ... } } })`
|
|
72
80
|
|
|
81
|
+
[1.3.0]: https://github.com/Veams/status-quo/compare/v1.2.0...v1.3.0
|
|
73
82
|
[1.2.0]: https://github.com/Veams/status-quo/compare/v1.0.0...v1.2.0
|
|
74
83
|
[1.0.0]: https://github.com/Veams/status-quo/releases/tag/v1.0.0
|
package/README.md
CHANGED
|
@@ -77,6 +77,19 @@ class CounterStore extends ObservableStateHandler<CounterState, CounterActions>
|
|
|
77
77
|
const [state, actions] = useStateFactory(() => new CounterStore(), []);
|
|
78
78
|
```
|
|
79
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
|
+
|
|
80
93
|
## Handlers
|
|
81
94
|
|
|
82
95
|
StatusQuo provides two handler implementations with the same public interface:
|
|
@@ -192,6 +205,31 @@ class AppSignalStore extends SignalStateHandler<AppState, AppActions> {
|
|
|
192
205
|
|
|
193
206
|
This section documents the primary public API with behavior notes and usage examples.
|
|
194
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
|
+
|
|
195
233
|
### `useStateHandler(factory, params?)`
|
|
196
234
|
|
|
197
235
|
Creates one handler instance per component mount and returns it.
|
|
@@ -397,6 +435,11 @@ protected constructor({
|
|
|
397
435
|
initialState: S;
|
|
398
436
|
options?: {
|
|
399
437
|
devTools?: { enabled?: boolean; namespace: string };
|
|
438
|
+
distinct?: {
|
|
439
|
+
enabled?: boolean;
|
|
440
|
+
comparator?: (previous: S, next: S) => boolean;
|
|
441
|
+
};
|
|
442
|
+
useDistinctUntilChanged?: boolean; // optional override
|
|
400
443
|
};
|
|
401
444
|
})
|
|
402
445
|
```
|
|
@@ -409,7 +452,8 @@ Public methods:
|
|
|
409
452
|
- `subscribe(listener: () => void): () => void`
|
|
410
453
|
|
|
411
454
|
Notes:
|
|
412
|
-
- The observable stream uses `distinctUntilChanged` by default
|
|
455
|
+
- The observable stream uses `distinctUntilChanged` by default.
|
|
456
|
+
- Distinct behavior can be configured globally via `setupStatusQuo` or per handler via `options.distinct`.
|
|
413
457
|
- `subscribe` does not fire for the initial value; it only fires on subsequent changes.
|
|
414
458
|
|
|
415
459
|
### `SignalStateHandler<S, A>`
|
|
@@ -426,6 +470,10 @@ protected constructor({
|
|
|
426
470
|
initialState: S;
|
|
427
471
|
options?: {
|
|
428
472
|
devTools?: { enabled?: boolean; namespace: string };
|
|
473
|
+
distinct?: {
|
|
474
|
+
enabled?: boolean;
|
|
475
|
+
comparator?: (previous: S, next: S) => boolean;
|
|
476
|
+
};
|
|
429
477
|
useDistinctUntilChanged?: boolean;
|
|
430
478
|
};
|
|
431
479
|
})
|
|
@@ -437,7 +485,22 @@ Public methods:
|
|
|
437
485
|
- `subscribe(listener: () => void): () => void`
|
|
438
486
|
|
|
439
487
|
Notes:
|
|
440
|
-
-
|
|
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
|
+
```
|
|
441
504
|
|
|
442
505
|
### `makeStateSingleton`
|
|
443
506
|
|
|
@@ -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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { useStateActions, useStateFactory, useStateHandler, useStateSingleton, useStateSubscription } from './hooks
|
|
2
|
-
import { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler } from './store
|
|
3
|
-
import
|
|
1
|
+
import { useStateActions, useStateFactory, useStateHandler, useStateSingleton, useStateSubscription } from './hooks';
|
|
2
|
+
import { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler } from './store';
|
|
3
|
+
import { setupStatusQuo } from './config/status-quo-config.js';
|
|
4
|
+
import type { DistinctComparator, DistinctOptions, StatusQuoConfig } from './config/status-quo-config.js';
|
|
5
|
+
import type { StateSingleton, StateSingletonOptions } from './store';
|
|
4
6
|
import type { StateSubscriptionHandler } from './types/types.js';
|
|
5
|
-
export { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler, useStateActions, useStateFactory, useStateHandler, useStateSingleton, useStateSubscription, };
|
|
6
|
-
export type { StateSingleton, StateSingletonOptions, StateSubscriptionHandler };
|
|
7
|
+
export { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler, setupStatusQuo, useStateActions, useStateFactory, useStateHandler, useStateSingleton, useStateSubscription, };
|
|
8
|
+
export type { DistinctComparator, DistinctOptions, StateSingleton, StateSingletonOptions, StateSubscriptionHandler, StatusQuoConfig, };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { useStateActions, useStateFactory, useStateHandler, useStateSingleton, useStateSubscription, } from './hooks
|
|
2
|
-
import { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler, } from './store
|
|
3
|
-
|
|
1
|
+
import { useStateActions, useStateFactory, useStateHandler, useStateSingleton, useStateSubscription, } from './hooks';
|
|
2
|
+
import { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler, } from './store';
|
|
3
|
+
import { setupStatusQuo } from './config/status-quo-config.js';
|
|
4
|
+
export { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler, setupStatusQuo, useStateActions, useStateFactory, useStateHandler, useStateSingleton, useStateSubscription, };
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAM/D,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,CAAC"}
|
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
import { lastValueFrom, Subject, take } from 'rxjs';
|
|
2
|
+
import { resetStatusQuoForTests, setupStatusQuo } from '../../config/status-quo-config.js';
|
|
2
3
|
import { ObservableStateHandler } from '../observable-state-handler.js';
|
|
3
4
|
class TestObservableStateHandler extends ObservableStateHandler {
|
|
4
|
-
constructor(withDevTools) {
|
|
5
|
+
constructor({ withDevTools, distinct, useDistinctUntilChanged } = {}) {
|
|
5
6
|
super({
|
|
6
7
|
initialState: {
|
|
7
8
|
test: 'testValue',
|
|
8
9
|
test2: 'testValue2',
|
|
9
10
|
},
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
options: {
|
|
12
|
+
...(withDevTools && {
|
|
12
13
|
devTools: {
|
|
13
14
|
enabled: true,
|
|
14
15
|
namespace: 'TestObservableStateHandler',
|
|
15
16
|
},
|
|
16
|
-
},
|
|
17
|
-
|
|
17
|
+
}),
|
|
18
|
+
...(distinct && {
|
|
19
|
+
distinct,
|
|
20
|
+
}),
|
|
21
|
+
...(typeof useDistinctUntilChanged === 'boolean' && {
|
|
22
|
+
useDistinctUntilChanged,
|
|
23
|
+
}),
|
|
24
|
+
},
|
|
18
25
|
});
|
|
19
26
|
}
|
|
20
27
|
getActions() {
|
|
@@ -28,8 +35,12 @@ class TestObservableStateHandler extends ObservableStateHandler {
|
|
|
28
35
|
describe('Observable State Handler', () => {
|
|
29
36
|
let stateHandler;
|
|
30
37
|
beforeEach(() => {
|
|
38
|
+
resetStatusQuoForTests();
|
|
31
39
|
stateHandler = new TestObservableStateHandler();
|
|
32
40
|
});
|
|
41
|
+
afterEach(() => {
|
|
42
|
+
resetStatusQuoForTests();
|
|
43
|
+
});
|
|
33
44
|
it('should provide initial state', () => {
|
|
34
45
|
expect(stateHandler.getInitialState()).toStrictEqual({
|
|
35
46
|
test: 'testValue',
|
|
@@ -85,5 +96,53 @@ describe('Observable State Handler', () => {
|
|
|
85
96
|
unsubscribe();
|
|
86
97
|
expect(spy).toHaveBeenCalledTimes(2); // 1. test (first setter), 2. test2 (second setter)
|
|
87
98
|
});
|
|
99
|
+
it('should respect global distinct setup when disabled', () => {
|
|
100
|
+
setupStatusQuo({
|
|
101
|
+
distinct: {
|
|
102
|
+
enabled: false,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
const handler = new TestObservableStateHandler();
|
|
106
|
+
const spy = jest.fn();
|
|
107
|
+
const unsubscribe = handler.subscribe(spy);
|
|
108
|
+
handler.setState({ test: 'same' });
|
|
109
|
+
handler.setState({ test: 'same' });
|
|
110
|
+
unsubscribe();
|
|
111
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
|
112
|
+
});
|
|
113
|
+
it('should respect global custom distinct comparator from setupStatusQuo', () => {
|
|
114
|
+
setupStatusQuo({
|
|
115
|
+
distinct: {
|
|
116
|
+
comparator: (previous, next) => {
|
|
117
|
+
return previous.test === next.test;
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
const handler = new TestObservableStateHandler();
|
|
122
|
+
const spy = jest.fn();
|
|
123
|
+
const unsubscribe = handler.subscribe(spy);
|
|
124
|
+
handler.setState({ test2: 'newValue2' });
|
|
125
|
+
handler.setState({ test: 'newValue' });
|
|
126
|
+
unsubscribe();
|
|
127
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
128
|
+
});
|
|
129
|
+
it('should prefer per-handler distinct options over global setup', () => {
|
|
130
|
+
setupStatusQuo({
|
|
131
|
+
distinct: {
|
|
132
|
+
enabled: false,
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
const handler = new TestObservableStateHandler({
|
|
136
|
+
distinct: {
|
|
137
|
+
enabled: true,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
const spy = jest.fn();
|
|
141
|
+
const unsubscribe = handler.subscribe(spy);
|
|
142
|
+
handler.setState({ test: 'same' });
|
|
143
|
+
handler.setState({ test: 'same' });
|
|
144
|
+
unsubscribe();
|
|
145
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
146
|
+
});
|
|
88
147
|
});
|
|
89
148
|
//# sourceMappingURL=observable-state-handler.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observable-state-handler.spec.js","sourceRoot":"","sources":["../../../src/store/__tests__/observable-state-handler.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"observable-state-handler.spec.js","sourceRoot":"","sources":["../../../src/store/__tests__/observable-state-handler.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,27 @@
|
|
|
1
|
+
import { resetStatusQuoForTests, setupStatusQuo } from '../../config/status-quo-config.js';
|
|
1
2
|
import { SignalStateHandler } from '../signal-state-handler.js';
|
|
3
|
+
import { makeStateSingleton } from '../state-singleton.js';
|
|
2
4
|
class TestSignalStateHandler extends SignalStateHandler {
|
|
3
|
-
constructor(withDevTools) {
|
|
5
|
+
constructor({ withDevTools, distinct, useDistinctUntilChanged } = {}) {
|
|
4
6
|
super({
|
|
5
7
|
initialState: {
|
|
6
8
|
test: 'testValue',
|
|
7
9
|
test2: 'testValue2',
|
|
8
10
|
},
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
options: {
|
|
12
|
+
...(withDevTools && {
|
|
11
13
|
devTools: {
|
|
12
14
|
enabled: true,
|
|
13
15
|
namespace: 'TestSignalStateHandler',
|
|
14
16
|
},
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
+
}),
|
|
18
|
+
...(distinct && {
|
|
19
|
+
distinct,
|
|
20
|
+
}),
|
|
21
|
+
...(typeof useDistinctUntilChanged === 'boolean' && {
|
|
22
|
+
useDistinctUntilChanged,
|
|
23
|
+
}),
|
|
24
|
+
},
|
|
17
25
|
});
|
|
18
26
|
}
|
|
19
27
|
getActions() {
|
|
@@ -24,11 +32,53 @@ class TestSignalStateHandler extends SignalStateHandler {
|
|
|
24
32
|
};
|
|
25
33
|
}
|
|
26
34
|
}
|
|
35
|
+
class CounterSignalStateHandler extends SignalStateHandler {
|
|
36
|
+
constructor(initialCount = 0) {
|
|
37
|
+
super({
|
|
38
|
+
initialState: {
|
|
39
|
+
count: initialCount,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
getActions() {
|
|
44
|
+
return {
|
|
45
|
+
increase: () => {
|
|
46
|
+
this.setState({ count: this.getState().count + 1 }, 'increase');
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
class CounterSignalBridgeStateHandler extends SignalStateHandler {
|
|
52
|
+
constructor(counterSingleton, onCounterSync) {
|
|
53
|
+
super({
|
|
54
|
+
initialState: {
|
|
55
|
+
count: 0,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
const counterStateHandler = counterSingleton.getInstance();
|
|
59
|
+
this.bindSubscribable({
|
|
60
|
+
subscribe: (listener) => counterStateHandler.subscribe(() => listener(counterStateHandler.getSnapshot())),
|
|
61
|
+
getSnapshot: () => counterStateHandler.getSnapshot(),
|
|
62
|
+
}, (nextCounterState) => {
|
|
63
|
+
onCounterSync(nextCounterState);
|
|
64
|
+
this.setState({ count: nextCounterState.count }, 'sync-counter');
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
getActions() {
|
|
68
|
+
return {
|
|
69
|
+
noop: () => undefined,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
27
73
|
describe('Signal State Handler', () => {
|
|
28
74
|
let stateHandler;
|
|
29
75
|
beforeEach(() => {
|
|
76
|
+
resetStatusQuoForTests();
|
|
30
77
|
stateHandler = new TestSignalStateHandler();
|
|
31
78
|
});
|
|
79
|
+
afterEach(() => {
|
|
80
|
+
resetStatusQuoForTests();
|
|
81
|
+
});
|
|
32
82
|
it('should provide initial state', () => {
|
|
33
83
|
expect(stateHandler.getInitialState()).toStrictEqual({
|
|
34
84
|
test: 'testValue',
|
|
@@ -74,5 +124,69 @@ describe('Signal State Handler', () => {
|
|
|
74
124
|
unsubscribe();
|
|
75
125
|
expect(spy).toHaveBeenCalledTimes(2);
|
|
76
126
|
});
|
|
127
|
+
it('should respect global distinct setup when disabled', () => {
|
|
128
|
+
setupStatusQuo({
|
|
129
|
+
distinct: {
|
|
130
|
+
enabled: false,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
const handler = new TestSignalStateHandler();
|
|
134
|
+
const spy = jest.fn();
|
|
135
|
+
const unsubscribe = handler.subscribe(spy);
|
|
136
|
+
handler.setState({ test: 'same' });
|
|
137
|
+
handler.setState({ test: 'same' });
|
|
138
|
+
unsubscribe();
|
|
139
|
+
expect(spy).toHaveBeenCalledTimes(2);
|
|
140
|
+
});
|
|
141
|
+
it('should respect global custom distinct comparator from setupStatusQuo', () => {
|
|
142
|
+
setupStatusQuo({
|
|
143
|
+
distinct: {
|
|
144
|
+
comparator: (previous, next) => {
|
|
145
|
+
return previous.test === next.test;
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
const handler = new TestSignalStateHandler();
|
|
150
|
+
const spy = jest.fn();
|
|
151
|
+
const unsubscribe = handler.subscribe(spy);
|
|
152
|
+
handler.setState({ test2: 'newValue2' });
|
|
153
|
+
handler.setState({ test: 'newValue' });
|
|
154
|
+
unsubscribe();
|
|
155
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
156
|
+
});
|
|
157
|
+
it('should prefer per-handler distinct options over global setup', () => {
|
|
158
|
+
setupStatusQuo({
|
|
159
|
+
distinct: {
|
|
160
|
+
enabled: false,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
const handler = new TestSignalStateHandler({
|
|
164
|
+
distinct: {
|
|
165
|
+
enabled: true,
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
const spy = jest.fn();
|
|
169
|
+
const unsubscribe = handler.subscribe(spy);
|
|
170
|
+
handler.setState({ test: 'same' });
|
|
171
|
+
handler.setState({ test: 'same' });
|
|
172
|
+
unsubscribe();
|
|
173
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
174
|
+
});
|
|
175
|
+
it('should notify another signal state handler for each singleton counter update', () => {
|
|
176
|
+
const counterSingleton = makeStateSingleton(() => new CounterSignalStateHandler(0), {
|
|
177
|
+
destroyOnNoConsumers: false,
|
|
178
|
+
});
|
|
179
|
+
const syncSpy = jest.fn();
|
|
180
|
+
const bridgeStateHandler = new CounterSignalBridgeStateHandler(counterSingleton, syncSpy);
|
|
181
|
+
const counterStateHandler = counterSingleton.getInstance();
|
|
182
|
+
counterStateHandler.getActions().increase();
|
|
183
|
+
counterStateHandler.getActions().increase();
|
|
184
|
+
expect(syncSpy).toHaveBeenCalledTimes(3);
|
|
185
|
+
expect(syncSpy).toHaveBeenNthCalledWith(1, { count: 0 });
|
|
186
|
+
expect(syncSpy).toHaveBeenNthCalledWith(2, { count: 1 });
|
|
187
|
+
expect(syncSpy).toHaveBeenNthCalledWith(3, { count: 2 });
|
|
188
|
+
expect(bridgeStateHandler.getState()).toStrictEqual({ count: 2 });
|
|
189
|
+
bridgeStateHandler.destroy();
|
|
190
|
+
});
|
|
77
191
|
});
|
|
78
192
|
//# sourceMappingURL=signal-state-handler.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signal-state-handler.spec.js","sourceRoot":"","sources":["../../../src/store/__tests__/signal-state-handler.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"signal-state-handler.spec.js","sourceRoot":"","sources":["../../../src/store/__tests__/signal-state-handler.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BehaviorSubject } from 'rxjs';
|
|
2
1
|
import { BaseStateHandler } from './base-state-handler.js';
|
|
3
2
|
import type { Observable } from 'rxjs';
|
|
3
|
+
import type { DistinctOptions } from '../config/status-quo-config.js';
|
|
4
4
|
type ObservableStateHandlerProps<S> = {
|
|
5
5
|
initialState: S;
|
|
6
6
|
options?: {
|
|
@@ -8,6 +8,8 @@ type ObservableStateHandlerProps<S> = {
|
|
|
8
8
|
enabled?: boolean;
|
|
9
9
|
namespace: string;
|
|
10
10
|
};
|
|
11
|
+
distinct?: DistinctOptions<S>;
|
|
12
|
+
useDistinctUntilChanged?: boolean;
|
|
11
13
|
};
|
|
12
14
|
};
|
|
13
15
|
type StateObservableOptions = {
|
|
@@ -15,11 +17,12 @@ type StateObservableOptions = {
|
|
|
15
17
|
};
|
|
16
18
|
export declare abstract class ObservableStateHandler<S, A> extends BaseStateHandler<S, A> {
|
|
17
19
|
private readonly state$;
|
|
20
|
+
private readonly distinctOptions;
|
|
18
21
|
protected constructor({ initialState, options }: ObservableStateHandlerProps<S>);
|
|
19
22
|
protected getStateValue(): S;
|
|
20
23
|
protected setStateValue(nextState: S): void;
|
|
21
24
|
getStateItemAsObservable(key: keyof S): Observable<S[keyof S]>;
|
|
22
|
-
getStateAsObservable(options?: StateObservableOptions):
|
|
25
|
+
getStateAsObservable(options?: StateObservableOptions): Observable<S>;
|
|
23
26
|
getObservable(key: keyof S): Observable<S[keyof S]>;
|
|
24
27
|
/** @deprecated Use getObservable instead. */
|
|
25
28
|
getObservableItem(key: keyof S): Observable<S[keyof S]>;
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import { BehaviorSubject, distinctUntilKeyChanged, map
|
|
1
|
+
import { BehaviorSubject, distinctUntilChanged, distinctUntilKeyChanged, map } from 'rxjs';
|
|
2
2
|
import { BaseStateHandler } from './base-state-handler.js';
|
|
3
|
-
|
|
4
|
-
return pipe(distinctUntilChanged((a, b) => {
|
|
5
|
-
return JSON.stringify(a) === JSON.stringify(b);
|
|
6
|
-
}));
|
|
7
|
-
}
|
|
8
|
-
const pipeMap = {
|
|
9
|
-
useDistinctUntilChanged: distinctUntilChangedAsJson(),
|
|
10
|
-
};
|
|
3
|
+
import { resolveDistinctOptions } from '../config/status-quo-config.js';
|
|
11
4
|
export class ObservableStateHandler extends BaseStateHandler {
|
|
12
5
|
state$;
|
|
6
|
+
distinctOptions;
|
|
13
7
|
constructor({ initialState, options }) {
|
|
14
8
|
super(initialState);
|
|
15
9
|
this.state$ = new BehaviorSubject(initialState);
|
|
10
|
+
this.distinctOptions = resolveDistinctOptions(options?.distinct, options?.useDistinctUntilChanged);
|
|
16
11
|
this.initDevTools(options?.devTools);
|
|
17
12
|
}
|
|
18
13
|
getStateValue() {
|
|
@@ -24,18 +19,14 @@ export class ObservableStateHandler extends BaseStateHandler {
|
|
|
24
19
|
getStateItemAsObservable(key) {
|
|
25
20
|
return this.state$.pipe(distinctUntilKeyChanged(key), map((state) => state[key]));
|
|
26
21
|
}
|
|
27
|
-
getStateAsObservable(options = {
|
|
28
|
-
useDistinctUntilChanged
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
.map((enabledOptions) => pipeMap[enabledOptions])
|
|
36
|
-
.reduce((stateObservable$, operator) => {
|
|
37
|
-
return stateObservable$.pipe(operator);
|
|
38
|
-
}, this.state$);
|
|
22
|
+
getStateAsObservable(options = {}) {
|
|
23
|
+
const useDistinctUntilChanged = options.useDistinctUntilChanged ?? this.distinctOptions.enabled;
|
|
24
|
+
if (!useDistinctUntilChanged) {
|
|
25
|
+
return this.state$;
|
|
26
|
+
}
|
|
27
|
+
return this.state$.pipe(distinctUntilChanged((previous, next) => {
|
|
28
|
+
return this.distinctOptions.comparator(previous, next);
|
|
29
|
+
}));
|
|
39
30
|
}
|
|
40
31
|
getObservable(key) {
|
|
41
32
|
return this.getStateItemAsObservable(key);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observable-state-handler.js","sourceRoot":"","sources":["../../src/store/observable-state-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"observable-state-handler.js","sourceRoot":"","sources":["../../src/store/observable-state-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAE3F,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAmBxE,MAAM,OAAgB,sBAA6B,SAAQ,gBAAsB;IAC9D,MAAM,CAAqB;IAC3B,eAAe,CAA+C;IAE/E,YAAsB,EAAE,YAAY,EAAE,OAAO,EAAkC;QAC7E,KAAK,CAAC,YAAY,CAAC,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAAI,YAAY,CAAC,CAAC;QACnD,IAAI,CAAC,eAAe,GAAG,sBAAsB,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAAC;QACnG,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;IAES,aAAa;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;IAES,aAAa,CAAC,SAAY;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IAED,wBAAwB,CAAC,GAAY;QACnC,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CACrB,uBAAuB,CAAC,GAAG,CAAC,EAC5B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAC3B,CAAC;IACJ,CAAC;IAED,oBAAoB,CAAC,UAAkC,EAAE;QACvD,MAAM,uBAAuB,GAC3B,OAAO,CAAC,uBAAuB,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;QAElE,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CACrB,oBAAoB,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE;YACtC,OAAO,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACzD,CAAC,CAAC,CACc,CAAC;IACrB,CAAC;IAED,aAAa,CAAC,GAAY;QACxB,OAAO,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,6CAA6C;IAC7C,iBAAiB,CAAC,GAAY;QAC5B,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,SAAS,CAAC,QAAoB;QAC5B,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE;YAC9D,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,WAAW,GAAG,IAAI,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;IAC1C,CAAC;CACF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BaseStateHandler } from './base-state-handler.js';
|
|
2
2
|
import type { Signal } from '@preact/signals-core';
|
|
3
|
+
import type { DistinctOptions } from '../config/status-quo-config.js';
|
|
3
4
|
type SignalStateHandlerProps<S> = {
|
|
4
5
|
initialState: S;
|
|
5
6
|
options?: {
|
|
@@ -7,19 +8,18 @@ type SignalStateHandlerProps<S> = {
|
|
|
7
8
|
enabled?: boolean;
|
|
8
9
|
namespace: string;
|
|
9
10
|
};
|
|
11
|
+
distinct?: DistinctOptions<S>;
|
|
10
12
|
useDistinctUntilChanged?: boolean;
|
|
11
13
|
};
|
|
12
14
|
};
|
|
13
15
|
type Listener = () => void;
|
|
14
16
|
export declare abstract class SignalStateHandler<S, A> extends BaseStateHandler<S, A> {
|
|
15
17
|
private readonly state;
|
|
16
|
-
private readonly
|
|
17
|
-
private readonly useDistinctUntilChanged;
|
|
18
|
+
private readonly distinctOptions;
|
|
18
19
|
protected constructor({ initialState, options }: SignalStateHandlerProps<S>);
|
|
19
20
|
getSignal(): Signal<S>;
|
|
20
21
|
subscribe(listener: Listener): () => void;
|
|
21
22
|
protected getStateValue(): S;
|
|
22
23
|
protected setStateValue(nextState: S): void;
|
|
23
|
-
private notify;
|
|
24
24
|
}
|
|
25
25
|
export {};
|