@veams/status-quo 0.1.0 → 1.1.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/.github/workflows/pages.yml +46 -0
  2. package/.github/workflows/release.yml +33 -0
  3. package/CHANGELOG.md +30 -0
  4. package/README.md +260 -124
  5. package/assets/statusquo-logo.png +0 -0
  6. package/dist/hooks/state-subscription.d.ts +1 -2
  7. package/dist/hooks/state-subscription.js +8 -9
  8. package/dist/hooks/state-subscription.js.map +1 -1
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.js +2 -2
  11. package/dist/index.js.map +1 -1
  12. package/dist/store/__tests__/{state-handler.spec.js → observable-state-handler.spec.js} +14 -14
  13. package/dist/store/__tests__/observable-state-handler.spec.js.map +1 -0
  14. package/dist/store/__tests__/signal-state-handler.spec.js +78 -0
  15. package/dist/store/__tests__/signal-state-handler.spec.js.map +1 -0
  16. package/dist/store/base-state-handler.d.ts +30 -0
  17. package/dist/store/base-state-handler.js +84 -0
  18. package/dist/store/base-state-handler.js.map +1 -0
  19. package/dist/store/index.d.ts +3 -1
  20. package/dist/store/index.js +3 -1
  21. package/dist/store/index.js.map +1 -1
  22. package/dist/store/observable-state-handler.d.ts +26 -0
  23. package/dist/store/observable-state-handler.js +55 -0
  24. package/dist/store/observable-state-handler.js.map +1 -0
  25. package/dist/store/signal-state-handler.d.ts +25 -0
  26. package/dist/store/signal-state-handler.js +49 -0
  27. package/dist/store/signal-state-handler.js.map +1 -0
  28. package/dist/types/types.d.ts +2 -2
  29. package/package.json +22 -11
  30. package/playground/index.html +12 -0
  31. package/playground/src/App.tsx +478 -0
  32. package/playground/src/assets/philosophy-agnostic.svg +18 -0
  33. package/playground/src/assets/philosophy-separation.svg +13 -0
  34. package/playground/src/assets/philosophy-swap.svg +17 -0
  35. package/playground/src/assets/statusquo-logo.png +0 -0
  36. package/playground/src/main.tsx +19 -0
  37. package/playground/src/styles.css +411 -0
  38. package/playground/tsconfig.json +12 -0
  39. package/playground/vite.config.ts +18 -0
  40. package/src/hooks/state-subscription.tsx +21 -14
  41. package/src/index.ts +14 -2
  42. package/src/store/__tests__/{state-handler.spec.ts → observable-state-handler.spec.ts} +15 -15
  43. package/src/store/__tests__/signal-state-handler.spec.ts +97 -0
  44. package/src/store/base-state-handler.ts +119 -0
  45. package/src/store/index.ts +3 -1
  46. package/src/store/observable-state-handler.ts +87 -0
  47. package/src/store/signal-state-handler.ts +76 -0
  48. package/src/types/types.ts +2 -3
  49. package/dist/store/__tests__/state-handler.spec.js.map +0 -1
  50. package/dist/store/state-handler.d.ts +0 -36
  51. package/dist/store/state-handler.js +0 -122
  52. package/dist/store/state-handler.js.map +0 -1
  53. package/dist/types/hooks/index.d.ts +0 -2
  54. package/dist/types/hooks/state-factory.d.ts +0 -2
  55. package/dist/types/hooks/state-singleton.d.ts +0 -2
  56. package/dist/types/hooks/state-subscription.d.ts +0 -3
  57. package/dist/types/index.d.ts +0 -6
  58. package/dist/types/store/dev-tools.d.ts +0 -23
  59. package/dist/types/store/index.d.ts +0 -3
  60. package/dist/types/store/state-handler.d.ts +0 -36
  61. package/dist/types/store/state-singleton.d.ts +0 -5
  62. package/dist/types/types/types.d.ts +0 -7
  63. package/src/store/state-handler.ts +0 -181
  64. /package/dist/store/__tests__/{state-handler.spec.d.ts → observable-state-handler.spec.d.ts} +0 -0
  65. /package/dist/{types/store/__tests__/state-handler.spec.d.ts → store/__tests__/signal-state-handler.spec.d.ts} +0 -0
@@ -0,0 +1,46 @@
1
+ name: Deploy Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ pages: write
11
+ id-token: write
12
+
13
+ concurrency:
14
+ group: pages
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ build:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - name: Checkout
22
+ uses: actions/checkout@v4
23
+ - name: Setup Node
24
+ uses: actions/setup-node@v4
25
+ with:
26
+ node-version: 20
27
+ cache: npm
28
+ - name: Install dependencies
29
+ run: npm ci
30
+ - name: Build docs
31
+ run: npm run docs:build
32
+ - name: Upload artifact
33
+ uses: actions/upload-pages-artifact@v3
34
+ with:
35
+ path: ./docs
36
+
37
+ deploy:
38
+ runs-on: ubuntu-latest
39
+ needs: build
40
+ environment:
41
+ name: github-pages
42
+ url: ${{ steps.deployment.outputs.page_url }}
43
+ steps:
44
+ - name: Deploy
45
+ id: deployment
46
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,33 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ release:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout
16
+ uses: actions/checkout@v4
17
+ - name: Setup Node
18
+ uses: actions/setup-node@v4
19
+ with:
20
+ node-version: 20
21
+ cache: npm
22
+ - name: Install dependencies
23
+ run: npm ci
24
+ - name: Build dist
25
+ run: npm run build
26
+ - name: Package dist
27
+ run: |
28
+ zip -r "dist-${{ github.ref_name }}.zip" dist
29
+ - name: Create GitHub release
30
+ uses: softprops/action-gh-release@v2
31
+ with:
32
+ files: dist-${{ github.ref_name }}.zip
33
+ generate_release_notes: true
package/CHANGELOG.md ADDED
@@ -0,0 +1,30 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+
7
+ ## [1.0.0] - 2026-02-17
8
+
9
+ ### Added
10
+ - `SignalStateHandler` (signals-backed state handler).
11
+ - `BaseStateHandler` to share devtools and lifecycle APIs.
12
+ - `bindSubscribable` helper for managing external subscriptions.
13
+ - Playground/demo with GitHub Pages deployment.
14
+
15
+ ### Changed
16
+ - `StateHandler` renamed to `ObservableStateHandler`.
17
+ - `StateSubscriptionHandler` now uses `subscribe/getSnapshot` (no `getObservable`).
18
+ - Devtools options moved under `options.devTools`.
19
+
20
+ ### Migration
21
+ - Update imports:
22
+ - From: `StateHandler`
23
+ - To: `ObservableStateHandler`
24
+ - Implement `subscribe()` and `getSnapshot()` on custom handlers.
25
+ - Replace `getObservable()` usage with `subscribe()` in custom integrations.
26
+ - Update devtools config:
27
+ - From: `super({ initialState, devTools: { ... } })`
28
+ - To: `super({ initialState, options: { devTools: { ... } } })`
29
+
30
+ [1.0.0]: https://github.com/Veams/status-quo/releases/tag/v1.0.0
package/README.md CHANGED
@@ -1,176 +1,312 @@
1
- # Status Quo (`@veams/status-quo`)
1
+ # @veams/status-quo
2
+ [![npm version](https://img.shields.io/npm/v/@veams/status-quo)](https://www.npmjs.com/package/@veams/status-quo)
2
3
 
3
- The `Manager` to rule your state.
4
+ <center>
5
+ <img src="assets/statusquo-logo.png" width="200" alt="StatusQuo Logo" style="margin: 0 auto;">
6
+ </center>
4
7
 
5
- ---
8
+ The manager to rule your state.
6
9
 
7
- ## Table of Content
10
+ This page mirrors the demo content and adds a full API reference.
8
11
 
9
- 1. [Getting Started](#getting-started)
10
- 2. [Example](#example)
12
+ ## Table of Contents
11
13
 
12
- ---
14
+ 1. [Overview](#overview)
15
+ 2. [Philosophy](#philosophy)
16
+ 3. [Demo](#demo)
17
+ 4. [Quickstart](#quickstart)
18
+ 5. [Handlers](#handlers)
19
+ 6. [Hooks](#hooks)
20
+ 7. [Singletons](#singletons)
21
+ 8. [Composition](#composition)
22
+ 9. [Devtools](#devtools)
23
+ 10. [Cleanup](#cleanup)
24
+ 11. [API Reference](#api-reference)
25
+ 12. [Migration](#migration)
13
26
 
14
- ## Getting Started
27
+ ## Overview
15
28
 
16
- 1. Create your own state handler which handles all the streams and a state you expose next to the actions
17
- 1. Use actions and state in your component
18
- 1. When using React, initialize the state handler with a custom hook called `useStateFactory()` (or `useStateSingleton()` for Singleton states)
29
+ StatusQuo is a small, framework-agnostic state layer that focuses on explicit lifecycle, clear action APIs, and a minimal subscription surface. It ships two handler implementations with the same public interface: RxJS-backed observables and signals-backed stores.
19
30
 
31
+ ## Philosophy
20
32
 
21
- These three steps are necessary to create a completely decoupled state management solution without the need of creating custom hooks with `useEffect()`.
33
+ - Swap the engine, keep the API. Your UI code stays the same when you switch from RxJS to Signals.
34
+ - Separate view and state. Handlers own transitions and expose actions; views subscribe to snapshots.
35
+ - Framework-agnostic core. Business logic lives outside the UI library; hooks provide the glue.
22
36
 
23
- __Note__:
24
- _Please keep in mind that dependencies for the hook needs to be flattened and cannot be used as an object due to how React works._
37
+ ## Demo
25
38
 
26
- ## Example
39
+ Live docs and demo:
27
40
 
28
- Let's start with a simple state example.
29
- You should start with the abstract class `StateHandler`:
41
+ [https://veams.github.io/status-quo/](https://veams.github.io/status-quo/)
42
+
43
+ ## Quickstart
44
+
45
+ Install:
46
+
47
+ ```bash
48
+ npm install @veams/status-quo rxjs @preact/signals-core
49
+ ```
50
+
51
+ Create a store and use it in a component:
30
52
 
31
53
  ```ts
32
- import { useStateFactory, StateHandler } from '@veams/status-quo';
54
+ import { ObservableStateHandler, useStateFactory } from '@veams/status-quo';
55
+
56
+ type CounterState = { count: number };
33
57
 
34
- type CounterState = {
35
- count: number;
36
- };
37
58
  type CounterActions = {
38
59
  increase: () => void;
39
60
  decrease: () => void;
40
61
  };
41
62
 
42
- class CounterStateHandler extends StateHandler<CounterState, CounterActions> {
43
- constructor([startCount = 0]) {
44
- super({ initialState: { count: startCount } });
63
+ class CounterStore extends ObservableStateHandler<CounterState, CounterActions> {
64
+ constructor() {
65
+ super({ initialState: { count: 0 } });
45
66
  }
46
-
47
- getActions() {
67
+
68
+ getActions(): CounterActions {
48
69
  return {
49
- increase() {
50
- this.setState({
51
- count: this.getState() + 1
52
- })
53
- },
54
- decrease() {
55
- const currentState = this.getState();
56
-
57
- if (currentState.count > 0) {
58
- this.setState({
59
- count: currentState - 1
60
- })
61
- }
62
- }
63
- }
70
+ increase: () => this.setState({ count: this.getState().count + 1 }),
71
+ decrease: () => this.setState({ count: this.getState().count - 1 }),
72
+ };
64
73
  }
65
74
  }
66
75
 
67
- export function CounterStateFactory(...args) {
68
- return new CounterStateHandler(...args);
69
- }
76
+ const [state, actions] = useStateFactory(() => new CounterStore(), []);
70
77
  ```
71
78
 
72
- This can be used in our factory hook function:
73
-
74
- ```tsx
75
- import { useStateFactory } from '@veams/status-quo';
76
- import { CounterStateFactory } from './counter.state.js';
77
-
78
- const Counter = () => {
79
- const [state, actions] = useStateFactory(CounterStateFactory, [0]);
80
-
81
- return (
82
- <div>
83
- <h2>Counter: {state}</h2>
84
- <button onClick={actions.increase}>Increase</button>
85
- <button onClick={actions.decrease}>Decrease</button>
86
- </div>
87
- )
88
- }
89
- ```
79
+ ## Handlers
80
+
81
+ StatusQuo provides two handler implementations with the same public interface:
82
+
83
+ - `ObservableStateHandler` (RxJS-backed)
84
+ - `SignalStateHandler` (Signals-backed)
85
+
86
+ Both are built on `BaseStateHandler`, which provides the shared lifecycle and devtools support.
90
87
 
91
- **What about singletons?**
88
+ ## Hooks
92
89
 
93
- Therefore, you can use a simple singleton class or use `makeStateSingleton()` and pass it later on to the singleton hook function:
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.
95
+
96
+ ## Singletons
94
97
 
95
98
  ```ts
96
- import { makeStateSingleton } from '@veams/status-quo';
99
+ import { makeStateSingleton, useStateSingleton } from '@veams/status-quo';
97
100
 
98
- import { CounterStateHandler } from './counter.state.js';
101
+ const CounterSingleton = makeStateSingleton(() => new CounterStore());
99
102
 
100
- export const CounterStateManager = makeStateSingleton(() => new CounterStateHandler([0]))
103
+ const [state, actions] = useStateSingleton(CounterSingleton);
101
104
  ```
102
105
 
103
- ```tsx
104
- import { useStateSingleton } from '@veams/status-quo';
105
- import { CounterStateManager } from './counter.singleton.js';
106
-
107
- const GlobalCounterHandler = () => {
108
- const [_, actions] = useStateSingleton(CounterStateManager);
109
-
110
- return (
111
- <div>
112
- <button onClick={actions.increase}>Increase</button>
113
- <button onClick={actions.decrease}>Decrease</button>
114
- </div>
115
- )
106
+ ## Composition
107
+
108
+ 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`.
109
+
110
+ ```ts
111
+ import { combineLatest } from 'rxjs';
112
+
113
+ // RxJS: combine handler streams (RxJS shines here)
114
+ class AppSignalStore extends SignalStateHandler<AppState, AppActions> {
115
+ private counter$ = CounterObservableStore.getInstance().getStateAsObservable();
116
+ private card$ = new CardObservableHandler();
117
+
118
+ constructor() {
119
+ super({ initialState: { counter: 0, cardTitle: '' }});
120
+
121
+ this.subscriptions.push(
122
+ combineLatest([
123
+ this.counter$,
124
+ this.card$,
125
+ ]).subscribe(([counterState, cardState]) => {
126
+ this.setState({
127
+ counter: counterState,
128
+ cardTitle: cardState.title,
129
+ }, 'sync-combined');
130
+ })
131
+ )
132
+ }
133
+
116
134
  }
117
135
 
118
- const GlobalCounterDisplay = () => {
119
- const [state] = useStateSingleton(CounterStateManager);
120
-
121
- return (
122
- <div>
123
- <h2>Counter: {state}</h2>
124
- </div>
125
- )
136
+ // Signals: combine derived values via computed + bindSubscribable
137
+ import { computed } from '@preact/signals-core';
138
+
139
+ class AppSignalStore extends SignalStateHandler<AppState, AppActions> {
140
+ private counter = CounterSignalHandler.getInstance();
141
+ private card = new CardSignalHandler();
142
+ private combined$ = computed(() => ({
143
+ counter: this.counter.getSignal().value,
144
+ cardTitle: this.card.getSignal().value.title,
145
+ }));
146
+
147
+ constructor() {
148
+ super({ initialState: { counter: 0, cardTitle: '' }});
149
+
150
+ this.bindSubscribable(
151
+ { subscribe: this.combined.subscribe.bind(this.combined), getSnapshot: () => this.combined.value },
152
+ (nextState) => this.setState(nextState, 'sync-combined')
153
+ );
154
+ }
126
155
  }
127
156
  ```
128
157
 
129
- ### What about debugging?
158
+ ## Devtools
130
159
 
131
- You know redux-devtools? You like it? We covered you (at least a bit)!
132
- You can enable the devtools in an easy way:
160
+ Enable Redux Devtools integration with `options.devTools`:
133
161
 
134
162
  ```ts
135
-
136
- class CounterStateHandler extends StateHandler<CounterState, CounterActions> {
137
- constructor([startCount = 0]) {
163
+ class CounterStore extends ObservableStateHandler<CounterState, CounterActions> {
164
+ constructor() {
138
165
  super({
139
- initialState: { count: startCount },
140
- devTools: { enabled: true, namespace: 'Counter' },
166
+ initialState: { count: 0 },
167
+ options: { devTools: { enabled: true, namespace: 'Counter' } },
141
168
  });
142
169
  }
170
+ }
171
+ ```
143
172
 
144
- getActions() {
145
- return {
146
- increase() {
147
- this.setState(
148
- {
149
- count: this.getState() + 1,
150
- },
151
- 'increase'
152
- );
153
- },
154
- decrease() {
155
- const currentState = this.getState();
156
-
157
- if (currentState.count > 0) {
158
- this.setState(
159
- {
160
- count: currentState - 1,
161
- },
162
- 'decrease'
163
- );
164
- }
165
- },
166
- };
167
- }
173
+ ## Cleanup
174
+
175
+ Handlers expose `subscribe`, `getSnapshot`, and `destroy` for custom integrations:
176
+
177
+ ```ts
178
+ const unsubscribe = store.subscribe(() => {
179
+ console.log(store.getSnapshot());
180
+ });
181
+
182
+ unsubscribe();
183
+ store.destroy();
184
+ ```
185
+
186
+ ## API Reference
187
+
188
+ ### `StateSubscriptionHandler<V, A>`
189
+
190
+ Required interface implemented by all handlers.
191
+
192
+ ```ts
193
+ interface StateSubscriptionHandler<V, A> {
194
+ subscribe: (listener: () => void) => () => void;
195
+ getSnapshot: () => V;
196
+ destroy: () => void;
197
+ getInitialState: () => V;
198
+ getActions: () => A;
168
199
  }
200
+ ```
201
+
202
+ ### `BaseStateHandler<S, A>`
203
+
204
+ Shared base class for all handlers.
205
+
206
+ Constructor:
207
+
208
+ ```ts
209
+ protected constructor(initialState: S)
210
+ ```
211
+
212
+ Public methods:
213
+
214
+ - `getInitialState(): S`
215
+ - `getState(): S`
216
+ - `getSnapshot(): S`
217
+ - `setState(next: Partial<S>, actionName = 'change'): void`
218
+ - `subscribe(listener: () => void): () => void` (abstract)
219
+ - `destroy(): void`
220
+ - `getActions(): A` (abstract)
221
+
222
+ Protected helpers:
223
+
224
+ - `getStateValue(): S` (abstract)
225
+ - `setStateValue(next: S): void` (abstract)
226
+ - `initDevTools(options?: { enabled?: boolean; namespace: string }): void`
227
+ - `bindSubscribable<T>(service: { subscribe: (listener: (value: T) => void) => () => void; getSnapshot?: () => T }, onChange: (value: T) => void): void`
228
+ - Registers the subscription on `this.subscriptions` and invokes `onChange` with the current snapshot when available.
229
+
230
+ ### `ObservableStateHandler<S, A>`
231
+
232
+ RxJS-backed handler. Extends `BaseStateHandler`.
233
+
234
+ Constructor:
235
+
236
+ ```ts
237
+ protected constructor({
238
+ initialState,
239
+ options
240
+ }: {
241
+ initialState: S;
242
+ options?: {
243
+ devTools?: { enabled?: boolean; namespace: string };
244
+ };
245
+ })
246
+ ```
247
+
248
+ Public methods:
249
+
250
+ - `getStateAsObservable(options?: { useDistinctUntilChanged?: boolean }): Observable<S>`
251
+ - `getStateItemAsObservable(key: keyof S): Observable<S[keyof S]>`
252
+ - `getObservableItem(key: keyof S): Observable<S[keyof S]>`
253
+ - `subscribe(listener: () => void): () => void`
254
+
255
+ Notes:
256
+ - The observable stream uses `distinctUntilChanged` by default (JSON compare).
257
+ - `subscribe` does not fire for the initial value; it only fires on subsequent changes.
258
+
259
+ ### `SignalStateHandler<S, A>`
260
+
261
+ Signals-backed handler. Extends `BaseStateHandler`.
262
+
263
+ Constructor:
264
+
265
+ ```ts
266
+ protected constructor({
267
+ initialState,
268
+ options
269
+ }: {
270
+ initialState: S;
271
+ options?: {
272
+ devTools?: { enabled?: boolean; namespace: string };
273
+ useDistinctUntilChanged?: boolean;
274
+ };
275
+ })
276
+ ```
277
+
278
+ Public methods:
279
+
280
+ - `getSignal(): Signal<S>`
281
+ - `subscribe(listener: () => void): () => void`
282
+
283
+ Notes:
284
+ - `useDistinctUntilChanged` defaults to `true` (JSON compare).
285
+
286
+ ### `makeStateSingleton`
169
287
 
170
- export function CounterStateFactory(...args) {
171
- return new CounterStateHandler(...args);
288
+ ```ts
289
+ function makeStateSingleton<S, A>(
290
+ factory: () => StateSubscriptionHandler<S, A>
291
+ ): {
292
+ getInstance: () => StateSubscriptionHandler<S, A>;
172
293
  }
173
294
  ```
174
295
 
175
- We just added the `devTools` option and also updated the `setState()` function by passing a second argument into it which is the actions name.
176
- Now you can open up the the browser extension and you are able to take a look at your actions and state(s).
296
+ ### Hooks
297
+
298
+ - `useStateFactory<V, A, P extends unknown[]>(factory: (...args: P) => StateSubscriptionHandler<V, A>, params?: P)`
299
+ - Returns `[state, actions]`.
300
+ - `useStateSingleton<V, A>(singleton: StateSingleton<V, A>)`
301
+ - Returns `[state, actions]`.
302
+
303
+ ## Migration
304
+
305
+ From pre-1.0 releases:
306
+
307
+ 1. Rename `StateHandler` -> `ObservableStateHandler`.
308
+ 2. Implement `subscribe()` and `getSnapshot()` on custom handlers.
309
+ 3. Replace `getObservable()` usage with `subscribe()` in custom integrations.
310
+ 4. Update devtools config:
311
+ - From: `super({ initialState, devTools: { ... } })`
312
+ - To: `super({ initialState, options: { devTools: { ... } } })`
Binary file
@@ -1,3 +1,2 @@
1
1
  import type { StateSubscriptionHandler } from '../types/types.js';
2
- import type { SetStateAction } from 'react';
3
- export declare function useStateSubscription<V, A>(stateSubscriptionHandler: StateSubscriptionHandler<V, A>): SetStateAction<V>;
2
+ export declare function useStateSubscription<V, A>(stateSubscriptionHandler: StateSubscriptionHandler<V, A>): V;
@@ -1,15 +1,14 @@
1
- import { useEffect, useState } from 'react';
1
+ import { useCallback, useSyncExternalStore } from 'react';
2
2
  export function useStateSubscription(stateSubscriptionHandler) {
3
- const [state, setSubscriptionState] = useState(stateSubscriptionHandler.getInitialState());
4
- useEffect(() => {
5
- const state$ = stateSubscriptionHandler.getObservable().subscribe((data) => {
6
- setSubscriptionState(data);
7
- });
3
+ const subscribe = useCallback((listener) => {
4
+ const unsubscribe = stateSubscriptionHandler.subscribe(listener);
8
5
  return () => {
9
- state$.unsubscribe();
10
- return stateSubscriptionHandler.destroy();
6
+ unsubscribe();
7
+ stateSubscriptionHandler.destroy();
11
8
  };
12
9
  }, [stateSubscriptionHandler]);
13
- return state;
10
+ const getSnapshot = useCallback(() => stateSubscriptionHandler.getSnapshot(), [stateSubscriptionHandler]);
11
+ const getServerSnapshot = useCallback(() => stateSubscriptionHandler.getInitialState(), [stateSubscriptionHandler]);
12
+ return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
14
13
  }
15
14
  //# sourceMappingURL=state-subscription.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"state-subscription.js","sourceRoot":"","sources":["../../src/hooks/state-subscription.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAK5C,MAAM,UAAU,oBAAoB,CAClC,wBAAwD;IAExD,MAAM,CAAC,KAAK,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAC5C,wBAAwB,CAAC,eAAe,EAAE,CAC3C,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,MAAM,GAAG,wBAAwB,CAAC,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;YACzE,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO,wBAAwB,CAAC,OAAO,EAAE,CAAC;QAC5C,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAE/B,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"state-subscription.js","sourceRoot":"","sources":["../../src/hooks/state-subscription.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAK1D,MAAM,UAAU,oBAAoB,CAClC,wBAAwD;IAExD,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,QAAkB,EAAE,EAAE;QACrB,MAAM,WAAW,GAAG,wBAAwB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEjE,OAAO,GAAG,EAAE;YACV,WAAW,EAAE,CAAC;YACd,wBAAwB,CAAC,OAAO,EAAE,CAAC;QACrC,CAAC,CAAC;IACJ,CAAC,EACD,CAAC,wBAAwB,CAAC,CAC3B,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAC7B,GAAG,EAAE,CAAC,wBAAwB,CAAC,WAAW,EAAE,EAC5C,CAAC,wBAAwB,CAAC,CAC3B,CAAC;IAEF,MAAM,iBAAiB,GAAG,WAAW,CACnC,GAAG,EAAE,CAAC,wBAAwB,CAAC,eAAe,EAAE,EAChD,CAAC,wBAAwB,CAAC,CAC3B,CAAC;IAEF,OAAO,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;AACzE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { useStateFactory, useStateSingleton } from './hooks/index.js';
2
- import { makeStateSingleton, StateHandler } from './store/index.js';
2
+ import { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler } from './store/index.js';
3
3
  import type { StateSingleton } from './store/index.js';
4
4
  import type { StateSubscriptionHandler } from './types/types.js';
5
- export { makeStateSingleton, StateHandler, useStateFactory, useStateSingleton };
5
+ export { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler, useStateFactory, useStateSingleton, };
6
6
  export type { StateSingleton, StateSubscriptionHandler };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import { useStateFactory, useStateSingleton } from './hooks/index.js';
2
- import { makeStateSingleton, StateHandler } from './store/index.js';
3
- export { makeStateSingleton, StateHandler, useStateFactory, useStateSingleton };
2
+ import { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler, } from './store/index.js';
3
+ export { BaseStateHandler, makeStateSingleton, ObservableStateHandler, SignalStateHandler, useStateFactory, useStateSingleton, };
4
4
  //# 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,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAKpE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,GAClB,CAAC"}