@veams/status-quo 1.9.0 → 1.11.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 (65) hide show
  1. package/.turbo/turbo-build.log +14 -12
  2. package/README.md +33 -4
  3. package/dist/index.d.ts +2 -2
  4. package/dist/index.js +2 -6
  5. package/dist/index.js.map +1 -1
  6. package/dist/observable/index.d.ts +5 -0
  7. package/dist/observable/index.js +6 -0
  8. package/dist/observable/index.js.map +1 -0
  9. package/dist/signals/index.d.ts +5 -0
  10. package/dist/signals/index.js +6 -0
  11. package/dist/signals/index.js.map +1 -0
  12. package/dist/store/__tests__/native-state-handler.spec.js +69 -0
  13. package/dist/store/__tests__/native-state-handler.spec.js.map +1 -1
  14. package/dist/store/__tests__/observable-state-handler.spec.js +6 -0
  15. package/dist/store/__tests__/observable-state-handler.spec.js.map +1 -1
  16. package/dist/store/__tests__/signal-state-handler.spec.js +69 -0
  17. package/dist/store/__tests__/signal-state-handler.spec.js.map +1 -1
  18. package/dist/store/base-state-handler.d.ts +7 -3
  19. package/dist/store/base-state-handler.js +27 -6
  20. package/dist/store/base-state-handler.js.map +1 -1
  21. package/dist/store/index.d.ts +0 -2
  22. package/dist/store/index.js +0 -4
  23. package/dist/store/index.js.map +1 -1
  24. package/package.json +15 -1
  25. package/src/index.ts +0 -6
  26. package/src/observable/index.ts +5 -0
  27. package/src/signals/index.ts +5 -0
  28. package/src/store/__tests__/native-state-handler.spec.ts +92 -0
  29. package/src/store/__tests__/observable-state-handler.spec.ts +10 -0
  30. package/src/store/__tests__/signal-state-handler.spec.ts +92 -0
  31. package/src/store/base-state-handler.ts +59 -9
  32. package/src/store/index.ts +0 -4
  33. package/dist/hooks/__tests__/state-provider.spec.d.ts +0 -4
  34. package/dist/hooks/__tests__/state-provider.spec.js +0 -179
  35. package/dist/hooks/__tests__/state-provider.spec.js.map +0 -1
  36. package/dist/hooks/__tests__/state-selector.spec.d.ts +0 -4
  37. package/dist/hooks/__tests__/state-selector.spec.js +0 -499
  38. package/dist/hooks/__tests__/state-selector.spec.js.map +0 -1
  39. package/dist/hooks/__tests__/state-singleton.spec.d.ts +0 -4
  40. package/dist/hooks/__tests__/state-singleton.spec.js +0 -96
  41. package/dist/hooks/__tests__/state-singleton.spec.js.map +0 -1
  42. package/dist/hooks/index.d.ts +0 -6
  43. package/dist/hooks/index.js +0 -7
  44. package/dist/hooks/index.js.map +0 -1
  45. package/dist/hooks/state-actions.d.ts +0 -2
  46. package/dist/hooks/state-actions.js +0 -5
  47. package/dist/hooks/state-actions.js.map +0 -1
  48. package/dist/hooks/state-factory.d.ts +0 -7
  49. package/dist/hooks/state-factory.js +0 -13
  50. package/dist/hooks/state-factory.js.map +0 -1
  51. package/dist/hooks/state-handler.d.ts +0 -2
  52. package/dist/hooks/state-handler.js +0 -9
  53. package/dist/hooks/state-handler.js.map +0 -1
  54. package/dist/hooks/state-provider.d.ts +0 -14
  55. package/dist/hooks/state-provider.js +0 -24
  56. package/dist/hooks/state-provider.js.map +0 -1
  57. package/dist/hooks/state-singleton.d.ts +0 -6
  58. package/dist/hooks/state-singleton.js +0 -7
  59. package/dist/hooks/state-singleton.js.map +0 -1
  60. package/dist/hooks/state-subscription-selector.d.ts +0 -3
  61. package/dist/hooks/state-subscription-selector.js +0 -63
  62. package/dist/hooks/state-subscription-selector.js.map +0 -1
  63. package/dist/hooks/state-subscription.d.ts +0 -9
  64. package/dist/hooks/state-subscription.js +0 -53
  65. package/dist/hooks/state-subscription.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"base-state-handler.js","sourceRoot":"","sources":["../../src/store/base-state-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-state-handler.js","sourceRoot":"","sources":["../../src/store/base-state-handler.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,6 @@
3
3
  */
4
4
  export { BaseStateHandler } from './base-state-handler.js';
5
5
  export { NativeStateHandler } from './native-state-handler.js';
6
- export { ObservableStateHandler } from './observable-state-handler.js';
7
- export { SignalStateHandler } from './signal-state-handler.js';
8
6
  /**
9
7
  * Export singleton related types and factory function.
10
8
  */
@@ -5,10 +5,6 @@
5
5
  export { BaseStateHandler } from './base-state-handler.js';
6
6
  // Export the lightweight state handler using plain JavaScript.
7
7
  export { NativeStateHandler } from './native-state-handler.js';
8
- // Export the state handler powered by RxJS BehaviorSubjects.
9
- export { ObservableStateHandler } from './observable-state-handler.js';
10
- // Export the state handler powered by Preact Signals.
11
- export { SignalStateHandler } from './signal-state-handler.js';
12
8
  // Export the factory function to create singleton state handler instances.
13
9
  export { makeStateSingleton } from './state-singleton.js';
14
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,yDAAyD;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,+DAA+D;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,6DAA6D;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,sDAAsD;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,2EAA2E;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,yDAAyD;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,+DAA+D;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,2EAA2E;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veams/status-quo",
3
- "version": "1.9.0",
3
+ "version": "1.11.0",
4
4
  "description": "The manager to rule states in frontend.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -25,6 +25,20 @@
25
25
  "default": "./dist/store/index.js"
26
26
  },
27
27
  "require": "./dist/store/index.js"
28
+ },
29
+ "./observable": {
30
+ "import": {
31
+ "types": "./dist/observable/index.d.ts",
32
+ "default": "./dist/observable/index.js"
33
+ },
34
+ "require": "./dist/observable/index.js"
35
+ },
36
+ "./signals": {
37
+ "import": {
38
+ "types": "./dist/signals/index.d.ts",
39
+ "default": "./dist/signals/index.js"
40
+ },
41
+ "require": "./dist/signals/index.js"
28
42
  }
29
43
  },
30
44
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -9,8 +9,6 @@ import {
9
9
  BaseStateHandler,
10
10
  makeStateSingleton,
11
11
  NativeStateHandler,
12
- ObservableStateHandler,
13
- SignalStateHandler,
14
12
  } from './store/index.js';
15
13
 
16
14
  // Import necessary types for external use.
@@ -34,12 +32,8 @@ export {
34
32
  makeStateSingleton,
35
33
  // Lightweight state handler using plain JavaScript.
36
34
  NativeStateHandler,
37
- // State handler powered by RxJS BehaviorSubjects.
38
- ObservableStateHandler,
39
35
  // Global configuration function for Status Quo.
40
36
  setupStatusQuo,
41
- // State handler powered by Preact Signals.
42
- SignalStateHandler,
43
37
  };
44
38
 
45
39
  /**
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Subpath entry for the RxJS-based ObservableStateHandler.
3
+ * Import from '@veams/status-quo/observable' to avoid pulling rxjs into the main bundle.
4
+ */
5
+ export { ObservableStateHandler } from '../store/observable-state-handler.js';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Subpath entry for the Preact Signals-based SignalStateHandler.
3
+ * Import from '@veams/status-quo/signals' to avoid pulling @preact/signals-core into the main bundle.
4
+ */
5
+ export { SignalStateHandler } from '../store/signal-state-handler.js';
@@ -51,6 +51,10 @@ type CounterBucketSelection = { bucket: number };
51
51
  type CounterBucketState = { bucket: number };
52
52
  type SetState = { openItems: Set<string> };
53
53
  type SetActions = { toggle: (id: string) => void };
54
+ type CounterSubscribable = {
55
+ subscribe: (listener: (value: CounterState) => void) => () => void;
56
+ getSnapshot: () => CounterState;
57
+ };
54
58
 
55
59
  class CounterNativeStateHandler extends NativeStateHandler<CounterState, CounterActions> {
56
60
  constructor(initialCount = 0) {
@@ -139,6 +143,37 @@ class CounterNativeBucketBridgeStateHandler extends NativeStateHandler<
139
143
  }
140
144
  }
141
145
 
146
+ class CounterNamedNativeBridgeStateHandler extends NativeStateHandler<
147
+ CounterState,
148
+ { noop: () => void }
149
+ > {
150
+ constructor(private readonly onCounterSync: (counterState: CounterState) => void) {
151
+ super({
152
+ initialState: {
153
+ count: -1,
154
+ },
155
+ });
156
+ }
157
+
158
+ bindNamedCounter(service: CounterSubscribable, subscriptionName = 'namedSubscription') {
159
+ this.bindSubscribable<CounterState, CounterState>(
160
+ subscriptionName,
161
+ service,
162
+ (nextCounterState) => {
163
+ this.onCounterSync(nextCounterState);
164
+ this.setState({ count: nextCounterState.count }, 'sync-counter');
165
+ },
166
+ (counterState) => counterState
167
+ );
168
+ }
169
+
170
+ getActions(): { noop: () => void } {
171
+ return {
172
+ noop: () => undefined,
173
+ };
174
+ }
175
+ }
176
+
142
177
  class SetNativeStateHandler extends NativeStateHandler<SetState, SetActions> {
143
178
  constructor() {
144
179
  super({
@@ -165,6 +200,27 @@ class SetNativeStateHandler extends NativeStateHandler<SetState, SetActions> {
165
200
  }
166
201
  }
167
202
 
203
+ function createCounterSubscribable(initialCount: number) {
204
+ let listener: ((value: CounterState) => void) | null = null;
205
+ const unsubscribe = jest.fn(() => {
206
+ listener = null;
207
+ });
208
+
209
+ return {
210
+ emit(value: CounterState) {
211
+ listener?.(value);
212
+ },
213
+ service: {
214
+ getSnapshot: () => ({ count: initialCount }),
215
+ subscribe: (nextListener: (value: CounterState) => void) => {
216
+ listener = nextListener;
217
+ return unsubscribe;
218
+ },
219
+ } satisfies CounterSubscribable,
220
+ unsubscribe,
221
+ };
222
+ }
223
+
168
224
  describe('Native State Handler', () => {
169
225
  let stateHandler: TestNativeStateHandler;
170
226
 
@@ -329,4 +385,40 @@ describe('Native State Handler', () => {
329
385
 
330
386
  bridgeStateHandler.destroy();
331
387
  });
388
+
389
+ it('should replace named bindSubscribable subscriptions when bound again with the same key', () => {
390
+ const syncSpy = jest.fn();
391
+ const bridgeStateHandler = new CounterNamedNativeBridgeStateHandler(syncSpy);
392
+ const firstCounter = createCounterSubscribable(1);
393
+ const secondCounter = createCounterSubscribable(5);
394
+
395
+ bridgeStateHandler.bindNamedCounter(firstCounter.service);
396
+ bridgeStateHandler.bindNamedCounter(secondCounter.service);
397
+
398
+ firstCounter.emit({ count: 2 });
399
+ secondCounter.emit({ count: 6 });
400
+
401
+ expect(firstCounter.unsubscribe).toHaveBeenCalledTimes(1);
402
+ expect(secondCounter.unsubscribe).toHaveBeenCalledTimes(0);
403
+ expect(syncSpy).toHaveBeenCalledTimes(3);
404
+ expect(syncSpy).toHaveBeenNthCalledWith(1, { count: 1 });
405
+ expect(syncSpy).toHaveBeenNthCalledWith(2, { count: 5 });
406
+ expect(syncSpy).toHaveBeenNthCalledWith(3, { count: 6 });
407
+ expect(bridgeStateHandler.getState()).toStrictEqual({ count: 6 });
408
+
409
+ bridgeStateHandler.destroy();
410
+ });
411
+
412
+ it('should unsubscribe named bindSubscribable subscriptions on destroy', () => {
413
+ const syncSpy = jest.fn();
414
+ const bridgeStateHandler = new CounterNamedNativeBridgeStateHandler(syncSpy);
415
+ const counter = createCounterSubscribable(3);
416
+
417
+ bridgeStateHandler.bindNamedCounter(counter.service);
418
+ bridgeStateHandler.destroy();
419
+ counter.emit({ count: 4 });
420
+
421
+ expect(counter.unsubscribe).toHaveBeenCalledTimes(1);
422
+ expect(syncSpy).toHaveBeenCalledTimes(1);
423
+ });
332
424
  });
@@ -124,6 +124,16 @@ describe('Observable State Handler', () => {
124
124
  expect(spy).toHaveBeenCalledTimes(1);
125
125
  });
126
126
 
127
+ it('should destroy named subscriptions as well', () => {
128
+ const spy = jest.fn();
129
+
130
+ stateHandler.namedSubscriptions.set('namedSubscription', { unsubscribe: spy });
131
+
132
+ stateHandler.destroy();
133
+
134
+ expect(spy).toHaveBeenCalledTimes(1);
135
+ });
136
+
127
137
  it('should expose state item observable via getObservableItem', async () => {
128
138
  const observableValue = await lastValueFrom(stateHandler.getObservableItem('test').pipe(take(1)));
129
139
 
@@ -49,6 +49,10 @@ type CounterState = { count: number };
49
49
  type CounterActions = { increase: () => void };
50
50
  type CounterBucketSelection = { bucket: number };
51
51
  type CounterBucketState = { bucket: number };
52
+ type CounterSubscribable = {
53
+ subscribe: (listener: (value: CounterState) => void) => () => void;
54
+ getSnapshot: () => CounterState;
55
+ };
52
56
 
53
57
  class CounterSignalStateHandler extends SignalStateHandler<CounterState, CounterActions> {
54
58
  constructor(initialCount = 0) {
@@ -137,6 +141,58 @@ class CounterSignalBucketBridgeStateHandler extends SignalStateHandler<
137
141
  }
138
142
  }
139
143
 
144
+ class CounterNamedSignalBridgeStateHandler extends SignalStateHandler<
145
+ CounterState,
146
+ { noop: () => void }
147
+ > {
148
+ constructor(private readonly onCounterSync: (counterState: CounterState) => void) {
149
+ super({
150
+ initialState: {
151
+ count: -1,
152
+ },
153
+ });
154
+ }
155
+
156
+ bindNamedCounter(service: CounterSubscribable, subscriptionName = 'namedSubscription') {
157
+ this.bindSubscribable<CounterState, CounterState>(
158
+ subscriptionName,
159
+ service,
160
+ (nextCounterState) => {
161
+ this.onCounterSync(nextCounterState);
162
+ this.setState({ count: nextCounterState.count }, 'sync-counter');
163
+ },
164
+ (counterState) => counterState
165
+ );
166
+ }
167
+
168
+ getActions(): { noop: () => void } {
169
+ return {
170
+ noop: () => undefined,
171
+ };
172
+ }
173
+ }
174
+
175
+ function createCounterSubscribable(initialCount: number) {
176
+ let listener: ((value: CounterState) => void) | null = null;
177
+ const unsubscribe = jest.fn(() => {
178
+ listener = null;
179
+ });
180
+
181
+ return {
182
+ emit(value: CounterState) {
183
+ listener?.(value);
184
+ },
185
+ service: {
186
+ getSnapshot: () => ({ count: initialCount }),
187
+ subscribe: (nextListener: (value: CounterState) => void) => {
188
+ listener = nextListener;
189
+ return unsubscribe;
190
+ },
191
+ } satisfies CounterSubscribable,
192
+ unsubscribe,
193
+ };
194
+ }
195
+
140
196
  describe('Signal State Handler', () => {
141
197
  let stateHandler: TestSignalStateHandler;
142
198
 
@@ -311,4 +367,40 @@ describe('Signal State Handler', () => {
311
367
 
312
368
  bridgeStateHandler.destroy();
313
369
  });
370
+
371
+ it('should replace named bindSubscribable subscriptions when bound again with the same key', () => {
372
+ const syncSpy = jest.fn();
373
+ const bridgeStateHandler = new CounterNamedSignalBridgeStateHandler(syncSpy);
374
+ const firstCounter = createCounterSubscribable(1);
375
+ const secondCounter = createCounterSubscribable(5);
376
+
377
+ bridgeStateHandler.bindNamedCounter(firstCounter.service);
378
+ bridgeStateHandler.bindNamedCounter(secondCounter.service);
379
+
380
+ firstCounter.emit({ count: 2 });
381
+ secondCounter.emit({ count: 6 });
382
+
383
+ expect(firstCounter.unsubscribe).toHaveBeenCalledTimes(1);
384
+ expect(secondCounter.unsubscribe).toHaveBeenCalledTimes(0);
385
+ expect(syncSpy).toHaveBeenCalledTimes(3);
386
+ expect(syncSpy).toHaveBeenNthCalledWith(1, { count: 1 });
387
+ expect(syncSpy).toHaveBeenNthCalledWith(2, { count: 5 });
388
+ expect(syncSpy).toHaveBeenNthCalledWith(3, { count: 6 });
389
+ expect(bridgeStateHandler.getState()).toStrictEqual({ count: 6 });
390
+
391
+ bridgeStateHandler.destroy();
392
+ });
393
+
394
+ it('should unsubscribe named bindSubscribable subscriptions on destroy', () => {
395
+ const syncSpy = jest.fn();
396
+ const bridgeStateHandler = new CounterNamedSignalBridgeStateHandler(syncSpy);
397
+ const counter = createCounterSubscribable(3);
398
+
399
+ bridgeStateHandler.bindNamedCounter(counter.service);
400
+ bridgeStateHandler.destroy();
401
+ counter.emit({ count: 4 });
402
+
403
+ expect(counter.unsubscribe).toHaveBeenCalledTimes(1);
404
+ expect(syncSpy).toHaveBeenCalledTimes(1);
405
+ });
314
406
  });
@@ -23,6 +23,10 @@ type Subscribable<T> = {
23
23
  getSnapshot?: () => T;
24
24
  };
25
25
 
26
+ type ManagedSubscription = {
27
+ unsubscribe: () => void;
28
+ };
29
+
26
30
  /**
27
31
  * Configuration for Redux DevTools features enabled in this handler.
28
32
  */
@@ -50,7 +54,9 @@ export abstract class BaseStateHandler<S, A> implements StateSubscriptionHandler
50
54
  protected devTools: DevTools | null = null;
51
55
 
52
56
  // Keeps track of active subscriptions to allow for cleanup.
53
- subscriptions: Array<{ unsubscribe: () => void }> = [];
57
+ subscriptions: ManagedSubscription[] = [];
58
+ // Tracks keyed subscriptions so handlers can replace them by name.
59
+ namedSubscriptions = new Map<string, ManagedSubscription>();
54
60
 
55
61
  /**
56
62
  * Initializes the handler with the given initial state.
@@ -125,8 +131,15 @@ export abstract class BaseStateHandler<S, A> implements StateSubscriptionHandler
125
131
  * Cleans up all active subscriptions when the handler is destroyed.
126
132
  */
127
133
  destroy(): void {
134
+ const subscriptions = [...this.subscriptions];
135
+ const namedSubscriptions = [...this.namedSubscriptions.values()];
136
+
137
+ this.subscriptions = [];
138
+ this.namedSubscriptions.clear();
139
+
128
140
  // Execute the unsubscribe function for each tracked subscription.
129
- this.subscriptions.forEach((subscription) => subscription.unsubscribe());
141
+ subscriptions.forEach((subscription) => subscription.unsubscribe());
142
+ namedSubscriptions.forEach((subscription) => subscription.unsubscribe());
130
143
  }
131
144
 
132
145
  // Abstract methods to be implemented by concrete handlers for specific state engines (RxJS, Signals, etc.).
@@ -145,18 +158,46 @@ export abstract class BaseStateHandler<S, A> implements StateSubscriptionHandler
145
158
  * Useful for bridging different state systems.
146
159
  */
147
160
  protected bindSubscribable<T, Sel>(
161
+ subscriptionName: string,
148
162
  service: Subscribable<T>,
149
163
  onChange: (value: Sel) => void,
150
164
  selector: Selector<T, Sel>,
151
165
  isEqual?: EqualityFn<Sel>
152
166
  ): void;
153
- protected bindSubscribable<T>(service: Subscribable<T>, onChange: (value: T) => void): void;
154
- protected bindSubscribable<T, Sel = T>(
167
+ protected bindSubscribable<T>(
168
+ subscriptionName: string,
169
+ service: Subscribable<T>,
170
+ onChange: (value: T) => void
171
+ ): void;
172
+ protected bindSubscribable<T, Sel>(
155
173
  service: Subscribable<T>,
156
174
  onChange: (value: Sel) => void,
157
- selector?: Selector<T, Sel>,
175
+ selector: Selector<T, Sel>,
176
+ isEqual?: EqualityFn<Sel>
177
+ ): void;
178
+ protected bindSubscribable<T>(service: Subscribable<T>, onChange: (value: T) => void): void;
179
+ protected bindSubscribable<T, Sel = T>(
180
+ subscriptionNameOrService: string | Subscribable<T>,
181
+ serviceOrOnChange: Subscribable<T> | ((value: Sel) => void),
182
+ onChangeOrSelector?: ((value: Sel) => void) | Selector<T, Sel>,
183
+ selectorOrIsEqual?: Selector<T, Sel> | EqualityFn<Sel>,
158
184
  isEqual: EqualityFn<Sel> = Object.is
159
185
  ) {
186
+ const hasSubscriptionName = typeof subscriptionNameOrService === 'string';
187
+ const subscriptionName = hasSubscriptionName ? subscriptionNameOrService : null;
188
+ const service = (
189
+ hasSubscriptionName ? serviceOrOnChange : subscriptionNameOrService
190
+ ) as Subscribable<T>;
191
+ const onChange = (
192
+ hasSubscriptionName ? onChangeOrSelector : serviceOrOnChange
193
+ ) as (value: Sel) => void;
194
+ const selector = (
195
+ hasSubscriptionName ? selectorOrIsEqual : onChangeOrSelector
196
+ ) as Selector<T, Sel> | undefined;
197
+ const equalityFn = (
198
+ hasSubscriptionName ? isEqual : (selectorOrIsEqual ?? Object.is)
199
+ ) as EqualityFn<Sel>;
200
+
160
201
  // Default to identity selector if none is provided.
161
202
  const selectorFn = (selector ?? ((value: T) => value as unknown as Sel));
162
203
  // Create a cache for selector results to avoid unnecessary updates.
@@ -172,7 +213,7 @@ export abstract class BaseStateHandler<S, A> implements StateSubscriptionHandler
172
213
  selectorCache,
173
214
  value,
174
215
  selectorFn,
175
- isEqual
216
+ equalityFn
176
217
  );
177
218
 
178
219
  // Only trigger the callback if the selected value changed.
@@ -183,10 +224,19 @@ export abstract class BaseStateHandler<S, A> implements StateSubscriptionHandler
183
224
  onChange(nextSelection);
184
225
  };
185
226
 
227
+ if (subscriptionName) {
228
+ this.namedSubscriptions.get(subscriptionName)?.unsubscribe();
229
+ }
230
+
186
231
  // Subscribe to the external source.
187
- const unsubscribe = service.subscribe(notifySelectedValue);
188
- // Track the subscription for later cleanup.
189
- this.subscriptions = [...(this.subscriptions ?? []), { unsubscribe }];
232
+ const subscription = { unsubscribe: service.subscribe(notifySelectedValue) };
233
+
234
+ if (subscriptionName) {
235
+ this.namedSubscriptions.set(subscriptionName, subscription);
236
+ } else {
237
+ // Track the subscription for later cleanup.
238
+ this.subscriptions = [...(this.subscriptions ?? []), subscription];
239
+ }
190
240
 
191
241
  // If the source has a getSnapshot method and we haven't received a value yet, pull it manually.
192
242
  if (service.getSnapshot && !receivedSyncValue) notifySelectedValue(service.getSnapshot());
@@ -6,10 +6,6 @@
6
6
  export { BaseStateHandler } from './base-state-handler.js';
7
7
  // Export the lightweight state handler using plain JavaScript.
8
8
  export { NativeStateHandler } from './native-state-handler.js';
9
- // Export the state handler powered by RxJS BehaviorSubjects.
10
- export { ObservableStateHandler } from './observable-state-handler.js';
11
- // Export the state handler powered by Preact Signals.
12
- export { SignalStateHandler } from './signal-state-handler.js';
13
9
 
14
10
  /**
15
11
  * Export singleton related types and factory function.
@@ -1,4 +0,0 @@
1
- declare global {
2
- var IS_REACT_ACT_ENVIRONMENT: boolean;
3
- }
4
- export {};
@@ -1,179 +0,0 @@
1
- import React, { act } from 'react';
2
- import { createRoot } from 'react-dom/client';
3
- import { StateProvider, useProvidedStateActions, useProvidedStateHandler, useProvidedStateSubscription, } from '../state-provider.js';
4
- class TestStateHandler {
5
- initialState;
6
- state;
7
- listeners = new Set();
8
- destroy = jest.fn();
9
- constructor(initialState) {
10
- this.initialState = initialState;
11
- this.state = initialState;
12
- }
13
- subscribe(listener) {
14
- const typedListener = listener;
15
- this.listeners.add(typedListener);
16
- return () => {
17
- this.listeners.delete(typedListener);
18
- };
19
- }
20
- getSnapshot = () => {
21
- return this.state;
22
- };
23
- getInitialState = () => {
24
- return this.initialState;
25
- };
26
- getActions = () => {
27
- return {
28
- increment: () => {
29
- this.state = {
30
- ...this.state,
31
- count: this.state.count + 1,
32
- };
33
- this.emitStateChange();
34
- },
35
- rename: (label) => {
36
- this.state = {
37
- ...this.state,
38
- label,
39
- };
40
- this.emitStateChange();
41
- },
42
- };
43
- };
44
- emitStateChange() {
45
- const nextState = this.state;
46
- this.listeners.forEach((listener) => listener(nextState));
47
- }
48
- }
49
- function CountConsumer({ onRender }) {
50
- const [count] = useProvidedStateSubscription((state) => state.count);
51
- onRender(count);
52
- return React.createElement("span", null, count);
53
- }
54
- function FullStateConsumer({ onActionsReady, onRender, }) {
55
- const [state, actions] = useProvidedStateSubscription();
56
- onRender(state);
57
- onActionsReady(actions);
58
- return React.createElement("span", null, state.label);
59
- }
60
- function ActionsOnlyConsumer({ onActionsReady, onRender, }) {
61
- const actions = useProvidedStateActions();
62
- onRender();
63
- onActionsReady(actions);
64
- return React.createElement("span", null, "actions-only");
65
- }
66
- function HandlerConsumer({ onHandlerReady, }) {
67
- const handler = useProvidedStateHandler();
68
- onHandlerReady(handler);
69
- return React.createElement("span", null, "handler");
70
- }
71
- function MissingProviderConsumer() {
72
- useProvidedStateActions();
73
- return null;
74
- }
75
- describe('StateProvider', () => {
76
- let container;
77
- let root;
78
- beforeAll(() => {
79
- globalThis.IS_REACT_ACT_ENVIRONMENT = true;
80
- });
81
- beforeEach(() => {
82
- container = document.createElement('div');
83
- document.body.appendChild(container);
84
- root = createRoot(container);
85
- });
86
- afterEach(() => {
87
- act(() => {
88
- root.unmount();
89
- });
90
- container.remove();
91
- });
92
- afterAll(() => {
93
- globalThis.IS_REACT_ACT_ENVIRONMENT = false;
94
- });
95
- it('should share one handler instance across the provider subtree', () => {
96
- const stateHandler = new TestStateHandler({
97
- count: 0,
98
- label: 'Counter',
99
- });
100
- const countRenderSpy = jest.fn();
101
- const actionsRenderSpy = jest.fn();
102
- const actionsReadySpy = jest.fn();
103
- const handlerReadySpy = jest.fn();
104
- act(() => {
105
- root.render(React.createElement(StateProvider, { instance: stateHandler },
106
- React.createElement(CountConsumer, { onRender: countRenderSpy }),
107
- React.createElement(ActionsOnlyConsumer, { onActionsReady: actionsReadySpy, onRender: actionsRenderSpy }),
108
- React.createElement(HandlerConsumer, { onHandlerReady: handlerReadySpy })));
109
- });
110
- expect(countRenderSpy).toHaveBeenCalledTimes(1);
111
- expect(countRenderSpy).toHaveBeenLastCalledWith(0);
112
- expect(actionsRenderSpy).toHaveBeenCalledTimes(1);
113
- expect(handlerReadySpy).toHaveBeenCalledWith(stateHandler);
114
- const [[actions]] = actionsReadySpy.mock.calls;
115
- act(() => {
116
- actions.rename('Renamed');
117
- });
118
- expect(countRenderSpy).toHaveBeenCalledTimes(1);
119
- expect(actionsRenderSpy).toHaveBeenCalledTimes(1);
120
- act(() => {
121
- actions.increment();
122
- });
123
- expect(countRenderSpy).toHaveBeenCalledTimes(2);
124
- expect(countRenderSpy).toHaveBeenLastCalledWith(1);
125
- expect(actionsRenderSpy).toHaveBeenCalledTimes(1);
126
- });
127
- it('should return the full snapshot when no selector is provided', () => {
128
- const stateHandler = new TestStateHandler({
129
- count: 2,
130
- label: 'Counter',
131
- });
132
- const renderSpy = jest.fn();
133
- const actionsReadySpy = jest.fn();
134
- act(() => {
135
- root.render(React.createElement(StateProvider, { instance: stateHandler },
136
- React.createElement(FullStateConsumer, { onActionsReady: actionsReadySpy, onRender: renderSpy })));
137
- });
138
- expect(renderSpy).toHaveBeenCalledTimes(1);
139
- expect(renderSpy).toHaveBeenLastCalledWith({ count: 2, label: 'Counter' });
140
- const [[actions]] = actionsReadySpy.mock.calls;
141
- act(() => {
142
- actions.increment();
143
- });
144
- expect(renderSpy).toHaveBeenCalledTimes(2);
145
- expect(renderSpy).toHaveBeenLastCalledWith({ count: 3, label: 'Counter' });
146
- });
147
- it('should follow a new instance when the provider instance changes', () => {
148
- const firstHandler = new TestStateHandler({
149
- count: 1,
150
- label: 'First',
151
- });
152
- const secondHandler = new TestStateHandler({
153
- count: 8,
154
- label: 'Second',
155
- });
156
- const renderSpy = jest.fn();
157
- act(() => {
158
- root.render(React.createElement(StateProvider, { instance: firstHandler },
159
- React.createElement(CountConsumer, { onRender: renderSpy })));
160
- });
161
- act(() => {
162
- root.render(React.createElement(StateProvider, { instance: secondHandler },
163
- React.createElement(CountConsumer, { onRender: renderSpy })));
164
- });
165
- expect(renderSpy).toHaveBeenCalledTimes(2);
166
- expect(renderSpy).toHaveBeenNthCalledWith(1, 1);
167
- expect(renderSpy).toHaveBeenNthCalledWith(2, 8);
168
- });
169
- it('should throw when provider hooks are used outside StateProvider', () => {
170
- const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => undefined);
171
- expect(() => {
172
- act(() => {
173
- root.render(React.createElement(MissingProviderConsumer, null));
174
- });
175
- }).toThrow('No StateProvider instance found in the current React tree.');
176
- consoleErrorSpy.mockRestore();
177
- });
178
- });
179
- //# sourceMappingURL=state-provider.spec.js.map