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 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(options) {
167
- const { default: defaultValue2 } = options ?? {};
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
- setState: setValue,
191
+ setValue,
188
192
  getValue,
189
- options,
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
- children,
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
- exports.PersistSignals = PersistSignals;
1707
- exports.ReactjrxQueryProvider = Provider;
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.usePersistSignalsContext = usePersistSignalsContext;
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/PersistSignals";
14
- export * from "./lib/state/persistance/withPersistance";
15
- export * from "./lib/state/persistance/createSharedStoreAdapter";
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 ReactjrxQueryProvider, useQueryClient } from "./lib/queries/react/Provider";
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, from, map, merge, throttleTime, switchMap, 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";
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(options) {
165
- const { default: defaultValue2 } = options ?? {};
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
- setState: setValue,
189
+ setValue,
186
190
  getValue,
187
- options,
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
- children,
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
- PersistSignals,
1706
- Provider as ReactjrxQueryProvider,
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
- usePersistSignalsContext,
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
  };
@@ -68,3 +68,7 @@ export declare const createClient: () => {
68
68
  start: () => () => void;
69
69
  };
70
70
  };
71
+ export declare class QueryClient {
72
+ client: ReturnType<typeof createClient>;
73
+ constructor();
74
+ }
@@ -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: ReturnType<typeof createClient>;
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$ }: {
@@ -1,4 +1,4 @@
1
- import { type Adapter } from "./types";
1
+ import { type Adapter } from "../types";
2
2
  /**
3
3
  * Create an adapter which use one unique store entry to store all
4
4
  * state. When using many signals it can help with maintenance to keep things
@@ -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> | unknown;
3
- setItem: (key: string, value: any) => Promise<unknown> | 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
- __key: "reactjrx_persistance";
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 Option<R = undefined> = {
4
- key?: string;
5
- } & (R extends undefined ? {
6
- default?: R;
3
+ type WithOptionalDefault<V> = V extends undefined ? {
4
+ default?: V;
7
5
  } : {
8
- default: R;
9
- });
10
- type SetState<S> = (stateOrUpdater: typeof SIGNAL_RESET | S | ((prev: S) => S)) => void;
11
- export interface Signal<S, R> {
12
- setState: SetState<S>;
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
- options: Option<S>;
18
+ config: Config<S, K>;
15
19
  subject: Observable<S>;
16
20
  }
17
- export declare function signal<T = undefined>(options: Option<T>): Signal<T, T>;
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,7 +1,7 @@
1
1
  {
2
2
  "name": "reactjrx",
3
3
  "private": false,
4
- "version": "1.46.0",
4
+ "version": "1.48.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
@@ -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>];
@@ -1,5 +0,0 @@
1
- import { type Signal } from "./signal";
2
- /**
3
- * Will reset signals when the scope is unmounted
4
- */
5
- export declare const useScopeSignals: (signals: Array<Signal<any, any>>) => void;
@@ -1,2 +0,0 @@
1
- import { type Signal } from "./signal";
2
- export declare const useSetSignal: <S, R>(signal: Signal<S, R>) => (stateOrUpdater: typeof import("./constants").SIGNAL_RESET | S | ((prev: S) => S)) => void;
@@ -1,2 +0,0 @@
1
- import { type Signal } from "./signal";
2
- export declare const useSignal: <S>(signal: Signal<S, S>) => readonly [S, (stateOrUpdater: typeof import("./constants").SIGNAL_RESET | S | ((prev: S) => S)) => void];