reactjrx 1.46.0 → 1.48.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/dist/index.cjs +123 -170
- package/dist/index.d.ts +4 -8
- package/dist/index.js +125 -172
- package/dist/lib/queries/client/createClient.d.ts +4 -0
- package/dist/lib/queries/react/Provider.d.ts +2 -2
- package/dist/lib/state/persistance/{createSharedStoreAdapter.d.ts → adapters/createSharedStoreAdapter.d.ts} +1 -1
- package/dist/lib/state/persistance/constants.d.ts +1 -0
- package/dist/lib/state/persistance/types.d.ts +4 -3
- package/dist/lib/state/persistance/usePersistSignals.d.ts +12 -0
- package/dist/lib/state/signal.d.ts +15 -11
- package/dist/lib/state/useSignalValue.d.ts +1 -1
- package/package.json +1 -1
- package/dist/lib/state/persistance/PersistSignals.d.ts +0 -12
- package/dist/lib/state/persistance/withPersistance.d.ts +0 -18
- package/dist/lib/state/useScopeSignals.d.ts +0 -5
- package/dist/lib/state/useSetSignal.d.ts +0 -2
- package/dist/lib/state/useSignal.d.ts +0 -2
- /package/dist/lib/state/persistance/{createLocalStorageAdapter.d.ts → adapters/createLocalStorageAdapter.d.ts} +0 -0
- /package/dist/lib/state/persistance/{createLocalforageAdapter.d.ts → adapters/createLocalforageAdapter.d.ts} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
+
var __publicField = (obj, key, value) => {
|
|
5
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
6
|
+
return value;
|
|
7
|
+
};
|
|
2
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
9
|
const react = require("react");
|
|
4
10
|
const rxjs = require("rxjs");
|
|
5
|
-
const jsxRuntime = require("react/jsx-runtime");
|
|
6
11
|
const operators = require("rxjs/operators");
|
|
12
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
7
13
|
const useLiveRef = (value) => {
|
|
8
14
|
const ref = react.useRef(value);
|
|
9
15
|
react.useMemo(() => {
|
|
@@ -163,12 +169,10 @@ const useBehaviorSubject = (state) => {
|
|
|
163
169
|
return subject;
|
|
164
170
|
};
|
|
165
171
|
const SIGNAL_RESET = Symbol("SIGNAL_RESET");
|
|
166
|
-
function signal(
|
|
167
|
-
const { default: defaultValue2 } =
|
|
172
|
+
function signal(config) {
|
|
173
|
+
const { default: defaultValue2 } = config ?? {};
|
|
168
174
|
const subject = new rxjs.BehaviorSubject(defaultValue2);
|
|
169
175
|
const setValue = (arg) => {
|
|
170
|
-
if (arg === subject.getValue())
|
|
171
|
-
return;
|
|
172
176
|
if (typeof arg === "function") {
|
|
173
177
|
const change = arg(subject.getValue());
|
|
174
178
|
if (change === subject.getValue())
|
|
@@ -184,166 +188,15 @@ function signal(options) {
|
|
|
184
188
|
};
|
|
185
189
|
const getValue = () => subject.getValue();
|
|
186
190
|
return {
|
|
187
|
-
|
|
191
|
+
setValue,
|
|
188
192
|
getValue,
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* @important
|
|
192
|
-
* We return the original behavior subject for two reasons:
|
|
193
|
-
* - useObserve may return the default value directly instead of undefined
|
|
194
|
-
* - the scope exist for react binding, this observable is a direct access outside of it
|
|
195
|
-
*/
|
|
193
|
+
config,
|
|
196
194
|
subject
|
|
197
195
|
};
|
|
198
196
|
}
|
|
199
|
-
const useSetSignal = (signal2) => {
|
|
200
|
-
return signal2.setState;
|
|
201
|
-
};
|
|
202
197
|
const useSignalValue = (signal2, key) => {
|
|
203
198
|
return useObserve(signal2.subject, { defaultValue: signal2.getValue(), key });
|
|
204
199
|
};
|
|
205
|
-
const useSignal = (signal2) => {
|
|
206
|
-
return [useSignalValue(signal2), useSetSignal(signal2)];
|
|
207
|
-
};
|
|
208
|
-
const useScopeSignals = (signals) => {
|
|
209
|
-
const signalsRef = useLiveRef(signals);
|
|
210
|
-
react.useEffect(
|
|
211
|
-
() => () => {
|
|
212
|
-
signalsRef.current.forEach(({ setState }) => {
|
|
213
|
-
setState(SIGNAL_RESET);
|
|
214
|
-
});
|
|
215
|
-
},
|
|
216
|
-
[]
|
|
217
|
-
);
|
|
218
|
-
};
|
|
219
|
-
const createLocalStorageAdapter = (forage) => ({
|
|
220
|
-
getItem: async (key) => {
|
|
221
|
-
const serializedValue = forage.getItem(key);
|
|
222
|
-
if (!serializedValue)
|
|
223
|
-
return void 0;
|
|
224
|
-
return JSON.parse(serializedValue);
|
|
225
|
-
},
|
|
226
|
-
setItem: async (key, value) => {
|
|
227
|
-
forage.setItem(key, JSON.stringify(value));
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
const PersistSignalsContext = react.createContext({
|
|
231
|
-
resetSignals: () => {
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
const usePersistSignalsContext = () => react.useContext(PersistSignalsContext);
|
|
235
|
-
const PersistSignals = react.memo(
|
|
236
|
-
({
|
|
237
|
-
children,
|
|
238
|
-
signals = [],
|
|
239
|
-
onReady,
|
|
240
|
-
adapter = createLocalStorageAdapter(localStorage)
|
|
241
|
-
}) => {
|
|
242
|
-
const persistanceRef = useLiveRef(signals);
|
|
243
|
-
const onReadyRef = useLiveRef(onReady);
|
|
244
|
-
const adapterRef = useLiveRef(adapter);
|
|
245
|
-
const resetSignalSubject = useSubject();
|
|
246
|
-
const resetSignals = react.useCallback(() => {
|
|
247
|
-
persistanceRef.current.forEach(({ setValue }) => {
|
|
248
|
-
setValue(SIGNAL_RESET);
|
|
249
|
-
});
|
|
250
|
-
resetSignalSubject.current.next();
|
|
251
|
-
}, []);
|
|
252
|
-
const value = react.useMemo(() => ({ resetSignals }), [resetSignals]);
|
|
253
|
-
const isHydrated = useObserve(() => {
|
|
254
|
-
const items = persistanceRef.current;
|
|
255
|
-
const stream = items.length === 0 ? rxjs.of(true) : rxjs.zip(
|
|
256
|
-
...items.map(
|
|
257
|
-
({ hydrateValue }) => rxjs.from(hydrateValue({ adapter: adapterRef.current }))
|
|
258
|
-
)
|
|
259
|
-
).pipe(rxjs.map(() => true));
|
|
260
|
-
return stream.pipe(
|
|
261
|
-
rxjs.tap(() => {
|
|
262
|
-
if (onReadyRef.current != null)
|
|
263
|
-
onReadyRef.current();
|
|
264
|
-
}),
|
|
265
|
-
rxjs.catchError((error) => {
|
|
266
|
-
console.error("Unable to hydrate", error);
|
|
267
|
-
return rxjs.EMPTY;
|
|
268
|
-
})
|
|
269
|
-
);
|
|
270
|
-
}, []) ?? false;
|
|
271
|
-
useSubscribe(
|
|
272
|
-
() => !isHydrated ? rxjs.EMPTY : rxjs.merge(
|
|
273
|
-
...persistanceRef.current.map(
|
|
274
|
-
({ persistValue, $ }) => (
|
|
275
|
-
// @todo test the reset
|
|
276
|
-
rxjs.merge(
|
|
277
|
-
resetSignalSubject.current,
|
|
278
|
-
$.pipe(
|
|
279
|
-
rxjs.throttleTime(500, void 0, {
|
|
280
|
-
trailing: true,
|
|
281
|
-
leading: false
|
|
282
|
-
})
|
|
283
|
-
)
|
|
284
|
-
).pipe(rxjs.switchMap(() => rxjs.from(persistValue({ adapter }))))
|
|
285
|
-
)
|
|
286
|
-
)
|
|
287
|
-
),
|
|
288
|
-
[isHydrated, adapter]
|
|
289
|
-
);
|
|
290
|
-
return isHydrated ? /* @__PURE__ */ jsxRuntime.jsx(PersistSignalsContext.Provider, { value, children }) : null;
|
|
291
|
-
}
|
|
292
|
-
);
|
|
293
|
-
const getNormalizedPersistanceValue = (unknownValue) => {
|
|
294
|
-
if (unknownValue === null)
|
|
295
|
-
return void 0;
|
|
296
|
-
if (typeof unknownValue === "object" && "__key" in unknownValue && unknownValue.__key === "reactjrx_persistance") {
|
|
297
|
-
return unknownValue;
|
|
298
|
-
}
|
|
299
|
-
return void 0;
|
|
300
|
-
};
|
|
301
|
-
function withPersistance(_signal, { version = 0 } = {}) {
|
|
302
|
-
if (!_signal.options.key) {
|
|
303
|
-
console.error(
|
|
304
|
-
"You need to specify a key to use persistance with this signal"
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
const hydrateValue = async ({
|
|
308
|
-
adapter,
|
|
309
|
-
key = _signal.options.key
|
|
310
|
-
}) => {
|
|
311
|
-
if (!key)
|
|
312
|
-
return;
|
|
313
|
-
const value = await adapter.getItem(key);
|
|
314
|
-
const normalizedValue = getNormalizedPersistanceValue(value);
|
|
315
|
-
if (normalizedValue == null)
|
|
316
|
-
return;
|
|
317
|
-
if (normalizedValue.migrationVersion && version > normalizedValue.migrationVersion) {
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
_signal.setState(value.value);
|
|
321
|
-
};
|
|
322
|
-
const persistValue = async ({
|
|
323
|
-
adapter,
|
|
324
|
-
key = _signal.options.key
|
|
325
|
-
}) => {
|
|
326
|
-
if (!key)
|
|
327
|
-
return;
|
|
328
|
-
const state = _signal.getValue();
|
|
329
|
-
const value = {
|
|
330
|
-
value: state,
|
|
331
|
-
__key: "reactjrx_persistance",
|
|
332
|
-
migrationVersion: version
|
|
333
|
-
};
|
|
334
|
-
await adapter.setItem(key, value);
|
|
335
|
-
};
|
|
336
|
-
return [
|
|
337
|
-
{
|
|
338
|
-
hydrateValue,
|
|
339
|
-
persistValue,
|
|
340
|
-
setValue: _signal.setState,
|
|
341
|
-
$: _signal.subject,
|
|
342
|
-
options: _signal.options
|
|
343
|
-
},
|
|
344
|
-
_signal
|
|
345
|
-
];
|
|
346
|
-
}
|
|
347
200
|
const normalizeStore = (store) => {
|
|
348
201
|
if (!store || typeof store !== "object") {
|
|
349
202
|
return void 0;
|
|
@@ -379,6 +232,107 @@ const createLocalforageAdapter = (forage) => ({
|
|
|
379
232
|
await forage.setItem(key, JSON.stringify(value));
|
|
380
233
|
}
|
|
381
234
|
});
|
|
235
|
+
const createLocalStorageAdapter = (forage) => ({
|
|
236
|
+
getItem: async (key) => {
|
|
237
|
+
const serializedValue = forage.getItem(key);
|
|
238
|
+
if (!serializedValue)
|
|
239
|
+
return void 0;
|
|
240
|
+
return JSON.parse(serializedValue);
|
|
241
|
+
},
|
|
242
|
+
setItem: async (key, value) => {
|
|
243
|
+
forage.setItem(key, JSON.stringify(value));
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
const IDENTIFIER_PERSISTANCE_KEY = "__reactjrx";
|
|
247
|
+
const getNormalizedPersistanceValue = (unknownValue) => {
|
|
248
|
+
if (typeof unknownValue === "object" && unknownValue !== null && IDENTIFIER_PERSISTANCE_KEY in unknownValue && unknownValue[IDENTIFIER_PERSISTANCE_KEY] === IDENTIFIER_PERSISTANCE_KEY) {
|
|
249
|
+
return unknownValue;
|
|
250
|
+
}
|
|
251
|
+
return void 0;
|
|
252
|
+
};
|
|
253
|
+
const persistValue = async ({
|
|
254
|
+
adapter,
|
|
255
|
+
signal: signal2,
|
|
256
|
+
version
|
|
257
|
+
}) => {
|
|
258
|
+
const state = signal2.getValue();
|
|
259
|
+
const value = {
|
|
260
|
+
value: state,
|
|
261
|
+
[IDENTIFIER_PERSISTANCE_KEY]: IDENTIFIER_PERSISTANCE_KEY,
|
|
262
|
+
migrationVersion: version
|
|
263
|
+
};
|
|
264
|
+
await adapter.setItem(signal2.config.key, value);
|
|
265
|
+
};
|
|
266
|
+
const hydrateValueToSignal = ({
|
|
267
|
+
adapter,
|
|
268
|
+
version,
|
|
269
|
+
signal: signal2
|
|
270
|
+
}) => {
|
|
271
|
+
return rxjs.from(adapter.getItem(signal2.config.key)).pipe(
|
|
272
|
+
rxjs.switchMap((value) => {
|
|
273
|
+
const normalizedValue = getNormalizedPersistanceValue(value);
|
|
274
|
+
if (!normalizedValue)
|
|
275
|
+
return rxjs.of(value);
|
|
276
|
+
if (normalizedValue.migrationVersion !== void 0 && version > normalizedValue.migrationVersion) {
|
|
277
|
+
return rxjs.of(value);
|
|
278
|
+
}
|
|
279
|
+
signal2.setValue(value.value);
|
|
280
|
+
return rxjs.of(value);
|
|
281
|
+
})
|
|
282
|
+
);
|
|
283
|
+
};
|
|
284
|
+
const usePersistSignals = ({
|
|
285
|
+
entries = [],
|
|
286
|
+
onReady,
|
|
287
|
+
adapter = createLocalStorageAdapter(localStorage)
|
|
288
|
+
}) => {
|
|
289
|
+
const entriesRef = useLiveRef(entries);
|
|
290
|
+
const onReadyRef = useLiveRef(onReady);
|
|
291
|
+
const adapterRef = useLiveRef(adapter);
|
|
292
|
+
const isHydrated = useObserve(
|
|
293
|
+
() => {
|
|
294
|
+
const entries2 = entriesRef.current;
|
|
295
|
+
const stream = entries2.length === 0 ? rxjs.of(true) : rxjs.zip(
|
|
296
|
+
...entries2.map(
|
|
297
|
+
({ signal: signal2, version }) => hydrateValueToSignal({
|
|
298
|
+
adapter: adapterRef.current,
|
|
299
|
+
signal: signal2,
|
|
300
|
+
version
|
|
301
|
+
})
|
|
302
|
+
)
|
|
303
|
+
).pipe(rxjs.map(() => true));
|
|
304
|
+
return stream.pipe(
|
|
305
|
+
rxjs.tap(() => {
|
|
306
|
+
if (onReadyRef.current != null)
|
|
307
|
+
onReadyRef.current();
|
|
308
|
+
}),
|
|
309
|
+
rxjs.catchError((error) => {
|
|
310
|
+
console.error("Unable to hydrate", error);
|
|
311
|
+
return rxjs.EMPTY;
|
|
312
|
+
})
|
|
313
|
+
);
|
|
314
|
+
},
|
|
315
|
+
{ defaultValue: false },
|
|
316
|
+
[]
|
|
317
|
+
);
|
|
318
|
+
useSubscribe(() => {
|
|
319
|
+
return !isHydrated ? rxjs.EMPTY : rxjs.merge(
|
|
320
|
+
...entriesRef.current.map(
|
|
321
|
+
({ signal: signal2, version }) => signal2.subject.pipe(
|
|
322
|
+
rxjs.throttleTime(500, rxjs.asyncScheduler, {
|
|
323
|
+
trailing: true
|
|
324
|
+
}),
|
|
325
|
+
rxjs.switchMap(
|
|
326
|
+
() => rxjs.from(
|
|
327
|
+
persistValue({ adapter: adapterRef.current, signal: signal2, version })
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
)
|
|
331
|
+
)
|
|
332
|
+
);
|
|
333
|
+
}, [isHydrated, adapterRef]);
|
|
334
|
+
return { isHydrated };
|
|
335
|
+
};
|
|
382
336
|
const useUnmountObservable = () => {
|
|
383
337
|
const subject = useSubject({
|
|
384
338
|
onBeforeComplete: () => {
|
|
@@ -611,11 +565,8 @@ const ClientEffect = ({
|
|
|
611
565
|
return null;
|
|
612
566
|
};
|
|
613
567
|
const Provider = react.memo(
|
|
614
|
-
({
|
|
615
|
-
|
|
616
|
-
client
|
|
617
|
-
}) => {
|
|
618
|
-
const value = react.useMemo(() => ({ client }), [client]);
|
|
568
|
+
({ children, client }) => {
|
|
569
|
+
const value = react.useMemo(() => ({ client: client.client }), [client]);
|
|
619
570
|
return /* @__PURE__ */ jsxRuntime.jsxs(Context.Provider, { value, children: [
|
|
620
571
|
/* @__PURE__ */ jsxRuntime.jsx(ClientEffect, { client: value.client }),
|
|
621
572
|
children
|
|
@@ -1703,8 +1654,14 @@ const createClient = () => {
|
|
|
1703
1654
|
...refetchClient
|
|
1704
1655
|
};
|
|
1705
1656
|
};
|
|
1706
|
-
|
|
1707
|
-
|
|
1657
|
+
class QueryClient {
|
|
1658
|
+
constructor() {
|
|
1659
|
+
__publicField(this, "client");
|
|
1660
|
+
this.client = createClient();
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
exports.QueryClient = QueryClient;
|
|
1664
|
+
exports.QueryClientProvider = Provider;
|
|
1708
1665
|
exports.SIGNAL_RESET = SIGNAL_RESET;
|
|
1709
1666
|
exports.createClient = createClient;
|
|
1710
1667
|
exports.createLocalforageAdapter = createLocalforageAdapter;
|
|
@@ -1719,15 +1676,11 @@ exports.useBehaviorSubject = useBehaviorSubject;
|
|
|
1719
1676
|
exports.useLiveRef = useLiveRef;
|
|
1720
1677
|
exports.useObserve = useObserve;
|
|
1721
1678
|
exports.useObserveCallback = useObserveCallback;
|
|
1722
|
-
exports.
|
|
1679
|
+
exports.usePersistSignals = usePersistSignals;
|
|
1723
1680
|
exports.useQuery = useQuery;
|
|
1724
1681
|
exports.useQueryClient = useQueryClient;
|
|
1725
|
-
exports.useScopeSignals = useScopeSignals;
|
|
1726
|
-
exports.useSetSignal = useSetSignal;
|
|
1727
|
-
exports.useSignal = useSignal;
|
|
1728
1682
|
exports.useSignalValue = useSignalValue;
|
|
1729
1683
|
exports.useSubject = useSubject;
|
|
1730
1684
|
exports.useSubscribe = useSubscribe;
|
|
1731
1685
|
exports.useSubscribeEffect = useSubscribeEffect;
|
|
1732
1686
|
exports.useUnmountObservable = useUnmountObservable;
|
|
1733
|
-
exports.withPersistance = withPersistance;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,15 +5,11 @@ export * from "./lib/binding/trigger";
|
|
|
5
5
|
export * from "./lib/binding/useSubject";
|
|
6
6
|
export * from "./lib/binding/useBehaviorSubject";
|
|
7
7
|
export * from "./lib/state/signal";
|
|
8
|
-
export * from "./lib/state/useSignal";
|
|
9
|
-
export * from "./lib/state/useSetSignal";
|
|
10
8
|
export * from "./lib/state/useSignalValue";
|
|
11
|
-
export * from "./lib/state/useScopeSignals";
|
|
12
9
|
export * from "./lib/state/constants";
|
|
13
|
-
export * from "./lib/state/persistance/
|
|
14
|
-
export * from "./lib/state/persistance/
|
|
15
|
-
export * from "./lib/state/persistance/
|
|
16
|
-
export * from "./lib/state/persistance/createLocalforageAdapter";
|
|
10
|
+
export * from "./lib/state/persistance/adapters/createSharedStoreAdapter";
|
|
11
|
+
export * from "./lib/state/persistance/adapters/createLocalforageAdapter";
|
|
12
|
+
export * from "./lib/state/persistance/usePersistSignals";
|
|
17
13
|
export * from "./lib/utils/useUnmountObservable";
|
|
18
14
|
export * from "./lib/utils/retryBackoff";
|
|
19
15
|
export * from "./lib/utils/useLiveRef";
|
|
@@ -21,4 +17,4 @@ export * from "./lib/queries/react/useAsyncQuery";
|
|
|
21
17
|
export * from "./lib/queries/react/useQuery";
|
|
22
18
|
export * from "./lib/queries/react/useSubscribeEffect";
|
|
23
19
|
export * from "./lib/queries/client/createClient";
|
|
24
|
-
export { Provider as
|
|
20
|
+
export { Provider as QueryClientProvider, useQueryClient } from "./lib/queries/react/Provider";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => {
|
|
4
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
|
+
return value;
|
|
6
|
+
};
|
|
1
7
|
import { useRef, useMemo, useCallback, useSyncExternalStore, useEffect, createContext, memo, useContext } from "react";
|
|
2
|
-
import { distinctUntilChanged, tap, finalize, catchError, EMPTY, Subject, identity, BehaviorSubject, of, zip,
|
|
3
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { distinctUntilChanged, tap, finalize, catchError, EMPTY, Subject, identity, BehaviorSubject, of, zip, map, merge, throttleTime, asyncScheduler, switchMap, from, defer, iif, timer, throwError, scan, take, startWith, combineLatest, first, takeUntil, filter, concatMap as concatMap$1, mergeMap, fromEvent, skip, withLatestFrom, retry, shareReplay, endWith, delay, share, pairwise, NEVER, takeWhile } from "rxjs";
|
|
4
9
|
import { retryWhen, concatMap, tap as tap$1 } from "rxjs/operators";
|
|
10
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
5
11
|
const useLiveRef = (value) => {
|
|
6
12
|
const ref = useRef(value);
|
|
7
13
|
useMemo(() => {
|
|
@@ -161,12 +167,10 @@ const useBehaviorSubject = (state) => {
|
|
|
161
167
|
return subject;
|
|
162
168
|
};
|
|
163
169
|
const SIGNAL_RESET = Symbol("SIGNAL_RESET");
|
|
164
|
-
function signal(
|
|
165
|
-
const { default: defaultValue2 } =
|
|
170
|
+
function signal(config) {
|
|
171
|
+
const { default: defaultValue2 } = config ?? {};
|
|
166
172
|
const subject = new BehaviorSubject(defaultValue2);
|
|
167
173
|
const setValue = (arg) => {
|
|
168
|
-
if (arg === subject.getValue())
|
|
169
|
-
return;
|
|
170
174
|
if (typeof arg === "function") {
|
|
171
175
|
const change = arg(subject.getValue());
|
|
172
176
|
if (change === subject.getValue())
|
|
@@ -182,166 +186,15 @@ function signal(options) {
|
|
|
182
186
|
};
|
|
183
187
|
const getValue = () => subject.getValue();
|
|
184
188
|
return {
|
|
185
|
-
|
|
189
|
+
setValue,
|
|
186
190
|
getValue,
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* @important
|
|
190
|
-
* We return the original behavior subject for two reasons:
|
|
191
|
-
* - useObserve may return the default value directly instead of undefined
|
|
192
|
-
* - the scope exist for react binding, this observable is a direct access outside of it
|
|
193
|
-
*/
|
|
191
|
+
config,
|
|
194
192
|
subject
|
|
195
193
|
};
|
|
196
194
|
}
|
|
197
|
-
const useSetSignal = (signal2) => {
|
|
198
|
-
return signal2.setState;
|
|
199
|
-
};
|
|
200
195
|
const useSignalValue = (signal2, key) => {
|
|
201
196
|
return useObserve(signal2.subject, { defaultValue: signal2.getValue(), key });
|
|
202
197
|
};
|
|
203
|
-
const useSignal = (signal2) => {
|
|
204
|
-
return [useSignalValue(signal2), useSetSignal(signal2)];
|
|
205
|
-
};
|
|
206
|
-
const useScopeSignals = (signals) => {
|
|
207
|
-
const signalsRef = useLiveRef(signals);
|
|
208
|
-
useEffect(
|
|
209
|
-
() => () => {
|
|
210
|
-
signalsRef.current.forEach(({ setState }) => {
|
|
211
|
-
setState(SIGNAL_RESET);
|
|
212
|
-
});
|
|
213
|
-
},
|
|
214
|
-
[]
|
|
215
|
-
);
|
|
216
|
-
};
|
|
217
|
-
const createLocalStorageAdapter = (forage) => ({
|
|
218
|
-
getItem: async (key) => {
|
|
219
|
-
const serializedValue = forage.getItem(key);
|
|
220
|
-
if (!serializedValue)
|
|
221
|
-
return void 0;
|
|
222
|
-
return JSON.parse(serializedValue);
|
|
223
|
-
},
|
|
224
|
-
setItem: async (key, value) => {
|
|
225
|
-
forage.setItem(key, JSON.stringify(value));
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
const PersistSignalsContext = createContext({
|
|
229
|
-
resetSignals: () => {
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
const usePersistSignalsContext = () => useContext(PersistSignalsContext);
|
|
233
|
-
const PersistSignals = memo(
|
|
234
|
-
({
|
|
235
|
-
children,
|
|
236
|
-
signals = [],
|
|
237
|
-
onReady,
|
|
238
|
-
adapter = createLocalStorageAdapter(localStorage)
|
|
239
|
-
}) => {
|
|
240
|
-
const persistanceRef = useLiveRef(signals);
|
|
241
|
-
const onReadyRef = useLiveRef(onReady);
|
|
242
|
-
const adapterRef = useLiveRef(adapter);
|
|
243
|
-
const resetSignalSubject = useSubject();
|
|
244
|
-
const resetSignals = useCallback(() => {
|
|
245
|
-
persistanceRef.current.forEach(({ setValue }) => {
|
|
246
|
-
setValue(SIGNAL_RESET);
|
|
247
|
-
});
|
|
248
|
-
resetSignalSubject.current.next();
|
|
249
|
-
}, []);
|
|
250
|
-
const value = useMemo(() => ({ resetSignals }), [resetSignals]);
|
|
251
|
-
const isHydrated = useObserve(() => {
|
|
252
|
-
const items = persistanceRef.current;
|
|
253
|
-
const stream = items.length === 0 ? of(true) : zip(
|
|
254
|
-
...items.map(
|
|
255
|
-
({ hydrateValue }) => from(hydrateValue({ adapter: adapterRef.current }))
|
|
256
|
-
)
|
|
257
|
-
).pipe(map(() => true));
|
|
258
|
-
return stream.pipe(
|
|
259
|
-
tap(() => {
|
|
260
|
-
if (onReadyRef.current != null)
|
|
261
|
-
onReadyRef.current();
|
|
262
|
-
}),
|
|
263
|
-
catchError((error) => {
|
|
264
|
-
console.error("Unable to hydrate", error);
|
|
265
|
-
return EMPTY;
|
|
266
|
-
})
|
|
267
|
-
);
|
|
268
|
-
}, []) ?? false;
|
|
269
|
-
useSubscribe(
|
|
270
|
-
() => !isHydrated ? EMPTY : merge(
|
|
271
|
-
...persistanceRef.current.map(
|
|
272
|
-
({ persistValue, $ }) => (
|
|
273
|
-
// @todo test the reset
|
|
274
|
-
merge(
|
|
275
|
-
resetSignalSubject.current,
|
|
276
|
-
$.pipe(
|
|
277
|
-
throttleTime(500, void 0, {
|
|
278
|
-
trailing: true,
|
|
279
|
-
leading: false
|
|
280
|
-
})
|
|
281
|
-
)
|
|
282
|
-
).pipe(switchMap(() => from(persistValue({ adapter }))))
|
|
283
|
-
)
|
|
284
|
-
)
|
|
285
|
-
),
|
|
286
|
-
[isHydrated, adapter]
|
|
287
|
-
);
|
|
288
|
-
return isHydrated ? /* @__PURE__ */ jsx(PersistSignalsContext.Provider, { value, children }) : null;
|
|
289
|
-
}
|
|
290
|
-
);
|
|
291
|
-
const getNormalizedPersistanceValue = (unknownValue) => {
|
|
292
|
-
if (unknownValue === null)
|
|
293
|
-
return void 0;
|
|
294
|
-
if (typeof unknownValue === "object" && "__key" in unknownValue && unknownValue.__key === "reactjrx_persistance") {
|
|
295
|
-
return unknownValue;
|
|
296
|
-
}
|
|
297
|
-
return void 0;
|
|
298
|
-
};
|
|
299
|
-
function withPersistance(_signal, { version = 0 } = {}) {
|
|
300
|
-
if (!_signal.options.key) {
|
|
301
|
-
console.error(
|
|
302
|
-
"You need to specify a key to use persistance with this signal"
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
const hydrateValue = async ({
|
|
306
|
-
adapter,
|
|
307
|
-
key = _signal.options.key
|
|
308
|
-
}) => {
|
|
309
|
-
if (!key)
|
|
310
|
-
return;
|
|
311
|
-
const value = await adapter.getItem(key);
|
|
312
|
-
const normalizedValue = getNormalizedPersistanceValue(value);
|
|
313
|
-
if (normalizedValue == null)
|
|
314
|
-
return;
|
|
315
|
-
if (normalizedValue.migrationVersion && version > normalizedValue.migrationVersion) {
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
_signal.setState(value.value);
|
|
319
|
-
};
|
|
320
|
-
const persistValue = async ({
|
|
321
|
-
adapter,
|
|
322
|
-
key = _signal.options.key
|
|
323
|
-
}) => {
|
|
324
|
-
if (!key)
|
|
325
|
-
return;
|
|
326
|
-
const state = _signal.getValue();
|
|
327
|
-
const value = {
|
|
328
|
-
value: state,
|
|
329
|
-
__key: "reactjrx_persistance",
|
|
330
|
-
migrationVersion: version
|
|
331
|
-
};
|
|
332
|
-
await adapter.setItem(key, value);
|
|
333
|
-
};
|
|
334
|
-
return [
|
|
335
|
-
{
|
|
336
|
-
hydrateValue,
|
|
337
|
-
persistValue,
|
|
338
|
-
setValue: _signal.setState,
|
|
339
|
-
$: _signal.subject,
|
|
340
|
-
options: _signal.options
|
|
341
|
-
},
|
|
342
|
-
_signal
|
|
343
|
-
];
|
|
344
|
-
}
|
|
345
198
|
const normalizeStore = (store) => {
|
|
346
199
|
if (!store || typeof store !== "object") {
|
|
347
200
|
return void 0;
|
|
@@ -377,6 +230,107 @@ const createLocalforageAdapter = (forage) => ({
|
|
|
377
230
|
await forage.setItem(key, JSON.stringify(value));
|
|
378
231
|
}
|
|
379
232
|
});
|
|
233
|
+
const createLocalStorageAdapter = (forage) => ({
|
|
234
|
+
getItem: async (key) => {
|
|
235
|
+
const serializedValue = forage.getItem(key);
|
|
236
|
+
if (!serializedValue)
|
|
237
|
+
return void 0;
|
|
238
|
+
return JSON.parse(serializedValue);
|
|
239
|
+
},
|
|
240
|
+
setItem: async (key, value) => {
|
|
241
|
+
forage.setItem(key, JSON.stringify(value));
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
const IDENTIFIER_PERSISTANCE_KEY = "__reactjrx";
|
|
245
|
+
const getNormalizedPersistanceValue = (unknownValue) => {
|
|
246
|
+
if (typeof unknownValue === "object" && unknownValue !== null && IDENTIFIER_PERSISTANCE_KEY in unknownValue && unknownValue[IDENTIFIER_PERSISTANCE_KEY] === IDENTIFIER_PERSISTANCE_KEY) {
|
|
247
|
+
return unknownValue;
|
|
248
|
+
}
|
|
249
|
+
return void 0;
|
|
250
|
+
};
|
|
251
|
+
const persistValue = async ({
|
|
252
|
+
adapter,
|
|
253
|
+
signal: signal2,
|
|
254
|
+
version
|
|
255
|
+
}) => {
|
|
256
|
+
const state = signal2.getValue();
|
|
257
|
+
const value = {
|
|
258
|
+
value: state,
|
|
259
|
+
[IDENTIFIER_PERSISTANCE_KEY]: IDENTIFIER_PERSISTANCE_KEY,
|
|
260
|
+
migrationVersion: version
|
|
261
|
+
};
|
|
262
|
+
await adapter.setItem(signal2.config.key, value);
|
|
263
|
+
};
|
|
264
|
+
const hydrateValueToSignal = ({
|
|
265
|
+
adapter,
|
|
266
|
+
version,
|
|
267
|
+
signal: signal2
|
|
268
|
+
}) => {
|
|
269
|
+
return from(adapter.getItem(signal2.config.key)).pipe(
|
|
270
|
+
switchMap((value) => {
|
|
271
|
+
const normalizedValue = getNormalizedPersistanceValue(value);
|
|
272
|
+
if (!normalizedValue)
|
|
273
|
+
return of(value);
|
|
274
|
+
if (normalizedValue.migrationVersion !== void 0 && version > normalizedValue.migrationVersion) {
|
|
275
|
+
return of(value);
|
|
276
|
+
}
|
|
277
|
+
signal2.setValue(value.value);
|
|
278
|
+
return of(value);
|
|
279
|
+
})
|
|
280
|
+
);
|
|
281
|
+
};
|
|
282
|
+
const usePersistSignals = ({
|
|
283
|
+
entries = [],
|
|
284
|
+
onReady,
|
|
285
|
+
adapter = createLocalStorageAdapter(localStorage)
|
|
286
|
+
}) => {
|
|
287
|
+
const entriesRef = useLiveRef(entries);
|
|
288
|
+
const onReadyRef = useLiveRef(onReady);
|
|
289
|
+
const adapterRef = useLiveRef(adapter);
|
|
290
|
+
const isHydrated = useObserve(
|
|
291
|
+
() => {
|
|
292
|
+
const entries2 = entriesRef.current;
|
|
293
|
+
const stream = entries2.length === 0 ? of(true) : zip(
|
|
294
|
+
...entries2.map(
|
|
295
|
+
({ signal: signal2, version }) => hydrateValueToSignal({
|
|
296
|
+
adapter: adapterRef.current,
|
|
297
|
+
signal: signal2,
|
|
298
|
+
version
|
|
299
|
+
})
|
|
300
|
+
)
|
|
301
|
+
).pipe(map(() => true));
|
|
302
|
+
return stream.pipe(
|
|
303
|
+
tap(() => {
|
|
304
|
+
if (onReadyRef.current != null)
|
|
305
|
+
onReadyRef.current();
|
|
306
|
+
}),
|
|
307
|
+
catchError((error) => {
|
|
308
|
+
console.error("Unable to hydrate", error);
|
|
309
|
+
return EMPTY;
|
|
310
|
+
})
|
|
311
|
+
);
|
|
312
|
+
},
|
|
313
|
+
{ defaultValue: false },
|
|
314
|
+
[]
|
|
315
|
+
);
|
|
316
|
+
useSubscribe(() => {
|
|
317
|
+
return !isHydrated ? EMPTY : merge(
|
|
318
|
+
...entriesRef.current.map(
|
|
319
|
+
({ signal: signal2, version }) => signal2.subject.pipe(
|
|
320
|
+
throttleTime(500, asyncScheduler, {
|
|
321
|
+
trailing: true
|
|
322
|
+
}),
|
|
323
|
+
switchMap(
|
|
324
|
+
() => from(
|
|
325
|
+
persistValue({ adapter: adapterRef.current, signal: signal2, version })
|
|
326
|
+
)
|
|
327
|
+
)
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
);
|
|
331
|
+
}, [isHydrated, adapterRef]);
|
|
332
|
+
return { isHydrated };
|
|
333
|
+
};
|
|
380
334
|
const useUnmountObservable = () => {
|
|
381
335
|
const subject = useSubject({
|
|
382
336
|
onBeforeComplete: () => {
|
|
@@ -609,11 +563,8 @@ const ClientEffect = ({
|
|
|
609
563
|
return null;
|
|
610
564
|
};
|
|
611
565
|
const Provider = memo(
|
|
612
|
-
({
|
|
613
|
-
|
|
614
|
-
client
|
|
615
|
-
}) => {
|
|
616
|
-
const value = useMemo(() => ({ client }), [client]);
|
|
566
|
+
({ children, client }) => {
|
|
567
|
+
const value = useMemo(() => ({ client: client.client }), [client]);
|
|
617
568
|
return /* @__PURE__ */ jsxs(Context.Provider, { value, children: [
|
|
618
569
|
/* @__PURE__ */ jsx(ClientEffect, { client: value.client }),
|
|
619
570
|
children
|
|
@@ -1701,9 +1652,15 @@ const createClient = () => {
|
|
|
1701
1652
|
...refetchClient
|
|
1702
1653
|
};
|
|
1703
1654
|
};
|
|
1655
|
+
class QueryClient {
|
|
1656
|
+
constructor() {
|
|
1657
|
+
__publicField(this, "client");
|
|
1658
|
+
this.client = createClient();
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1704
1661
|
export {
|
|
1705
|
-
|
|
1706
|
-
Provider as
|
|
1662
|
+
QueryClient,
|
|
1663
|
+
Provider as QueryClientProvider,
|
|
1707
1664
|
SIGNAL_RESET,
|
|
1708
1665
|
createClient,
|
|
1709
1666
|
createLocalforageAdapter,
|
|
@@ -1718,16 +1675,12 @@ export {
|
|
|
1718
1675
|
useLiveRef,
|
|
1719
1676
|
useObserve,
|
|
1720
1677
|
useObserveCallback,
|
|
1721
|
-
|
|
1678
|
+
usePersistSignals,
|
|
1722
1679
|
useQuery,
|
|
1723
1680
|
useQueryClient,
|
|
1724
|
-
useScopeSignals,
|
|
1725
|
-
useSetSignal,
|
|
1726
|
-
useSignal,
|
|
1727
1681
|
useSignalValue,
|
|
1728
1682
|
useSubject,
|
|
1729
1683
|
useSubscribe,
|
|
1730
1684
|
useSubscribeEffect,
|
|
1731
|
-
useUnmountObservable
|
|
1732
|
-
withPersistance
|
|
1685
|
+
useUnmountObservable
|
|
1733
1686
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
|
-
import { type createClient } from "../client/createClient";
|
|
2
|
+
import { type QueryClient, type createClient } from "../client/createClient";
|
|
3
3
|
export declare const Context: import("react").Context<{
|
|
4
4
|
client: ReturnType<typeof createClient>;
|
|
5
5
|
}>;
|
|
6
6
|
export declare const Provider: import("react").MemoExoticComponent<({ children, client }: {
|
|
7
7
|
children: ReactNode;
|
|
8
|
-
client:
|
|
8
|
+
client: QueryClient;
|
|
9
9
|
}) => import("react/jsx-runtime").JSX.Element>;
|
|
10
10
|
export declare const useQueryClient: () => {
|
|
11
11
|
pipeQueryResult: <R extends Partial<import("../client/types").QueryResult<T>>, T>({ options$ }: {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const IDENTIFIER_PERSISTANCE_KEY = "__reactjrx";
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import type { IDENTIFIER_PERSISTANCE_KEY } from "./constants";
|
|
1
2
|
export interface Adapter {
|
|
2
|
-
getItem: (key: string) => Promise<unknown
|
|
3
|
-
setItem: (key: string, value: any) => Promise<unknown
|
|
3
|
+
getItem: (key: string) => Promise<unknown>;
|
|
4
|
+
setItem: (key: string, value: any) => Promise<unknown>;
|
|
4
5
|
}
|
|
5
6
|
export interface PersistanceEntry {
|
|
6
7
|
value: unknown;
|
|
7
8
|
migrationVersion?: number;
|
|
8
|
-
|
|
9
|
+
[IDENTIFIER_PERSISTANCE_KEY]: typeof IDENTIFIER_PERSISTANCE_KEY;
|
|
9
10
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Adapter } from "./types";
|
|
2
|
+
import type { Signal } from "../signal";
|
|
3
|
+
export declare const usePersistSignals: ({ entries, onReady, adapter }: {
|
|
4
|
+
entries?: {
|
|
5
|
+
version: number;
|
|
6
|
+
signal: Signal<any, any, string>;
|
|
7
|
+
}[] | undefined;
|
|
8
|
+
onReady?: (() => void) | undefined;
|
|
9
|
+
adapter?: Adapter | undefined;
|
|
10
|
+
}) => {
|
|
11
|
+
isHydrated: boolean;
|
|
12
|
+
};
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import type { Observable } from "rxjs";
|
|
2
2
|
import { SIGNAL_RESET } from "./constants";
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
} & (R extends undefined ? {
|
|
6
|
-
default?: R;
|
|
3
|
+
type WithOptionalDefault<V> = V extends undefined ? {
|
|
4
|
+
default?: V;
|
|
7
5
|
} : {
|
|
8
|
-
default:
|
|
9
|
-
}
|
|
10
|
-
type
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
default: V;
|
|
7
|
+
};
|
|
8
|
+
type WithOptionalKey<V> = V extends undefined ? {
|
|
9
|
+
key?: V;
|
|
10
|
+
} : {
|
|
11
|
+
key: V;
|
|
12
|
+
};
|
|
13
|
+
type Config<R = undefined, K = undefined> = WithOptionalKey<K> & WithOptionalDefault<R>;
|
|
14
|
+
type setValue<S> = (stateOrUpdater: typeof SIGNAL_RESET | S | ((prev: S) => S)) => void;
|
|
15
|
+
export interface Signal<S = undefined, R = undefined, K = undefined> {
|
|
16
|
+
setValue: setValue<S>;
|
|
13
17
|
getValue: () => R;
|
|
14
|
-
|
|
18
|
+
config: Config<S, K>;
|
|
15
19
|
subject: Observable<S>;
|
|
16
20
|
}
|
|
17
|
-
export declare function signal<T = undefined>(
|
|
21
|
+
export declare function signal<T = undefined, K = undefined>(config: Config<T, K>): Signal<T, T, K>;
|
|
18
22
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { type Signal } from "./signal";
|
|
2
|
-
export declare const useSignalValue: <S>(signal: Signal<S, S>, key?: string) => S;
|
|
2
|
+
export declare const useSignalValue: <S, K>(signal: Signal<S, S, K>, key?: string) => S;
|
package/package.json
CHANGED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { type ReactNode } from "react";
|
|
2
|
-
import type { WithPersistanceReturn } from "./withPersistance";
|
|
3
|
-
import { type Adapter } from "./types";
|
|
4
|
-
export declare const usePersistSignalsContext: () => {
|
|
5
|
-
resetSignals: () => void;
|
|
6
|
-
};
|
|
7
|
-
export declare const PersistSignals: import("react").MemoExoticComponent<({ children, signals, onReady, adapter }: {
|
|
8
|
-
children: ReactNode;
|
|
9
|
-
signals?: WithPersistanceReturn<any>[] | undefined;
|
|
10
|
-
onReady?: (() => void) | undefined;
|
|
11
|
-
adapter?: Adapter | undefined;
|
|
12
|
-
}) => import("react/jsx-runtime").JSX.Element | null>;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Signal } from "../signal";
|
|
2
|
-
import { type Adapter } from "./types";
|
|
3
|
-
export interface WithPersistanceReturn<T> {
|
|
4
|
-
hydrateValue: (params: {
|
|
5
|
-
adapter: Adapter;
|
|
6
|
-
}) => Promise<void>;
|
|
7
|
-
persistValue: (params: {
|
|
8
|
-
adapter: Adapter;
|
|
9
|
-
}) => Promise<void>;
|
|
10
|
-
setValue: Signal<T, T>["setState"];
|
|
11
|
-
$: Signal<T, T>["subject"];
|
|
12
|
-
options: {
|
|
13
|
-
key?: string;
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
export declare function withPersistance<T>(_signal: Signal<T, T>, { version }?: {
|
|
17
|
-
version?: number;
|
|
18
|
-
}): [WithPersistanceReturn<T>, Signal<T, T>];
|
|
File without changes
|
|
File without changes
|