@veams/status-quo 1.11.0 → 1.12.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.
- package/CHANGELOG.md +2 -0
- package/README.md +21 -2
- package/dist/react/hooks/__tests__/state-selector.spec.js +103 -0
- package/dist/react/hooks/__tests__/state-selector.spec.js.map +1 -1
- package/dist/react/hooks/state-subscription-selector.js +46 -34
- package/dist/react/hooks/state-subscription-selector.js.map +1 -1
- package/dist/store/__tests__/native-state-handler.spec.js +62 -0
- package/dist/store/__tests__/native-state-handler.spec.js.map +1 -1
- package/dist/store/base-state-handler.d.ts +22 -0
- package/dist/store/base-state-handler.js +76 -0
- package/dist/store/base-state-handler.js.map +1 -1
- package/dist/types/types.d.ts +2 -0
- package/package.json +1 -1
- package/src/react/hooks/__tests__/state-selector.spec.tsx +160 -1
- package/src/react/hooks/state-subscription-selector.tsx +54 -40
- package/src/store/__tests__/native-state-handler.spec.ts +80 -0
- package/src/store/base-state-handler.ts +88 -0
- package/src/types/types.ts +4 -0
|
@@ -53,6 +53,11 @@ export abstract class BaseStateHandler<S, A> implements StateSubscriptionHandler
|
|
|
53
53
|
// Holds the Redux DevTools instance if enabled.
|
|
54
54
|
protected devTools: DevTools | null = null;
|
|
55
55
|
|
|
56
|
+
// Tracks mounted consumers that have connected this handler.
|
|
57
|
+
private connectCount = 0;
|
|
58
|
+
// Prevents duplicate side effects while the handler is already connected.
|
|
59
|
+
private isConnected = false;
|
|
60
|
+
|
|
56
61
|
// Keeps track of active subscriptions to allow for cleanup.
|
|
57
62
|
subscriptions: ManagedSubscription[] = [];
|
|
58
63
|
// Tracks keyed subscriptions so handlers can replace them by name.
|
|
@@ -127,10 +132,93 @@ export abstract class BaseStateHandler<S, A> implements StateSubscriptionHandler
|
|
|
127
132
|
this.devTools?.send(actionName, nextState);
|
|
128
133
|
}
|
|
129
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Starts external effects for this handler.
|
|
137
|
+
*/
|
|
138
|
+
connect(): void {
|
|
139
|
+
const previousConnectCount = this.connectCount;
|
|
140
|
+
this.connectCount += 1;
|
|
141
|
+
|
|
142
|
+
if (this.isConnected) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this.isConnected = true;
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
this.onConnect();
|
|
150
|
+
} catch (error) {
|
|
151
|
+
this.connectCount = previousConnectCount;
|
|
152
|
+
this.isConnected = false;
|
|
153
|
+
this.clearManagedSubscriptions();
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Stops external effects once all connected consumers have disconnected.
|
|
160
|
+
*/
|
|
161
|
+
disconnect(): void {
|
|
162
|
+
if (this.connectCount === 0) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
this.connectCount -= 1;
|
|
167
|
+
|
|
168
|
+
if (this.connectCount > 0) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (!this.isConnected) {
|
|
173
|
+
this.clearManagedSubscriptions();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
this.onDisconnect();
|
|
179
|
+
} finally {
|
|
180
|
+
this.isConnected = false;
|
|
181
|
+
this.clearManagedSubscriptions();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
130
185
|
/**
|
|
131
186
|
* Cleans up all active subscriptions when the handler is destroyed.
|
|
132
187
|
*/
|
|
133
188
|
destroy(): void {
|
|
189
|
+
this.connectCount = 0;
|
|
190
|
+
|
|
191
|
+
if (!this.isConnected) {
|
|
192
|
+
this.clearManagedSubscriptions();
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
this.onDisconnect();
|
|
198
|
+
} finally {
|
|
199
|
+
this.isConnected = false;
|
|
200
|
+
this.clearManagedSubscriptions();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Optional hook for subclasses that need to start external effects.
|
|
206
|
+
*/
|
|
207
|
+
protected onConnect(): void {
|
|
208
|
+
// Optional override.
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Optional hook for subclasses that need to stop external effects.
|
|
213
|
+
*/
|
|
214
|
+
protected onDisconnect(): void {
|
|
215
|
+
// Optional override.
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Clears all subscriptions managed through this base handler.
|
|
220
|
+
*/
|
|
221
|
+
protected clearManagedSubscriptions(): void {
|
|
134
222
|
const subscriptions = [...this.subscriptions];
|
|
135
223
|
const namedSubscriptions = [...this.namedSubscriptions.values()];
|
|
136
224
|
|
package/src/types/types.ts
CHANGED
|
@@ -13,6 +13,10 @@ export interface StateSubscriptionHandler<V, A> {
|
|
|
13
13
|
subscribe(listener: () => void): () => void;
|
|
14
14
|
// Method to subscribe a listener that receives the updated state value.
|
|
15
15
|
subscribe(listener: (value: V) => void): () => void;
|
|
16
|
+
// Optional method to start external effects after a committed consumer subscribes.
|
|
17
|
+
connect?: () => void;
|
|
18
|
+
// Optional method to stop external effects after the last consumer unsubscribes.
|
|
19
|
+
disconnect?: () => void;
|
|
16
20
|
// Method to retrieve the current state snapshot.
|
|
17
21
|
getSnapshot: () => V;
|
|
18
22
|
// Method to clean up resources associated with the handler.
|