floppy-disk 3.6.1 → 3.7.0-beta.2
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/esm/react/create-mutation.d.mts +1 -11
- package/esm/react/create-query.d.mts +154 -19
- package/esm/react/create-stores.d.mts +32 -14
- package/esm/react/create-stream.d.mts +88 -0
- package/esm/react.d.mts +1 -0
- package/esm/react.mjs +313 -96
- package/package.json +4 -1
- package/react/create-mutation.d.ts +1 -11
- package/react/create-query.d.ts +154 -19
- package/react/create-stores.d.ts +32 -14
- package/react/create-stream.d.ts +88 -0
- package/react.d.ts +1 -0
- package/react.js +313 -95
package/react.js
CHANGED
|
@@ -104,11 +104,7 @@ const createStores = (initialState, options) => {
|
|
|
104
104
|
store.key = key;
|
|
105
105
|
store.keyHash = keyHash;
|
|
106
106
|
stores.set(keyHash, store);
|
|
107
|
-
|
|
108
|
-
const useStore = (options2) => useStoreState(store, options2);
|
|
109
|
-
return Object.assign(useStore, {
|
|
110
|
-
...store,
|
|
111
|
-
delete: () => {
|
|
107
|
+
store.delete = () => {
|
|
112
108
|
if (store.getSubscriberCount() > 0) {
|
|
113
109
|
console.warn(
|
|
114
110
|
"Cannot delete store while it still has active subscribers. Unsubscribe all listeners before deleting the store."
|
|
@@ -117,13 +113,15 @@ const createStores = (initialState, options) => {
|
|
|
117
113
|
}
|
|
118
114
|
store.setState(initialState);
|
|
119
115
|
return stores.delete(keyHash);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const useStore = (options2) => useStoreState(store, options2);
|
|
119
|
+
return Object.assign(useStore, store);
|
|
122
120
|
};
|
|
123
121
|
return getStore;
|
|
124
122
|
};
|
|
125
123
|
|
|
126
|
-
const INITIAL_STATE$
|
|
124
|
+
const INITIAL_STATE$2 = {
|
|
127
125
|
isPending: false,
|
|
128
126
|
isRevalidating: false,
|
|
129
127
|
willRetryAt: void 0,
|
|
@@ -151,15 +149,15 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
151
149
|
onSettled = vanilla.noop,
|
|
152
150
|
shouldRetry: shouldRetryFn = (_, s) => s.retryCount === 0 ? [true, 1500] : [false]
|
|
153
151
|
} = options;
|
|
154
|
-
const initialState = { ...INITIAL_STATE$
|
|
152
|
+
const initialState = { ...INITIAL_STATE$2 };
|
|
155
153
|
const stores = /* @__PURE__ */ new Map();
|
|
156
154
|
const configureStoreEvents = (variableHash) => ({
|
|
157
155
|
...options,
|
|
158
156
|
onFirstSubscribe: (state, store) => {
|
|
159
157
|
var _a;
|
|
160
158
|
(_a = options.onFirstSubscribe) == null ? void 0 : _a.call(options, state, store);
|
|
161
|
-
const {
|
|
162
|
-
clearTimeout(
|
|
159
|
+
const { internal, revalidate: revalidate2 } = store;
|
|
160
|
+
clearTimeout(internal.garbageCollectionTimeoutId);
|
|
163
161
|
if (vanilla.isClient) {
|
|
164
162
|
if (revalidateOnFocus) {
|
|
165
163
|
focusListeners.add(revalidate2);
|
|
@@ -169,9 +167,9 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
169
167
|
}
|
|
170
168
|
}
|
|
171
169
|
if (revalidateOnReconnect) {
|
|
172
|
-
onlineListeners.add(revalidate2);
|
|
170
|
+
onlineListeners$1.add(revalidate2);
|
|
173
171
|
if (!onlineListenersAdded) {
|
|
174
|
-
window.addEventListener("online", onWindowOnline);
|
|
172
|
+
window.addEventListener("online", onWindowOnline$1);
|
|
175
173
|
onlineListenersAdded = true;
|
|
176
174
|
}
|
|
177
175
|
}
|
|
@@ -180,15 +178,15 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
180
178
|
onLastUnsubscribe: (state, store) => {
|
|
181
179
|
var _a;
|
|
182
180
|
(_a = options.onLastUnsubscribe) == null ? void 0 : _a.call(options, state, store);
|
|
183
|
-
const {
|
|
184
|
-
clearTimeout(
|
|
185
|
-
if (
|
|
181
|
+
const { internal, revalidate: revalidate2 } = store;
|
|
182
|
+
clearTimeout(internal.retryTimeoutId);
|
|
183
|
+
if (internal.retryResolver) {
|
|
186
184
|
store.setState({ willRetryAt: void 0 });
|
|
187
|
-
|
|
188
|
-
|
|
185
|
+
internal.retryResolver(store.getState());
|
|
186
|
+
internal.retryResolver = void 0;
|
|
189
187
|
}
|
|
190
|
-
|
|
191
|
-
if (
|
|
188
|
+
internal.garbageCollectionTimeoutId = setTimeout(() => {
|
|
189
|
+
if (internal.promiseResolver || internal.retryResolver) {
|
|
192
190
|
store.setState(initialState);
|
|
193
191
|
} else {
|
|
194
192
|
stores.delete(variableHash);
|
|
@@ -203,23 +201,22 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
203
201
|
}
|
|
204
202
|
}
|
|
205
203
|
if (revalidateOnReconnect) {
|
|
206
|
-
onlineListeners.delete(revalidate2);
|
|
207
|
-
if (onlineListeners.size === 0) {
|
|
208
|
-
window.removeEventListener("online", onWindowOnline);
|
|
204
|
+
onlineListeners$1.delete(revalidate2);
|
|
205
|
+
if (onlineListeners$1.size === 0) {
|
|
206
|
+
window.removeEventListener("online", onWindowOnline$1);
|
|
209
207
|
onlineListenersAdded = false;
|
|
210
208
|
}
|
|
211
209
|
}
|
|
212
210
|
}
|
|
213
211
|
}
|
|
214
212
|
});
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
metadata: {},
|
|
213
|
+
const getApis = (store, variable) => ({
|
|
214
|
+
internal: {},
|
|
218
215
|
setInitialData: (data, revalidate2 = false) => {
|
|
219
216
|
const state = store.getState();
|
|
220
217
|
if (state.state === "INITIAL" && state.data === void 0) {
|
|
221
|
-
const {
|
|
222
|
-
if (revalidate2)
|
|
218
|
+
const { internal } = store;
|
|
219
|
+
if (revalidate2) internal.isInvalidated = true;
|
|
223
220
|
store.setState({
|
|
224
221
|
state: "SUCCESS",
|
|
225
222
|
isSuccess: true,
|
|
@@ -237,28 +234,28 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
237
234
|
return revalidate(store, variable, overwriteOngoingExecution);
|
|
238
235
|
},
|
|
239
236
|
invalidate: (options2) => {
|
|
240
|
-
const {
|
|
241
|
-
|
|
237
|
+
const { internal } = store;
|
|
238
|
+
internal.isInvalidated = true;
|
|
242
239
|
if (store.getSubscriberCount() > 0) {
|
|
243
|
-
|
|
240
|
+
store.execute(options2);
|
|
244
241
|
return true;
|
|
245
242
|
}
|
|
246
243
|
return false;
|
|
247
244
|
},
|
|
248
245
|
reset: () => {
|
|
249
246
|
var _a, _b;
|
|
250
|
-
const {
|
|
251
|
-
clearTimeout(
|
|
252
|
-
if (
|
|
247
|
+
const { internal } = store;
|
|
248
|
+
clearTimeout(internal.retryTimeoutId);
|
|
249
|
+
if (internal.retryResolver || internal.promiseResolver) {
|
|
253
250
|
console.debug(
|
|
254
251
|
"Ongoing query execution was ignored due to reset(). The result will not update the store state."
|
|
255
252
|
);
|
|
256
|
-
(_a =
|
|
257
|
-
(_b =
|
|
258
|
-
|
|
259
|
-
|
|
253
|
+
(_a = internal.promiseResolver) == null ? void 0 : _a.call(internal, initialState);
|
|
254
|
+
(_b = internal.retryResolver) == null ? void 0 : _b.call(internal, initialState);
|
|
255
|
+
internal.promiseResolver = void 0;
|
|
256
|
+
internal.retryResolver = void 0;
|
|
260
257
|
}
|
|
261
|
-
|
|
258
|
+
internal.promise = void 0;
|
|
262
259
|
store.setState(initialState);
|
|
263
260
|
},
|
|
264
261
|
delete: () => {
|
|
@@ -268,35 +265,36 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
268
265
|
);
|
|
269
266
|
return false;
|
|
270
267
|
}
|
|
271
|
-
|
|
268
|
+
store.reset();
|
|
272
269
|
return stores.delete(store.variableHash);
|
|
273
270
|
},
|
|
274
271
|
optimisticUpdate: (optimisticData) => {
|
|
275
|
-
const {
|
|
276
|
-
|
|
272
|
+
const { internal, revalidate: revalidate2, rollbackOptimisticUpdate } = store;
|
|
273
|
+
internal.rollbackData = store.getState().data;
|
|
277
274
|
store.setState({ data: optimisticData });
|
|
278
275
|
return { revalidate: revalidate2, rollback: rollbackOptimisticUpdate };
|
|
279
276
|
},
|
|
280
277
|
rollbackOptimisticUpdate: () => {
|
|
281
|
-
const {
|
|
282
|
-
store.setState({ data:
|
|
283
|
-
return
|
|
278
|
+
const { internal } = store;
|
|
279
|
+
store.setState({ data: internal.rollbackData });
|
|
280
|
+
return internal.rollbackData;
|
|
284
281
|
}
|
|
285
282
|
});
|
|
286
283
|
const execute = async (store, variable, overwriteOngoingExecution = false) => {
|
|
287
|
-
const {
|
|
288
|
-
|
|
289
|
-
|
|
284
|
+
const { internal: _internal } = store;
|
|
285
|
+
const internal = _internal;
|
|
286
|
+
if (!overwriteOngoingExecution && internal.promise) return internal.promise;
|
|
287
|
+
clearTimeout(internal.retryTimeoutId);
|
|
290
288
|
const createPromise = () => {
|
|
291
289
|
const promise = new Promise((resolve) => {
|
|
292
|
-
|
|
290
|
+
internal.promiseResolver = resolve;
|
|
293
291
|
const stateBeforeExecute = store.getState();
|
|
294
292
|
store.setState({
|
|
295
293
|
isPending: true,
|
|
296
294
|
isRevalidating: stateBeforeExecute.state === "SUCCESS",
|
|
297
295
|
willRetryAt: void 0,
|
|
298
|
-
isRetrying: !!
|
|
299
|
-
retryCount:
|
|
296
|
+
isRetrying: !!internal.retryResolver,
|
|
297
|
+
retryCount: internal.retryResolver ? stateBeforeExecute.retryCount + 1 : 0
|
|
300
298
|
});
|
|
301
299
|
queryFn(variable, stateBeforeExecute, store.variableHash).then((data) => {
|
|
302
300
|
var _a;
|
|
@@ -305,8 +303,8 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
305
303
|
"Query function returned undefined. Successful responses must not be undefined."
|
|
306
304
|
);
|
|
307
305
|
}
|
|
308
|
-
if (!
|
|
309
|
-
if (promise !==
|
|
306
|
+
if (!internal.promiseResolver) return;
|
|
307
|
+
if (promise !== internal.promise) return resolve(internal.promise);
|
|
310
308
|
const now = Date.now();
|
|
311
309
|
store.setState({
|
|
312
310
|
isPending: false,
|
|
@@ -322,17 +320,17 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
322
320
|
error: void 0,
|
|
323
321
|
errorUpdatedAt: void 0
|
|
324
322
|
});
|
|
325
|
-
|
|
326
|
-
|
|
323
|
+
internal.isInvalidated = false;
|
|
324
|
+
internal.rollbackData = data;
|
|
327
325
|
resolve(store.getState());
|
|
328
|
-
(_a =
|
|
329
|
-
|
|
326
|
+
(_a = internal.retryResolver) == null ? void 0 : _a.call(internal, store.getState());
|
|
327
|
+
internal.retryResolver = void 0;
|
|
330
328
|
onSuccess(data, variable, stateBeforeExecute);
|
|
331
329
|
onSettled(variable, stateBeforeExecute);
|
|
332
330
|
}).catch((error) => {
|
|
333
331
|
var _a;
|
|
334
|
-
if (!
|
|
335
|
-
if (promise !==
|
|
332
|
+
if (!internal.promiseResolver && !internal.retryResolver) return;
|
|
333
|
+
if (promise !== internal.promise) return resolve(internal.promise);
|
|
336
334
|
const nextState = {
|
|
337
335
|
...store.getState(),
|
|
338
336
|
isPending: false,
|
|
@@ -342,8 +340,8 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
342
340
|
const [shouldRetry, retryDelay] = shouldRetryFn(error, nextState);
|
|
343
341
|
const hasSubscriber = store.getSubscriberCount() > 0;
|
|
344
342
|
if (shouldRetry && hasSubscriber) {
|
|
345
|
-
|
|
346
|
-
|
|
343
|
+
internal.retryResolver = resolve;
|
|
344
|
+
internal.retryTimeoutId = setTimeout(createPromise, retryDelay);
|
|
347
345
|
store.setState({
|
|
348
346
|
isPending: false,
|
|
349
347
|
isRevalidating: false,
|
|
@@ -356,43 +354,38 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
356
354
|
isRevalidating: false,
|
|
357
355
|
isRetrying: false,
|
|
358
356
|
retryCount: 0,
|
|
357
|
+
state: store.getState().state === "SUCCESS" ? "SUCCESS_BUT_REVALIDATION_ERROR" : "ERROR",
|
|
358
|
+
isError: true,
|
|
359
359
|
error,
|
|
360
|
-
errorUpdatedAt: Date.now()
|
|
361
|
-
...store.getState().data ? {
|
|
362
|
-
state: "SUCCESS_BUT_REVALIDATION_ERROR",
|
|
363
|
-
isError: false
|
|
364
|
-
} : {
|
|
365
|
-
state: "ERROR",
|
|
366
|
-
isError: true
|
|
367
|
-
}
|
|
360
|
+
errorUpdatedAt: Date.now()
|
|
368
361
|
});
|
|
369
362
|
const state = store.getState();
|
|
370
363
|
resolve(state);
|
|
371
|
-
(_a =
|
|
372
|
-
|
|
364
|
+
(_a = internal.retryResolver) == null ? void 0 : _a.call(internal, state);
|
|
365
|
+
internal.retryResolver = void 0;
|
|
373
366
|
if (onError) onError(error, variable, stateBeforeExecute);
|
|
374
367
|
else console.error(state);
|
|
375
368
|
onSettled(variable, stateBeforeExecute);
|
|
376
369
|
}
|
|
377
370
|
}).finally(() => {
|
|
378
|
-
if (
|
|
379
|
-
|
|
380
|
-
|
|
371
|
+
if (internal.promise === promise) {
|
|
372
|
+
internal.promise = void 0;
|
|
373
|
+
internal.promiseResolver = void 0;
|
|
381
374
|
}
|
|
382
375
|
});
|
|
383
376
|
});
|
|
384
|
-
|
|
377
|
+
internal.promise = promise;
|
|
385
378
|
return promise;
|
|
386
379
|
};
|
|
387
380
|
return createPromise();
|
|
388
381
|
};
|
|
389
382
|
const revalidate = async (store, variable, overwriteOngoingExecution) => {
|
|
390
|
-
const {
|
|
391
|
-
if (!overwriteOngoingExecution &&
|
|
383
|
+
const { internal } = store;
|
|
384
|
+
if (!overwriteOngoingExecution && internal.promise) return internal.promise;
|
|
392
385
|
const state = store.getState();
|
|
393
386
|
if (state.dataUpdatedAt) {
|
|
394
387
|
const isFresh = state.dataUpdatedAt + staleTime > Date.now();
|
|
395
|
-
if (isFresh && !
|
|
388
|
+
if (isFresh && !internal.isInvalidated) return state;
|
|
396
389
|
}
|
|
397
390
|
return execute(store, variable, overwriteOngoingExecution);
|
|
398
391
|
};
|
|
@@ -409,7 +402,16 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
409
402
|
);
|
|
410
403
|
store.variableHash = variableHash;
|
|
411
404
|
stores.set(variableHash, store);
|
|
412
|
-
|
|
405
|
+
const apis = getApis(store, variable);
|
|
406
|
+
store.setInitialData = apis.setInitialData;
|
|
407
|
+
store.execute = apis.execute;
|
|
408
|
+
store.revalidate = apis.revalidate;
|
|
409
|
+
store.invalidate = apis.invalidate;
|
|
410
|
+
store.reset = apis.reset;
|
|
411
|
+
store.delete = apis.delete;
|
|
412
|
+
store.optimisticUpdate = apis.optimisticUpdate;
|
|
413
|
+
store.rollbackOptimisticUpdate = apis.rollbackOptimisticUpdate;
|
|
414
|
+
store.internal = apis.internal;
|
|
413
415
|
}
|
|
414
416
|
const useStore = (options2 = {}) => {
|
|
415
417
|
const {
|
|
@@ -477,15 +479,11 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
477
479
|
return trackedState;
|
|
478
480
|
};
|
|
479
481
|
return Object.assign(useStore, {
|
|
480
|
-
|
|
481
|
-
getSubscriberCount: store.getSubscriberCount,
|
|
482
|
-
getState: store.getState,
|
|
482
|
+
...store,
|
|
483
483
|
setState: (value) => {
|
|
484
484
|
console.debug("Manual setState (not via provided actions) on query store");
|
|
485
485
|
store.setState(value);
|
|
486
|
-
}
|
|
487
|
-
...internals.get(store),
|
|
488
|
-
variableHash
|
|
486
|
+
}
|
|
489
487
|
});
|
|
490
488
|
};
|
|
491
489
|
return Object.assign(getStore, {
|
|
@@ -496,7 +494,7 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
496
494
|
* - Useful for bulk refetching.
|
|
497
495
|
*/
|
|
498
496
|
executeAll: (options2) => {
|
|
499
|
-
stores.forEach((store) =>
|
|
497
|
+
stores.forEach((store) => store.execute(options2));
|
|
500
498
|
},
|
|
501
499
|
/**
|
|
502
500
|
* Revalidates all query instances.
|
|
@@ -505,7 +503,7 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
505
503
|
* - Only re-fetches stale queries.
|
|
506
504
|
*/
|
|
507
505
|
revalidateAll: (options2) => {
|
|
508
|
-
stores.forEach((store) =>
|
|
506
|
+
stores.forEach((store) => store.revalidate(options2));
|
|
509
507
|
},
|
|
510
508
|
/**
|
|
511
509
|
* Invalidates all query instances.
|
|
@@ -515,13 +513,13 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
515
513
|
* - Invalidated queries bypass `staleTime` until successfully executed again.
|
|
516
514
|
*/
|
|
517
515
|
invalidateAll: (options2) => {
|
|
518
|
-
stores.forEach((store) =>
|
|
516
|
+
stores.forEach((store) => store.invalidate(options2));
|
|
519
517
|
},
|
|
520
518
|
/**
|
|
521
519
|
* Resets all query instances.
|
|
522
520
|
*/
|
|
523
521
|
resetAll: () => {
|
|
524
|
-
stores.forEach((store) =>
|
|
522
|
+
stores.forEach((store) => store.reset());
|
|
525
523
|
}
|
|
526
524
|
});
|
|
527
525
|
};
|
|
@@ -529,10 +527,10 @@ let focusListenersAdded = false;
|
|
|
529
527
|
const focusListeners = /* @__PURE__ */ new Set();
|
|
530
528
|
const onWindowFocus = () => [...focusListeners].forEach((fn) => fn());
|
|
531
529
|
let onlineListenersAdded = false;
|
|
532
|
-
const onlineListeners = /* @__PURE__ */ new Set();
|
|
533
|
-
const onWindowOnline = () => [...onlineListeners].forEach((fn) => fn());
|
|
530
|
+
const onlineListeners$1 = /* @__PURE__ */ new Set();
|
|
531
|
+
const onWindowOnline$1 = () => [...onlineListeners$1].forEach((fn) => fn());
|
|
534
532
|
|
|
535
|
-
const INITIAL_STATE = {
|
|
533
|
+
const INITIAL_STATE$1 = {
|
|
536
534
|
state: "INITIAL",
|
|
537
535
|
isPending: false,
|
|
538
536
|
isSuccess: false,
|
|
@@ -545,7 +543,7 @@ const INITIAL_STATE = {
|
|
|
545
543
|
};
|
|
546
544
|
const createMutation = (mutationFn, options = {}) => {
|
|
547
545
|
const { onSuccess = vanilla.noop, onError, onSettled = vanilla.noop } = options;
|
|
548
|
-
const initialState = { ...INITIAL_STATE };
|
|
546
|
+
const initialState = { ...INITIAL_STATE$1 };
|
|
549
547
|
let ongoingPromise;
|
|
550
548
|
const resolveFns = /* @__PURE__ */ new Set([]);
|
|
551
549
|
const store = vanilla.initStore(initialState, options);
|
|
@@ -663,7 +661,7 @@ const useMutation = (mutationFn, options = {}) => {
|
|
|
663
661
|
callbackRef.current.onSuccess = onSuccess;
|
|
664
662
|
callbackRef.current.onError = onError;
|
|
665
663
|
callbackRef.current.onSettled = onSettled;
|
|
666
|
-
const stateRef = react.useRef({ ...INITIAL_STATE });
|
|
664
|
+
const stateRef = react.useRef({ ...INITIAL_STATE$1 });
|
|
667
665
|
const [, reRender] = react.useState({});
|
|
668
666
|
const refs = react.useRef({
|
|
669
667
|
mutationFn,
|
|
@@ -746,7 +744,7 @@ const useMutation = (mutationFn, options = {}) => {
|
|
|
746
744
|
"Mutation state was reset while a request is still pending. The request will continue, but its result may override the reset state."
|
|
747
745
|
);
|
|
748
746
|
}
|
|
749
|
-
stateRef.current = { ...INITIAL_STATE };
|
|
747
|
+
stateRef.current = { ...INITIAL_STATE$1 };
|
|
750
748
|
reRender({});
|
|
751
749
|
}, []);
|
|
752
750
|
const r = [
|
|
@@ -760,10 +758,230 @@ const useMutation = (mutationFn, options = {}) => {
|
|
|
760
758
|
return r;
|
|
761
759
|
};
|
|
762
760
|
|
|
761
|
+
const INITIAL_STATE = {
|
|
762
|
+
connectionState: "INITIAL",
|
|
763
|
+
connectingAt: void 0,
|
|
764
|
+
connectedAt: void 0,
|
|
765
|
+
disconnectedAt: void 0,
|
|
766
|
+
state: "INITIAL",
|
|
767
|
+
isSuccess: false,
|
|
768
|
+
isError: false,
|
|
769
|
+
data: void 0,
|
|
770
|
+
dataUpdatedAt: void 0,
|
|
771
|
+
error: void 0,
|
|
772
|
+
errorUpdatedAt: void 0
|
|
773
|
+
};
|
|
774
|
+
const experimental_createStream = (connect, disconnect, options = {}) => {
|
|
775
|
+
const {
|
|
776
|
+
disconnectOn = () => 5e3,
|
|
777
|
+
// 5 seconds after any `DisconnectTrigger`
|
|
778
|
+
reconnectOn = () => false
|
|
779
|
+
// no need reconnect if still connected
|
|
780
|
+
} = options.connection || {};
|
|
781
|
+
const {
|
|
782
|
+
gcTime = 5 * 60 * 1e3
|
|
783
|
+
// 5 minutes
|
|
784
|
+
} = options.data || {};
|
|
785
|
+
const initialState = { ...INITIAL_STATE };
|
|
786
|
+
const stores = /* @__PURE__ */ new Map();
|
|
787
|
+
const connections = /* @__PURE__ */ new WeakMap();
|
|
788
|
+
const disconnectFns = /* @__PURE__ */ new WeakMap();
|
|
789
|
+
const disconnectTimeoutIds = /* @__PURE__ */ new WeakMap();
|
|
790
|
+
const clearDataTimeoutIds = /* @__PURE__ */ new WeakMap();
|
|
791
|
+
const configureStoreEvents = () => ({
|
|
792
|
+
...options,
|
|
793
|
+
onFirstSubscribe: (state, store) => {
|
|
794
|
+
var _a, _b;
|
|
795
|
+
clearTimeout((_a = disconnectTimeoutIds.get(store)) == null ? void 0 : _a["last-unsubscribe"]);
|
|
796
|
+
(_b = options.onFirstSubscribe) == null ? void 0 : _b.call(options, state, store);
|
|
797
|
+
triggerReconnect(store, "first-subscribe");
|
|
798
|
+
if (vanilla.isClient) {
|
|
799
|
+
visibilityChangeListeners.add(triggers.visibilityChange);
|
|
800
|
+
onlineListeners.add(triggers.online);
|
|
801
|
+
offlineListeners.add(triggers.offline);
|
|
802
|
+
if (!listenersAdded) {
|
|
803
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
804
|
+
window.addEventListener("online", onWindowOnline);
|
|
805
|
+
window.addEventListener("offline", onWindowOffline);
|
|
806
|
+
listenersAdded = true;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
},
|
|
810
|
+
onLastUnsubscribe: (state, store) => {
|
|
811
|
+
var _a;
|
|
812
|
+
(_a = options.onLastUnsubscribe) == null ? void 0 : _a.call(options, state, store);
|
|
813
|
+
triggerDisconnect(store, "last-unsubscribe");
|
|
814
|
+
if (vanilla.isClient) {
|
|
815
|
+
visibilityChangeListeners.delete(triggers.visibilityChange);
|
|
816
|
+
onlineListeners.delete(triggers.online);
|
|
817
|
+
offlineListeners.delete(triggers.offline);
|
|
818
|
+
if (visibilityChangeListeners.size === 0) {
|
|
819
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
820
|
+
window.removeEventListener("online", onWindowOnline);
|
|
821
|
+
window.removeEventListener("offline", onWindowOffline);
|
|
822
|
+
listenersAdded = false;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
const getStore = (variable = {}) => {
|
|
828
|
+
const variableHash = vanilla.getHash(variable);
|
|
829
|
+
let store;
|
|
830
|
+
if (stores.has(variableHash)) {
|
|
831
|
+
store = stores.get(variableHash);
|
|
832
|
+
} else {
|
|
833
|
+
store = vanilla.initStore(
|
|
834
|
+
initialState,
|
|
835
|
+
configureStoreEvents()
|
|
836
|
+
// Intentionally using as any: don't want to add generic on `initStore`
|
|
837
|
+
);
|
|
838
|
+
store.variableHash = variableHash;
|
|
839
|
+
stores.set(variableHash, store);
|
|
840
|
+
store.connection = {};
|
|
841
|
+
store.connection.get = () => connections.get(store);
|
|
842
|
+
store.connection.reconnect = () => {
|
|
843
|
+
var _a;
|
|
844
|
+
const { connectionState } = store.getState();
|
|
845
|
+
if (connectionState === "CONNECTING") return;
|
|
846
|
+
(_a = disconnectFns.get(store)) == null ? void 0 : _a();
|
|
847
|
+
store.setState({
|
|
848
|
+
connectionState: "CONNECTING",
|
|
849
|
+
connectingAt: Date.now()
|
|
850
|
+
});
|
|
851
|
+
const connection = connect(variable, {
|
|
852
|
+
connected: () => {
|
|
853
|
+
store.setState({
|
|
854
|
+
connectionState: "CONNECTED",
|
|
855
|
+
connectedAt: Date.now(),
|
|
856
|
+
disconnectedAt: void 0
|
|
857
|
+
});
|
|
858
|
+
},
|
|
859
|
+
data: (reducer) => {
|
|
860
|
+
store.setState((prev) => {
|
|
861
|
+
var _a2;
|
|
862
|
+
return {
|
|
863
|
+
connectionState: "CONNECTED",
|
|
864
|
+
connectedAt: (_a2 = prev.connectedAt) != null ? _a2 : Date.now(),
|
|
865
|
+
state: "SUCCESS",
|
|
866
|
+
isSuccess: true,
|
|
867
|
+
isError: false,
|
|
868
|
+
data: reducer(prev.data),
|
|
869
|
+
dataUpdatedAt: Date.now(),
|
|
870
|
+
error: void 0,
|
|
871
|
+
errorUpdatedAt: void 0
|
|
872
|
+
};
|
|
873
|
+
});
|
|
874
|
+
},
|
|
875
|
+
error: (error) => {
|
|
876
|
+
store.setState((prev) => ({
|
|
877
|
+
state: prev.state === "SUCCESS" ? "SUCCESS_BUT_THEN_ERROR" : "ERROR",
|
|
878
|
+
isError: true,
|
|
879
|
+
error,
|
|
880
|
+
errorUpdatedAt: Date.now()
|
|
881
|
+
}));
|
|
882
|
+
}
|
|
883
|
+
});
|
|
884
|
+
connections.set(store, connection);
|
|
885
|
+
disconnectFns.set(store, () => disconnect(connection));
|
|
886
|
+
};
|
|
887
|
+
store.connection.disconnect = () => {
|
|
888
|
+
var _a;
|
|
889
|
+
if (store.getSubscriberCount()) {
|
|
890
|
+
console.warn("Stream disconnected while there is subscriber");
|
|
891
|
+
}
|
|
892
|
+
const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
|
|
893
|
+
if (disconnectTimeoutIds_) {
|
|
894
|
+
clearTimeout(disconnectTimeoutIds_["last-unsubscribe"]);
|
|
895
|
+
clearTimeout(disconnectTimeoutIds_["document-hidden"]);
|
|
896
|
+
clearTimeout(disconnectTimeoutIds_.offline);
|
|
897
|
+
}
|
|
898
|
+
(_a = disconnectFns.get(store)) == null ? void 0 : _a();
|
|
899
|
+
if (store.getState().connectionState !== "INITIAL") {
|
|
900
|
+
store.setState({
|
|
901
|
+
connectionState: "DISCONNECTED",
|
|
902
|
+
disconnectedAt: Date.now()
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
connections.delete(store);
|
|
906
|
+
disconnectFns.delete(store);
|
|
907
|
+
clearDataTimeoutIds.set(
|
|
908
|
+
store,
|
|
909
|
+
setTimeout(() => {
|
|
910
|
+
store.data.reset();
|
|
911
|
+
}, gcTime)
|
|
912
|
+
);
|
|
913
|
+
};
|
|
914
|
+
store.data = {};
|
|
915
|
+
store.data.reset = () => {
|
|
916
|
+
store.setState({
|
|
917
|
+
state: "INITIAL",
|
|
918
|
+
isSuccess: false,
|
|
919
|
+
isError: false,
|
|
920
|
+
data: void 0,
|
|
921
|
+
dataUpdatedAt: void 0,
|
|
922
|
+
error: void 0,
|
|
923
|
+
errorUpdatedAt: void 0
|
|
924
|
+
});
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
const useStore = (options2) => useStoreState(store, {
|
|
928
|
+
initialState: { data: options2 == null ? void 0 : options2.initialData }
|
|
929
|
+
});
|
|
930
|
+
return Object.assign(useStore, store);
|
|
931
|
+
};
|
|
932
|
+
const triggerReconnect = (store, trigger) => {
|
|
933
|
+
clearTimeout(clearDataTimeoutIds.get(store));
|
|
934
|
+
const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
|
|
935
|
+
if (disconnectTimeoutIds_) {
|
|
936
|
+
clearTimeout(disconnectTimeoutIds_["last-unsubscribe"]);
|
|
937
|
+
clearTimeout(disconnectTimeoutIds_["document-hidden"]);
|
|
938
|
+
clearTimeout(disconnectTimeoutIds_.offline);
|
|
939
|
+
}
|
|
940
|
+
const { connectionState } = store.getState();
|
|
941
|
+
console.info("triggerReconnect", connectionState);
|
|
942
|
+
if (connectionState === "INITIAL" || connectionState === "DISCONNECTED") {
|
|
943
|
+
return store.connection.reconnect();
|
|
944
|
+
}
|
|
945
|
+
const shouldReconnect = reconnectOn(trigger, store.getState());
|
|
946
|
+
console.log({ shouldReconnect });
|
|
947
|
+
if (shouldReconnect) store.connection.reconnect();
|
|
948
|
+
};
|
|
949
|
+
const triggerDisconnect = (store, trigger) => {
|
|
950
|
+
const disconnectDelay = disconnectOn(trigger, store.getState());
|
|
951
|
+
if (typeof disconnectDelay !== "number") return;
|
|
952
|
+
if (!disconnectTimeoutIds.has(store)) disconnectTimeoutIds.set(store, {});
|
|
953
|
+
const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
|
|
954
|
+
disconnectTimeoutIds_[trigger] = setTimeout(() => {
|
|
955
|
+
store.connection.disconnect();
|
|
956
|
+
}, disconnectDelay);
|
|
957
|
+
};
|
|
958
|
+
const triggers = {
|
|
959
|
+
visibilityChange: () => {
|
|
960
|
+
console.info("visibilityChange", document.visibilityState);
|
|
961
|
+
if (document.visibilityState === "visible") {
|
|
962
|
+
stores.forEach((store) => triggerReconnect(store, "document-visible"));
|
|
963
|
+
} else {
|
|
964
|
+
stores.forEach((store) => triggerDisconnect(store, "document-hidden"));
|
|
965
|
+
}
|
|
966
|
+
},
|
|
967
|
+
online: () => stores.forEach((store) => triggerReconnect(store, "online")),
|
|
968
|
+
offline: () => stores.forEach((store) => triggerDisconnect(store, "offline"))
|
|
969
|
+
};
|
|
970
|
+
return getStore;
|
|
971
|
+
};
|
|
972
|
+
const visibilityChangeListeners = /* @__PURE__ */ new Set();
|
|
973
|
+
const onVisibilityChange = () => [...visibilityChangeListeners].forEach((fn) => fn());
|
|
974
|
+
const onlineListeners = /* @__PURE__ */ new Set();
|
|
975
|
+
const onWindowOnline = () => [...onlineListeners].forEach((fn) => fn());
|
|
976
|
+
const offlineListeners = /* @__PURE__ */ new Set();
|
|
977
|
+
const onWindowOffline = () => [...offlineListeners].forEach((fn) => fn());
|
|
978
|
+
let listenersAdded = false;
|
|
979
|
+
|
|
763
980
|
exports.createMutation = createMutation;
|
|
764
981
|
exports.createQuery = createQuery;
|
|
765
982
|
exports.createStore = createStore;
|
|
766
983
|
exports.createStores = createStores;
|
|
984
|
+
exports.experimental_createStream = experimental_createStream;
|
|
767
985
|
exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
|
|
768
986
|
exports.useMutation = useMutation;
|
|
769
987
|
exports.useStoreState = useStoreState;
|