floppy-disk 3.7.0-beta.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-query.d.mts +1 -1
- package/esm/react/create-stream.d.mts +88 -0
- package/esm/react.d.mts +1 -0
- package/esm/react.mjs +236 -22
- package/package.json +4 -1
- package/react/create-query.d.ts +1 -1
- package/react/create-stream.d.ts +88 -0
- package/react.d.ts +1 -0
- package/react.js +236 -21
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type InitStoreOptions, type StoreApi } from "../vanilla.mjs";
|
|
2
|
+
import type { StoreKey } from "./create-stores.mjs";
|
|
3
|
+
type StreamDataState<TData, TError> = {
|
|
4
|
+
state: "INITIAL";
|
|
5
|
+
isSuccess: false;
|
|
6
|
+
isError: false;
|
|
7
|
+
data: undefined;
|
|
8
|
+
dataUpdatedAt: undefined;
|
|
9
|
+
error: undefined;
|
|
10
|
+
errorUpdatedAt: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
state: "SUCCESS";
|
|
13
|
+
isSuccess: true;
|
|
14
|
+
isError: false;
|
|
15
|
+
data: TData;
|
|
16
|
+
dataUpdatedAt: number;
|
|
17
|
+
error: undefined;
|
|
18
|
+
errorUpdatedAt: undefined;
|
|
19
|
+
} | {
|
|
20
|
+
state: "ERROR";
|
|
21
|
+
isSuccess: false;
|
|
22
|
+
isError: true;
|
|
23
|
+
data: undefined;
|
|
24
|
+
dataUpdatedAt: undefined;
|
|
25
|
+
error: TError;
|
|
26
|
+
errorUpdatedAt: number;
|
|
27
|
+
} | {
|
|
28
|
+
state: "SUCCESS_BUT_THEN_ERROR";
|
|
29
|
+
isSuccess: true;
|
|
30
|
+
isError: true;
|
|
31
|
+
data: TData;
|
|
32
|
+
dataUpdatedAt: number;
|
|
33
|
+
error: TError;
|
|
34
|
+
errorUpdatedAt: number;
|
|
35
|
+
};
|
|
36
|
+
export type StreamState<TData, TError> = ({
|
|
37
|
+
connectionState: "INITIAL";
|
|
38
|
+
connectingAt: undefined;
|
|
39
|
+
connectedAt: undefined;
|
|
40
|
+
disconnectedAt: undefined;
|
|
41
|
+
} & Extract<StreamDataState<TData, TError>, {
|
|
42
|
+
state: "INITIAL";
|
|
43
|
+
}>) | ({
|
|
44
|
+
connectionState: "CONNECTING";
|
|
45
|
+
connectingAt: number;
|
|
46
|
+
connectedAt: number | undefined;
|
|
47
|
+
disconnectedAt: number | undefined;
|
|
48
|
+
} & StreamDataState<TData, TError>) | ({
|
|
49
|
+
connectionState: "CONNECTED";
|
|
50
|
+
connectingAt: number;
|
|
51
|
+
connectedAt: number;
|
|
52
|
+
disconnectedAt: undefined;
|
|
53
|
+
} & StreamDataState<TData, TError>) | ({
|
|
54
|
+
connectionState: "DISCONNECTED";
|
|
55
|
+
connectingAt: number;
|
|
56
|
+
connectedAt: number | undefined;
|
|
57
|
+
disconnectedAt: number;
|
|
58
|
+
} & StreamDataState<TData, TError>);
|
|
59
|
+
type DisconnectTrigger = "last-unsubscribe" | "document-hidden" | "offline";
|
|
60
|
+
type ReconnectTrigger = "first-subscribe" | "document-visible" | "online";
|
|
61
|
+
type AdditionalStoreApi<TConnection> = {
|
|
62
|
+
variableHash: string;
|
|
63
|
+
connection: {
|
|
64
|
+
get: () => Readonly<TConnection> | undefined;
|
|
65
|
+
reconnect: () => void;
|
|
66
|
+
disconnect: () => void;
|
|
67
|
+
};
|
|
68
|
+
data: {
|
|
69
|
+
reset: () => void;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
export type StreamOptions<TConnection, TData, TError = Error> = InitStoreOptions<StreamState<TData, TError>, AdditionalStoreApi<TConnection>> & {
|
|
73
|
+
connection?: {
|
|
74
|
+
disconnectOn?: (trigger: DisconnectTrigger, state: StreamState<TData, TError>) => false | number;
|
|
75
|
+
reconnectOn?: (trigger: ReconnectTrigger, state: StreamState<TData, TError>) => boolean;
|
|
76
|
+
};
|
|
77
|
+
data?: {
|
|
78
|
+
gcTime?: number;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
export declare const experimental_createStream: <TConnection, TData, TVariable extends StoreKey, TError = Error>(connect: (variable: TVariable, emit: {
|
|
82
|
+
connected: () => void;
|
|
83
|
+
data: (reducer: (data: TData | undefined) => TData) => void;
|
|
84
|
+
error: (error: TError) => void;
|
|
85
|
+
}) => TConnection, disconnect: (connection: TConnection) => void, options?: StreamOptions<TConnection, TData, TError>) => (variable?: TVariable) => ((options?: {
|
|
86
|
+
initialData?: TData;
|
|
87
|
+
}) => StreamState<TData, TError>) & StoreApi<StreamState<TData, TError>> & AdditionalStoreApi<TConnection>;
|
|
88
|
+
export {};
|
package/esm/react.d.mts
CHANGED
|
@@ -5,3 +5,4 @@ export * from "./react/create-stores.mjs";
|
|
|
5
5
|
export * from "./react/create-query.mjs";
|
|
6
6
|
export { createMutation, type MutationOptions, type MutationState, } from "./react/create-mutation.mjs";
|
|
7
7
|
export * from "./react/use-mutation.mjs";
|
|
8
|
+
export * from "./react/create-stream.mjs";
|
package/esm/react.mjs
CHANGED
|
@@ -119,7 +119,7 @@ const createStores = (initialState, options) => {
|
|
|
119
119
|
return getStore;
|
|
120
120
|
};
|
|
121
121
|
|
|
122
|
-
const INITIAL_STATE$
|
|
122
|
+
const INITIAL_STATE$2 = {
|
|
123
123
|
isPending: false,
|
|
124
124
|
isRevalidating: false,
|
|
125
125
|
willRetryAt: void 0,
|
|
@@ -147,7 +147,7 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
147
147
|
onSettled = noop,
|
|
148
148
|
shouldRetry: shouldRetryFn = (_, s) => s.retryCount === 0 ? [true, 1500] : [false]
|
|
149
149
|
} = options;
|
|
150
|
-
const initialState = { ...INITIAL_STATE$
|
|
150
|
+
const initialState = { ...INITIAL_STATE$2 };
|
|
151
151
|
const stores = /* @__PURE__ */ new Map();
|
|
152
152
|
const configureStoreEvents = (variableHash) => ({
|
|
153
153
|
...options,
|
|
@@ -165,9 +165,9 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
if (revalidateOnReconnect) {
|
|
168
|
-
onlineListeners.add(revalidate2);
|
|
168
|
+
onlineListeners$1.add(revalidate2);
|
|
169
169
|
if (!onlineListenersAdded) {
|
|
170
|
-
window.addEventListener("online", onWindowOnline);
|
|
170
|
+
window.addEventListener("online", onWindowOnline$1);
|
|
171
171
|
onlineListenersAdded = true;
|
|
172
172
|
}
|
|
173
173
|
}
|
|
@@ -199,9 +199,9 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
201
|
if (revalidateOnReconnect) {
|
|
202
|
-
onlineListeners.delete(revalidate2);
|
|
203
|
-
if (onlineListeners.size === 0) {
|
|
204
|
-
window.removeEventListener("online", onWindowOnline);
|
|
202
|
+
onlineListeners$1.delete(revalidate2);
|
|
203
|
+
if (onlineListeners$1.size === 0) {
|
|
204
|
+
window.removeEventListener("online", onWindowOnline$1);
|
|
205
205
|
onlineListenersAdded = false;
|
|
206
206
|
}
|
|
207
207
|
}
|
|
@@ -352,15 +352,10 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
352
352
|
isRevalidating: false,
|
|
353
353
|
isRetrying: false,
|
|
354
354
|
retryCount: 0,
|
|
355
|
+
state: store.getState().state === "SUCCESS" ? "SUCCESS_BUT_REVALIDATION_ERROR" : "ERROR",
|
|
356
|
+
isError: true,
|
|
355
357
|
error,
|
|
356
|
-
errorUpdatedAt: Date.now()
|
|
357
|
-
...store.getState().data ? {
|
|
358
|
-
state: "SUCCESS_BUT_REVALIDATION_ERROR",
|
|
359
|
-
isError: false
|
|
360
|
-
} : {
|
|
361
|
-
state: "ERROR",
|
|
362
|
-
isError: true
|
|
363
|
-
}
|
|
358
|
+
errorUpdatedAt: Date.now()
|
|
364
359
|
});
|
|
365
360
|
const state = store.getState();
|
|
366
361
|
resolve(state);
|
|
@@ -530,10 +525,10 @@ let focusListenersAdded = false;
|
|
|
530
525
|
const focusListeners = /* @__PURE__ */ new Set();
|
|
531
526
|
const onWindowFocus = () => [...focusListeners].forEach((fn) => fn());
|
|
532
527
|
let onlineListenersAdded = false;
|
|
533
|
-
const onlineListeners = /* @__PURE__ */ new Set();
|
|
534
|
-
const onWindowOnline = () => [...onlineListeners].forEach((fn) => fn());
|
|
528
|
+
const onlineListeners$1 = /* @__PURE__ */ new Set();
|
|
529
|
+
const onWindowOnline$1 = () => [...onlineListeners$1].forEach((fn) => fn());
|
|
535
530
|
|
|
536
|
-
const INITIAL_STATE = {
|
|
531
|
+
const INITIAL_STATE$1 = {
|
|
537
532
|
state: "INITIAL",
|
|
538
533
|
isPending: false,
|
|
539
534
|
isSuccess: false,
|
|
@@ -546,7 +541,7 @@ const INITIAL_STATE = {
|
|
|
546
541
|
};
|
|
547
542
|
const createMutation = (mutationFn, options = {}) => {
|
|
548
543
|
const { onSuccess = noop, onError, onSettled = noop } = options;
|
|
549
|
-
const initialState = { ...INITIAL_STATE };
|
|
544
|
+
const initialState = { ...INITIAL_STATE$1 };
|
|
550
545
|
let ongoingPromise;
|
|
551
546
|
const resolveFns = /* @__PURE__ */ new Set([]);
|
|
552
547
|
const store = initStore(initialState, options);
|
|
@@ -664,7 +659,7 @@ const useMutation = (mutationFn, options = {}) => {
|
|
|
664
659
|
callbackRef.current.onSuccess = onSuccess;
|
|
665
660
|
callbackRef.current.onError = onError;
|
|
666
661
|
callbackRef.current.onSettled = onSettled;
|
|
667
|
-
const stateRef = useRef({ ...INITIAL_STATE });
|
|
662
|
+
const stateRef = useRef({ ...INITIAL_STATE$1 });
|
|
668
663
|
const [, reRender] = useState({});
|
|
669
664
|
const refs = useRef({
|
|
670
665
|
mutationFn,
|
|
@@ -747,7 +742,7 @@ const useMutation = (mutationFn, options = {}) => {
|
|
|
747
742
|
"Mutation state was reset while a request is still pending. The request will continue, but its result may override the reset state."
|
|
748
743
|
);
|
|
749
744
|
}
|
|
750
|
-
stateRef.current = { ...INITIAL_STATE };
|
|
745
|
+
stateRef.current = { ...INITIAL_STATE$1 };
|
|
751
746
|
reRender({});
|
|
752
747
|
}, []);
|
|
753
748
|
const r = [
|
|
@@ -761,4 +756,223 @@ const useMutation = (mutationFn, options = {}) => {
|
|
|
761
756
|
return r;
|
|
762
757
|
};
|
|
763
758
|
|
|
764
|
-
|
|
759
|
+
const INITIAL_STATE = {
|
|
760
|
+
connectionState: "INITIAL",
|
|
761
|
+
connectingAt: void 0,
|
|
762
|
+
connectedAt: void 0,
|
|
763
|
+
disconnectedAt: void 0,
|
|
764
|
+
state: "INITIAL",
|
|
765
|
+
isSuccess: false,
|
|
766
|
+
isError: false,
|
|
767
|
+
data: void 0,
|
|
768
|
+
dataUpdatedAt: void 0,
|
|
769
|
+
error: void 0,
|
|
770
|
+
errorUpdatedAt: void 0
|
|
771
|
+
};
|
|
772
|
+
const experimental_createStream = (connect, disconnect, options = {}) => {
|
|
773
|
+
const {
|
|
774
|
+
disconnectOn = () => 5e3,
|
|
775
|
+
// 5 seconds after any `DisconnectTrigger`
|
|
776
|
+
reconnectOn = () => false
|
|
777
|
+
// no need reconnect if still connected
|
|
778
|
+
} = options.connection || {};
|
|
779
|
+
const {
|
|
780
|
+
gcTime = 5 * 60 * 1e3
|
|
781
|
+
// 5 minutes
|
|
782
|
+
} = options.data || {};
|
|
783
|
+
const initialState = { ...INITIAL_STATE };
|
|
784
|
+
const stores = /* @__PURE__ */ new Map();
|
|
785
|
+
const connections = /* @__PURE__ */ new WeakMap();
|
|
786
|
+
const disconnectFns = /* @__PURE__ */ new WeakMap();
|
|
787
|
+
const disconnectTimeoutIds = /* @__PURE__ */ new WeakMap();
|
|
788
|
+
const clearDataTimeoutIds = /* @__PURE__ */ new WeakMap();
|
|
789
|
+
const configureStoreEvents = () => ({
|
|
790
|
+
...options,
|
|
791
|
+
onFirstSubscribe: (state, store) => {
|
|
792
|
+
var _a, _b;
|
|
793
|
+
clearTimeout((_a = disconnectTimeoutIds.get(store)) == null ? void 0 : _a["last-unsubscribe"]);
|
|
794
|
+
(_b = options.onFirstSubscribe) == null ? void 0 : _b.call(options, state, store);
|
|
795
|
+
triggerReconnect(store, "first-subscribe");
|
|
796
|
+
if (isClient) {
|
|
797
|
+
visibilityChangeListeners.add(triggers.visibilityChange);
|
|
798
|
+
onlineListeners.add(triggers.online);
|
|
799
|
+
offlineListeners.add(triggers.offline);
|
|
800
|
+
if (!listenersAdded) {
|
|
801
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
802
|
+
window.addEventListener("online", onWindowOnline);
|
|
803
|
+
window.addEventListener("offline", onWindowOffline);
|
|
804
|
+
listenersAdded = true;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
},
|
|
808
|
+
onLastUnsubscribe: (state, store) => {
|
|
809
|
+
var _a;
|
|
810
|
+
(_a = options.onLastUnsubscribe) == null ? void 0 : _a.call(options, state, store);
|
|
811
|
+
triggerDisconnect(store, "last-unsubscribe");
|
|
812
|
+
if (isClient) {
|
|
813
|
+
visibilityChangeListeners.delete(triggers.visibilityChange);
|
|
814
|
+
onlineListeners.delete(triggers.online);
|
|
815
|
+
offlineListeners.delete(triggers.offline);
|
|
816
|
+
if (visibilityChangeListeners.size === 0) {
|
|
817
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
818
|
+
window.removeEventListener("online", onWindowOnline);
|
|
819
|
+
window.removeEventListener("offline", onWindowOffline);
|
|
820
|
+
listenersAdded = false;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
});
|
|
825
|
+
const getStore = (variable = {}) => {
|
|
826
|
+
const variableHash = getHash(variable);
|
|
827
|
+
let store;
|
|
828
|
+
if (stores.has(variableHash)) {
|
|
829
|
+
store = stores.get(variableHash);
|
|
830
|
+
} else {
|
|
831
|
+
store = initStore(
|
|
832
|
+
initialState,
|
|
833
|
+
configureStoreEvents()
|
|
834
|
+
// Intentionally using as any: don't want to add generic on `initStore`
|
|
835
|
+
);
|
|
836
|
+
store.variableHash = variableHash;
|
|
837
|
+
stores.set(variableHash, store);
|
|
838
|
+
store.connection = {};
|
|
839
|
+
store.connection.get = () => connections.get(store);
|
|
840
|
+
store.connection.reconnect = () => {
|
|
841
|
+
var _a;
|
|
842
|
+
const { connectionState } = store.getState();
|
|
843
|
+
if (connectionState === "CONNECTING") return;
|
|
844
|
+
(_a = disconnectFns.get(store)) == null ? void 0 : _a();
|
|
845
|
+
store.setState({
|
|
846
|
+
connectionState: "CONNECTING",
|
|
847
|
+
connectingAt: Date.now()
|
|
848
|
+
});
|
|
849
|
+
const connection = connect(variable, {
|
|
850
|
+
connected: () => {
|
|
851
|
+
store.setState({
|
|
852
|
+
connectionState: "CONNECTED",
|
|
853
|
+
connectedAt: Date.now(),
|
|
854
|
+
disconnectedAt: void 0
|
|
855
|
+
});
|
|
856
|
+
},
|
|
857
|
+
data: (reducer) => {
|
|
858
|
+
store.setState((prev) => {
|
|
859
|
+
var _a2;
|
|
860
|
+
return {
|
|
861
|
+
connectionState: "CONNECTED",
|
|
862
|
+
connectedAt: (_a2 = prev.connectedAt) != null ? _a2 : Date.now(),
|
|
863
|
+
state: "SUCCESS",
|
|
864
|
+
isSuccess: true,
|
|
865
|
+
isError: false,
|
|
866
|
+
data: reducer(prev.data),
|
|
867
|
+
dataUpdatedAt: Date.now(),
|
|
868
|
+
error: void 0,
|
|
869
|
+
errorUpdatedAt: void 0
|
|
870
|
+
};
|
|
871
|
+
});
|
|
872
|
+
},
|
|
873
|
+
error: (error) => {
|
|
874
|
+
store.setState((prev) => ({
|
|
875
|
+
state: prev.state === "SUCCESS" ? "SUCCESS_BUT_THEN_ERROR" : "ERROR",
|
|
876
|
+
isError: true,
|
|
877
|
+
error,
|
|
878
|
+
errorUpdatedAt: Date.now()
|
|
879
|
+
}));
|
|
880
|
+
}
|
|
881
|
+
});
|
|
882
|
+
connections.set(store, connection);
|
|
883
|
+
disconnectFns.set(store, () => disconnect(connection));
|
|
884
|
+
};
|
|
885
|
+
store.connection.disconnect = () => {
|
|
886
|
+
var _a;
|
|
887
|
+
if (store.getSubscriberCount()) {
|
|
888
|
+
console.warn("Stream disconnected while there is subscriber");
|
|
889
|
+
}
|
|
890
|
+
const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
|
|
891
|
+
if (disconnectTimeoutIds_) {
|
|
892
|
+
clearTimeout(disconnectTimeoutIds_["last-unsubscribe"]);
|
|
893
|
+
clearTimeout(disconnectTimeoutIds_["document-hidden"]);
|
|
894
|
+
clearTimeout(disconnectTimeoutIds_.offline);
|
|
895
|
+
}
|
|
896
|
+
(_a = disconnectFns.get(store)) == null ? void 0 : _a();
|
|
897
|
+
if (store.getState().connectionState !== "INITIAL") {
|
|
898
|
+
store.setState({
|
|
899
|
+
connectionState: "DISCONNECTED",
|
|
900
|
+
disconnectedAt: Date.now()
|
|
901
|
+
});
|
|
902
|
+
}
|
|
903
|
+
connections.delete(store);
|
|
904
|
+
disconnectFns.delete(store);
|
|
905
|
+
clearDataTimeoutIds.set(
|
|
906
|
+
store,
|
|
907
|
+
setTimeout(() => {
|
|
908
|
+
store.data.reset();
|
|
909
|
+
}, gcTime)
|
|
910
|
+
);
|
|
911
|
+
};
|
|
912
|
+
store.data = {};
|
|
913
|
+
store.data.reset = () => {
|
|
914
|
+
store.setState({
|
|
915
|
+
state: "INITIAL",
|
|
916
|
+
isSuccess: false,
|
|
917
|
+
isError: false,
|
|
918
|
+
data: void 0,
|
|
919
|
+
dataUpdatedAt: void 0,
|
|
920
|
+
error: void 0,
|
|
921
|
+
errorUpdatedAt: void 0
|
|
922
|
+
});
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
const useStore = (options2) => useStoreState(store, {
|
|
926
|
+
initialState: { data: options2 == null ? void 0 : options2.initialData }
|
|
927
|
+
});
|
|
928
|
+
return Object.assign(useStore, store);
|
|
929
|
+
};
|
|
930
|
+
const triggerReconnect = (store, trigger) => {
|
|
931
|
+
clearTimeout(clearDataTimeoutIds.get(store));
|
|
932
|
+
const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
|
|
933
|
+
if (disconnectTimeoutIds_) {
|
|
934
|
+
clearTimeout(disconnectTimeoutIds_["last-unsubscribe"]);
|
|
935
|
+
clearTimeout(disconnectTimeoutIds_["document-hidden"]);
|
|
936
|
+
clearTimeout(disconnectTimeoutIds_.offline);
|
|
937
|
+
}
|
|
938
|
+
const { connectionState } = store.getState();
|
|
939
|
+
console.info("triggerReconnect", connectionState);
|
|
940
|
+
if (connectionState === "INITIAL" || connectionState === "DISCONNECTED") {
|
|
941
|
+
return store.connection.reconnect();
|
|
942
|
+
}
|
|
943
|
+
const shouldReconnect = reconnectOn(trigger, store.getState());
|
|
944
|
+
console.log({ shouldReconnect });
|
|
945
|
+
if (shouldReconnect) store.connection.reconnect();
|
|
946
|
+
};
|
|
947
|
+
const triggerDisconnect = (store, trigger) => {
|
|
948
|
+
const disconnectDelay = disconnectOn(trigger, store.getState());
|
|
949
|
+
if (typeof disconnectDelay !== "number") return;
|
|
950
|
+
if (!disconnectTimeoutIds.has(store)) disconnectTimeoutIds.set(store, {});
|
|
951
|
+
const disconnectTimeoutIds_ = disconnectTimeoutIds.get(store);
|
|
952
|
+
disconnectTimeoutIds_[trigger] = setTimeout(() => {
|
|
953
|
+
store.connection.disconnect();
|
|
954
|
+
}, disconnectDelay);
|
|
955
|
+
};
|
|
956
|
+
const triggers = {
|
|
957
|
+
visibilityChange: () => {
|
|
958
|
+
console.info("visibilityChange", document.visibilityState);
|
|
959
|
+
if (document.visibilityState === "visible") {
|
|
960
|
+
stores.forEach((store) => triggerReconnect(store, "document-visible"));
|
|
961
|
+
} else {
|
|
962
|
+
stores.forEach((store) => triggerDisconnect(store, "document-hidden"));
|
|
963
|
+
}
|
|
964
|
+
},
|
|
965
|
+
online: () => stores.forEach((store) => triggerReconnect(store, "online")),
|
|
966
|
+
offline: () => stores.forEach((store) => triggerDisconnect(store, "offline"))
|
|
967
|
+
};
|
|
968
|
+
return getStore;
|
|
969
|
+
};
|
|
970
|
+
const visibilityChangeListeners = /* @__PURE__ */ new Set();
|
|
971
|
+
const onVisibilityChange = () => [...visibilityChangeListeners].forEach((fn) => fn());
|
|
972
|
+
const onlineListeners = /* @__PURE__ */ new Set();
|
|
973
|
+
const onWindowOnline = () => [...onlineListeners].forEach((fn) => fn());
|
|
974
|
+
const offlineListeners = /* @__PURE__ */ new Set();
|
|
975
|
+
const onWindowOffline = () => [...offlineListeners].forEach((fn) => fn());
|
|
976
|
+
let listenersAdded = false;
|
|
977
|
+
|
|
978
|
+
export { createMutation, createQuery, createStore, createStores, experimental_createStream, useIsomorphicLayoutEffect, useMutation, useStoreState };
|
package/package.json
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
"name": "floppy-disk",
|
|
3
3
|
"description": "Lightweight unified state management for sync and async data.",
|
|
4
4
|
"private": false,
|
|
5
|
-
"version": "3.7.0-beta.
|
|
5
|
+
"version": "3.7.0-beta.2",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"tag": "beta"
|
|
8
|
+
},
|
|
6
9
|
"keywords": [
|
|
7
10
|
"utilities",
|
|
8
11
|
"store",
|
package/react/create-query.d.ts
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type InitStoreOptions, type StoreApi } from "../vanilla.ts";
|
|
2
|
+
import type { StoreKey } from "./create-stores.ts";
|
|
3
|
+
type StreamDataState<TData, TError> = {
|
|
4
|
+
state: "INITIAL";
|
|
5
|
+
isSuccess: false;
|
|
6
|
+
isError: false;
|
|
7
|
+
data: undefined;
|
|
8
|
+
dataUpdatedAt: undefined;
|
|
9
|
+
error: undefined;
|
|
10
|
+
errorUpdatedAt: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
state: "SUCCESS";
|
|
13
|
+
isSuccess: true;
|
|
14
|
+
isError: false;
|
|
15
|
+
data: TData;
|
|
16
|
+
dataUpdatedAt: number;
|
|
17
|
+
error: undefined;
|
|
18
|
+
errorUpdatedAt: undefined;
|
|
19
|
+
} | {
|
|
20
|
+
state: "ERROR";
|
|
21
|
+
isSuccess: false;
|
|
22
|
+
isError: true;
|
|
23
|
+
data: undefined;
|
|
24
|
+
dataUpdatedAt: undefined;
|
|
25
|
+
error: TError;
|
|
26
|
+
errorUpdatedAt: number;
|
|
27
|
+
} | {
|
|
28
|
+
state: "SUCCESS_BUT_THEN_ERROR";
|
|
29
|
+
isSuccess: true;
|
|
30
|
+
isError: true;
|
|
31
|
+
data: TData;
|
|
32
|
+
dataUpdatedAt: number;
|
|
33
|
+
error: TError;
|
|
34
|
+
errorUpdatedAt: number;
|
|
35
|
+
};
|
|
36
|
+
export type StreamState<TData, TError> = ({
|
|
37
|
+
connectionState: "INITIAL";
|
|
38
|
+
connectingAt: undefined;
|
|
39
|
+
connectedAt: undefined;
|
|
40
|
+
disconnectedAt: undefined;
|
|
41
|
+
} & Extract<StreamDataState<TData, TError>, {
|
|
42
|
+
state: "INITIAL";
|
|
43
|
+
}>) | ({
|
|
44
|
+
connectionState: "CONNECTING";
|
|
45
|
+
connectingAt: number;
|
|
46
|
+
connectedAt: number | undefined;
|
|
47
|
+
disconnectedAt: number | undefined;
|
|
48
|
+
} & StreamDataState<TData, TError>) | ({
|
|
49
|
+
connectionState: "CONNECTED";
|
|
50
|
+
connectingAt: number;
|
|
51
|
+
connectedAt: number;
|
|
52
|
+
disconnectedAt: undefined;
|
|
53
|
+
} & StreamDataState<TData, TError>) | ({
|
|
54
|
+
connectionState: "DISCONNECTED";
|
|
55
|
+
connectingAt: number;
|
|
56
|
+
connectedAt: number | undefined;
|
|
57
|
+
disconnectedAt: number;
|
|
58
|
+
} & StreamDataState<TData, TError>);
|
|
59
|
+
type DisconnectTrigger = "last-unsubscribe" | "document-hidden" | "offline";
|
|
60
|
+
type ReconnectTrigger = "first-subscribe" | "document-visible" | "online";
|
|
61
|
+
type AdditionalStoreApi<TConnection> = {
|
|
62
|
+
variableHash: string;
|
|
63
|
+
connection: {
|
|
64
|
+
get: () => Readonly<TConnection> | undefined;
|
|
65
|
+
reconnect: () => void;
|
|
66
|
+
disconnect: () => void;
|
|
67
|
+
};
|
|
68
|
+
data: {
|
|
69
|
+
reset: () => void;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
export type StreamOptions<TConnection, TData, TError = Error> = InitStoreOptions<StreamState<TData, TError>, AdditionalStoreApi<TConnection>> & {
|
|
73
|
+
connection?: {
|
|
74
|
+
disconnectOn?: (trigger: DisconnectTrigger, state: StreamState<TData, TError>) => false | number;
|
|
75
|
+
reconnectOn?: (trigger: ReconnectTrigger, state: StreamState<TData, TError>) => boolean;
|
|
76
|
+
};
|
|
77
|
+
data?: {
|
|
78
|
+
gcTime?: number;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
export declare const experimental_createStream: <TConnection, TData, TVariable extends StoreKey, TError = Error>(connect: (variable: TVariable, emit: {
|
|
82
|
+
connected: () => void;
|
|
83
|
+
data: (reducer: (data: TData | undefined) => TData) => void;
|
|
84
|
+
error: (error: TError) => void;
|
|
85
|
+
}) => TConnection, disconnect: (connection: TConnection) => void, options?: StreamOptions<TConnection, TData, TError>) => (variable?: TVariable) => ((options?: {
|
|
86
|
+
initialData?: TData;
|
|
87
|
+
}) => StreamState<TData, TError>) & StoreApi<StreamState<TData, TError>> & AdditionalStoreApi<TConnection>;
|
|
88
|
+
export {};
|
package/react.d.ts
CHANGED
|
@@ -5,3 +5,4 @@ export * from "./react/create-stores.ts";
|
|
|
5
5
|
export * from "./react/create-query.ts";
|
|
6
6
|
export { createMutation, type MutationOptions, type MutationState, } from "./react/create-mutation.ts";
|
|
7
7
|
export * from "./react/use-mutation.ts";
|
|
8
|
+
export * from "./react/create-stream.ts";
|
package/react.js
CHANGED
|
@@ -121,7 +121,7 @@ const createStores = (initialState, options) => {
|
|
|
121
121
|
return getStore;
|
|
122
122
|
};
|
|
123
123
|
|
|
124
|
-
const INITIAL_STATE$
|
|
124
|
+
const INITIAL_STATE$2 = {
|
|
125
125
|
isPending: false,
|
|
126
126
|
isRevalidating: false,
|
|
127
127
|
willRetryAt: void 0,
|
|
@@ -149,7 +149,7 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
149
149
|
onSettled = vanilla.noop,
|
|
150
150
|
shouldRetry: shouldRetryFn = (_, s) => s.retryCount === 0 ? [true, 1500] : [false]
|
|
151
151
|
} = options;
|
|
152
|
-
const initialState = { ...INITIAL_STATE$
|
|
152
|
+
const initialState = { ...INITIAL_STATE$2 };
|
|
153
153
|
const stores = /* @__PURE__ */ new Map();
|
|
154
154
|
const configureStoreEvents = (variableHash) => ({
|
|
155
155
|
...options,
|
|
@@ -167,9 +167,9 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
if (revalidateOnReconnect) {
|
|
170
|
-
onlineListeners.add(revalidate2);
|
|
170
|
+
onlineListeners$1.add(revalidate2);
|
|
171
171
|
if (!onlineListenersAdded) {
|
|
172
|
-
window.addEventListener("online", onWindowOnline);
|
|
172
|
+
window.addEventListener("online", onWindowOnline$1);
|
|
173
173
|
onlineListenersAdded = true;
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -201,9 +201,9 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
if (revalidateOnReconnect) {
|
|
204
|
-
onlineListeners.delete(revalidate2);
|
|
205
|
-
if (onlineListeners.size === 0) {
|
|
206
|
-
window.removeEventListener("online", onWindowOnline);
|
|
204
|
+
onlineListeners$1.delete(revalidate2);
|
|
205
|
+
if (onlineListeners$1.size === 0) {
|
|
206
|
+
window.removeEventListener("online", onWindowOnline$1);
|
|
207
207
|
onlineListenersAdded = false;
|
|
208
208
|
}
|
|
209
209
|
}
|
|
@@ -354,15 +354,10 @@ const createQuery = (queryFn, options = {}) => {
|
|
|
354
354
|
isRevalidating: false,
|
|
355
355
|
isRetrying: false,
|
|
356
356
|
retryCount: 0,
|
|
357
|
+
state: store.getState().state === "SUCCESS" ? "SUCCESS_BUT_REVALIDATION_ERROR" : "ERROR",
|
|
358
|
+
isError: true,
|
|
357
359
|
error,
|
|
358
|
-
errorUpdatedAt: Date.now()
|
|
359
|
-
...store.getState().data ? {
|
|
360
|
-
state: "SUCCESS_BUT_REVALIDATION_ERROR",
|
|
361
|
-
isError: false
|
|
362
|
-
} : {
|
|
363
|
-
state: "ERROR",
|
|
364
|
-
isError: true
|
|
365
|
-
}
|
|
360
|
+
errorUpdatedAt: Date.now()
|
|
366
361
|
});
|
|
367
362
|
const state = store.getState();
|
|
368
363
|
resolve(state);
|
|
@@ -532,10 +527,10 @@ let focusListenersAdded = false;
|
|
|
532
527
|
const focusListeners = /* @__PURE__ */ new Set();
|
|
533
528
|
const onWindowFocus = () => [...focusListeners].forEach((fn) => fn());
|
|
534
529
|
let onlineListenersAdded = false;
|
|
535
|
-
const onlineListeners = /* @__PURE__ */ new Set();
|
|
536
|
-
const onWindowOnline = () => [...onlineListeners].forEach((fn) => fn());
|
|
530
|
+
const onlineListeners$1 = /* @__PURE__ */ new Set();
|
|
531
|
+
const onWindowOnline$1 = () => [...onlineListeners$1].forEach((fn) => fn());
|
|
537
532
|
|
|
538
|
-
const INITIAL_STATE = {
|
|
533
|
+
const INITIAL_STATE$1 = {
|
|
539
534
|
state: "INITIAL",
|
|
540
535
|
isPending: false,
|
|
541
536
|
isSuccess: false,
|
|
@@ -548,7 +543,7 @@ const INITIAL_STATE = {
|
|
|
548
543
|
};
|
|
549
544
|
const createMutation = (mutationFn, options = {}) => {
|
|
550
545
|
const { onSuccess = vanilla.noop, onError, onSettled = vanilla.noop } = options;
|
|
551
|
-
const initialState = { ...INITIAL_STATE };
|
|
546
|
+
const initialState = { ...INITIAL_STATE$1 };
|
|
552
547
|
let ongoingPromise;
|
|
553
548
|
const resolveFns = /* @__PURE__ */ new Set([]);
|
|
554
549
|
const store = vanilla.initStore(initialState, options);
|
|
@@ -666,7 +661,7 @@ const useMutation = (mutationFn, options = {}) => {
|
|
|
666
661
|
callbackRef.current.onSuccess = onSuccess;
|
|
667
662
|
callbackRef.current.onError = onError;
|
|
668
663
|
callbackRef.current.onSettled = onSettled;
|
|
669
|
-
const stateRef = react.useRef({ ...INITIAL_STATE });
|
|
664
|
+
const stateRef = react.useRef({ ...INITIAL_STATE$1 });
|
|
670
665
|
const [, reRender] = react.useState({});
|
|
671
666
|
const refs = react.useRef({
|
|
672
667
|
mutationFn,
|
|
@@ -749,7 +744,7 @@ const useMutation = (mutationFn, options = {}) => {
|
|
|
749
744
|
"Mutation state was reset while a request is still pending. The request will continue, but its result may override the reset state."
|
|
750
745
|
);
|
|
751
746
|
}
|
|
752
|
-
stateRef.current = { ...INITIAL_STATE };
|
|
747
|
+
stateRef.current = { ...INITIAL_STATE$1 };
|
|
753
748
|
reRender({});
|
|
754
749
|
}, []);
|
|
755
750
|
const r = [
|
|
@@ -763,10 +758,230 @@ const useMutation = (mutationFn, options = {}) => {
|
|
|
763
758
|
return r;
|
|
764
759
|
};
|
|
765
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
|
+
|
|
766
980
|
exports.createMutation = createMutation;
|
|
767
981
|
exports.createQuery = createQuery;
|
|
768
982
|
exports.createStore = createStore;
|
|
769
983
|
exports.createStores = createStores;
|
|
984
|
+
exports.experimental_createStream = experimental_createStream;
|
|
770
985
|
exports.useIsomorphicLayoutEffect = useIsomorphicLayoutEffect;
|
|
771
986
|
exports.useMutation = useMutation;
|
|
772
987
|
exports.useStoreState = useStoreState;
|