reactjrx 4.0.9 → 5.0.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.
@@ -7,6 +7,15 @@ type SwitchVariables<TVariables> = {
7
7
  variables: TVariables;
8
8
  abort: AbortSignal;
9
9
  };
10
+ /**
11
+ * Each member of TanStack's result, with `variables` holding the variables
12
+ * given to `mutate` instead of the `{ variables, abort }` the hook runs with.
13
+ */
14
+ type WithCallerVariables<TResult, TVariables> = TResult extends {
15
+ variables: infer TResultVariables;
16
+ } ? Omit<TResult, "variables"> & {
17
+ variables: TResultVariables extends SwitchVariables<TVariables> ? TVariables : undefined;
18
+ } : never;
10
19
  /**
11
20
  * Runs a mutation, and cancels the call still running when a new one starts.
12
21
  * A cancelled call fails with `SwitchMutationCancelError` and is not retried.
@@ -14,12 +23,11 @@ type SwitchVariables<TVariables> = {
14
23
  * ends.
15
24
  *
16
25
  * The callbacks, the client's defaults included, receive the variables given
17
- * to `mutate`. A `MutationCache`, `result.variables` and `useMutationState`
18
- * see the `{ variables, abort }` the hook runs the mutation with.
26
+ * to `mutate`, and `result.variables` holds them. A `MutationCache` and
27
+ * `useMutationState` see the `{ variables, abort }` the hook runs the
28
+ * mutation with.
19
29
  */
20
- export declare function useSwitchMutation$<TData = unknown, TError = DefaultError, TVariables = void, TOnMutateResult = unknown>({ mutationFn, ...options }: UseMutation$Options<TData | null, TError, TVariables, TOnMutateResult>, queryClient?: QueryClient): {
21
- mutate: (variables: TVariables) => void;
22
- mutateAsync: (variables: TVariables) => Promise<TData | null>;
30
+ export declare function useSwitchMutation$<TData = unknown, TError = DefaultError, TVariables = void, TOnMutateResult = unknown>({ mutationFn, ...options }: UseMutation$Options<TData | null, TError, TVariables, TOnMutateResult>, queryClient?: QueryClient): WithCallerVariables<{
23
31
  state$: import('rxjs').BehaviorSubject<Pick<import('@tanstack/react-query').UseMutationResult<TData | null, TError, SwitchVariables<TVariables>, TOnMutateResult>, "status" | "isPending" | "isError" | "isSuccess" | "isIdle">>;
24
32
  data: undefined;
25
33
  variables: undefined;
@@ -36,8 +44,6 @@ export declare function useSwitchMutation$<TData = unknown, TError = DefaultErro
36
44
  isPaused: boolean;
37
45
  submittedAt: number;
38
46
  } | {
39
- mutate: (variables: TVariables) => void;
40
- mutateAsync: (variables: TVariables) => Promise<TData | null>;
41
47
  state$: import('rxjs').BehaviorSubject<Pick<import('@tanstack/react-query').UseMutationResult<TData | null, TError, SwitchVariables<TVariables>, TOnMutateResult>, "status" | "isPending" | "isError" | "isSuccess" | "isIdle">>;
42
48
  data: undefined;
43
49
  variables: SwitchVariables<TVariables>;
@@ -54,8 +60,6 @@ export declare function useSwitchMutation$<TData = unknown, TError = DefaultErro
54
60
  isPaused: boolean;
55
61
  submittedAt: number;
56
62
  } | {
57
- mutate: (variables: TVariables) => void;
58
- mutateAsync: (variables: TVariables) => Promise<TData | null>;
59
63
  state$: import('rxjs').BehaviorSubject<Pick<import('@tanstack/react-query').UseMutationResult<TData | null, TError, SwitchVariables<TVariables>, TOnMutateResult>, "status" | "isPending" | "isError" | "isSuccess" | "isIdle">>;
60
64
  data: undefined;
61
65
  error: TError;
@@ -72,8 +76,6 @@ export declare function useSwitchMutation$<TData = unknown, TError = DefaultErro
72
76
  isPaused: boolean;
73
77
  submittedAt: number;
74
78
  } | {
75
- mutate: (variables: TVariables) => void;
76
- mutateAsync: (variables: TVariables) => Promise<TData | null>;
77
79
  state$: import('rxjs').BehaviorSubject<Pick<import('@tanstack/react-query').UseMutationResult<TData | null, TError, SwitchVariables<TVariables>, TOnMutateResult>, "status" | "isPending" | "isError" | "isSuccess" | "isIdle">>;
78
80
  data: TData | null;
79
81
  error: null;
@@ -89,5 +91,8 @@ export declare function useSwitchMutation$<TData = unknown, TError = DefaultErro
89
91
  failureReason: TError | null;
90
92
  isPaused: boolean;
91
93
  submittedAt: number;
94
+ }, TVariables> & {
95
+ mutate: (variables: TVariables) => void;
96
+ mutateAsync: (variables: TVariables) => Promise<TData | null>;
92
97
  };
93
98
  export {};
@@ -53,6 +53,5 @@ export declare function signal<K extends string>(config: {
53
53
  }): Signal<undefined, K>;
54
54
  export declare function virtualSignal<T>(config: {
55
55
  default: T;
56
- key?: string;
57
56
  }): VirtualSignal<T>;
58
57
  export {};
@@ -1,13 +1,9 @@
1
- import { BehaviorSubject } from 'rxjs';
2
1
  import { Signal, VirtualSignal } from './Signal';
3
2
  export declare class SignalContext {
4
3
  /**
5
- * items only get added as they are created. The only time we should cleanup
6
- * are on context destroy. This is to ensure later re-use of virtual signals
7
- * return the same persisted state.
4
+ * Signals are only added, as they are created, so a virtual signal used
5
+ * again in the same context gets the same signal and its state.
8
6
  */
9
- signals: BehaviorSubject<Map<VirtualSignal<unknown>, Signal<any, undefined>>>;
10
- isDestroyed: boolean;
7
+ private readonly signals;
11
8
  getOrCreateSignal<T>(virtualSignal: VirtualSignal<T>): Signal<T>;
12
- destroy(): void;
13
9
  }
@@ -1,6 +1,7 @@
1
+ /**
2
+ * Where the persistence reads and writes the values of its signals.
3
+ */
1
4
  export interface Adapter {
2
5
  getItem: (key: string) => Promise<unknown>;
3
6
  setItem: (key: string, value: any) => Promise<unknown>;
4
- removeItem: (key: string) => Promise<unknown>;
5
- clear: () => Promise<unknown>;
6
7
  }
@@ -9,6 +9,4 @@ export declare class MockAdapter implements Adapter {
9
9
  });
10
10
  getItem(key: string): Promise<any>;
11
11
  setItem(_: string, __: any): Promise<unknown>;
12
- removeItem(_: string): Promise<unknown>;
13
- clear(): Promise<unknown>;
14
12
  }
@@ -1,5 +1 @@
1
1
  export declare const IDENTIFIER_PERSISTENCE_KEY = "__reactjrx";
2
- /**
3
- * What hydration emits when the adapter holds nothing usable for a signal.
4
- */
5
- export declare const NOTHING_STORED: unique symbol;
@@ -1,20 +1,28 @@
1
- import { Observable } from 'rxjs';
2
1
  import { Adapter } from './adapters/Adapter';
3
2
  import { SignalPersistenceConfig } from './types';
4
3
  export declare const persistValue: ({ adapter, config, }: {
5
4
  adapter: Adapter;
6
5
  config: SignalPersistenceConfig<any>;
7
- }) => Observable<unknown>;
6
+ }) => import('rxjs').Observable<unknown>;
8
7
  /**
9
- * Emits the value the signal was hydrated with, or `NOTHING_STORED` when
10
- * nothing usable is stored.
8
+ * What the adapter holds for an entry, as the signal's value:
9
+ * - `missing`: nothing usable, or a value of an older version that the entry
10
+ * has no `hydrate` to migrate;
11
+ * - `unreadable`: a value that `hydrate` threw on;
12
+ * - `migrated`: a value of an older version, migrated by `hydrate`, which the
13
+ * adapter does not hold yet;
14
+ * - `current`: a value of the entry's version or newer, through `hydrate`
15
+ * when the entry has one.
11
16
  */
12
- export declare function hydrateValueToSignal({ adapter, config, resetToDefault, }: {
13
- adapter: Adapter;
14
- config: SignalPersistenceConfig<any>;
15
- /**
16
- * When nothing usable is stored, reset the signal to its default instead of
17
- * leaving its current value in place.
18
- */
19
- resetToDefault?: boolean;
20
- }): Observable<unknown>;
17
+ export type StoredState = {
18
+ type: "missing";
19
+ } | {
20
+ type: "unreadable";
21
+ } | {
22
+ type: "migrated";
23
+ value: unknown;
24
+ } | {
25
+ type: "current";
26
+ value: unknown;
27
+ };
28
+ export declare const readStoredState: (stored: unknown, { hydrate, signal, version }: SignalPersistenceConfig<any>) => StoredState;
@@ -13,9 +13,9 @@ type Entry = SignalPersistenceConfig<AnySignal>;
13
13
  * - a removed signal stops being persisted, after its pending value is saved.
14
14
  *
15
15
  * Emits `{ type: "hydrated" }` once, the first time every entry added so far
16
- * has been hydrated (right away for an empty list). An entry that fails to
17
- * hydrate is logged and never persisted, and holds back that emission until
18
- * it is removed.
16
+ * has been hydrated (right away for an empty list). An entry whose adapter
17
+ * fails to read it is logged and never persisted, and holds back that
18
+ * emission until it is removed.
19
19
  */
20
20
  export declare function persistSignals({ entries$, onHydrated, adapter, resetToDefault, }: {
21
21
  entries$: Observable<Entry[]>;
@@ -15,11 +15,18 @@ export interface SignalPersistenceConfig<S extends Signal<any, string>> {
15
15
  version: number;
16
16
  signal: S;
17
17
  /**
18
- * Called with the stored value when the signal is hydrated from it. The
19
- * value is `undefined` when the signal was saved holding `undefined`.
18
+ * Turns a stored value into the signal's value, given the `version` it was
19
+ * stored with. It also runs for a value stored with an older version, to
20
+ * migrate it: the result is then saved with this entry's version. Without
21
+ * `hydrate`, a value stored with an older version is discarded.
22
+ *
23
+ * The value is `unknown`, since the storage can hold any shape, and it is
24
+ * `undefined` when the signal was saved holding `undefined`. If `hydrate`
25
+ * throws, the error is logged and the entry hydrates as if nothing usable
26
+ * were stored, but the storage keeps the value until the signal changes.
20
27
  */
21
28
  hydrate?: (params: {
22
29
  version: number;
23
- value: SignalValue<S>;
30
+ value: unknown;
24
31
  }) => SignalValue<S>;
25
32
  }
@@ -1,9 +1,7 @@
1
- import { VirtualSignal } from '../Signal';
2
- import { SignalContext } from '../SignalContext';
3
- export type SignalContextType = SignalContext;
4
- export declare const SignalReactContext: import('react').Context<SignalContext>;
5
- export declare const SignalContextProvider: import('react').MemoExoticComponent<({ children }: {
1
+ /**
2
+ * Holds the signals of the virtual signals used under it, for as long as it
3
+ * is mounted. They never complete.
4
+ */
5
+ export declare const SignalContextProvider: import('react').MemoExoticComponent<({ children, }: {
6
6
  children: React.ReactNode;
7
7
  }) => import('react').JSX.Element>;
8
- export declare const useSignalContext: () => SignalContext;
9
- export declare const useMakeOrRetrieveSignal: (virtualSignal?: VirtualSignal<unknown>) => import('../Signal').Signal<unknown, undefined> | undefined;
@@ -0,0 +1,2 @@
1
+ import { SignalContext } from '../SignalContext';
2
+ export declare const SignalReactContext: import('react').Context<SignalContext | undefined>;
@@ -23,13 +23,14 @@ export declare function usePersistSignals({ entries, onHydrated, adapter, }: {
23
23
  /**
24
24
  * Passing a new adapter reference starts over: pending values are saved to
25
25
  * the previous adapter, then every entry takes the value stored in the new
26
- * one. When nothing is stored, or only an older version, the entry goes
27
- * back to its default once the hook has had two different adapters, so it
28
- * never carries another adapter's value over (another profile's, for
29
- * example). Before that, including when the same adapter comes back after
30
- * a gap without adapter, it keeps its current value. Adapters are compared
31
- * by reference: a new object for the same storage counts as a different
32
- * adapter. Use a stable reference to avoid infinite loop.
26
+ * one. When nothing is stored, or only an older version that the entry has
27
+ * no `hydrate` for, the entry goes back to its default once the hook has
28
+ * had two different adapters, so it never carries another adapter's value
29
+ * over (another profile's, for example). Before that, including when the
30
+ * same adapter comes back after a gap without adapter, it keeps its current
31
+ * value. Adapters are compared by reference: a new object for the same
32
+ * storage counts as a different adapter. Use a stable reference to avoid
33
+ * infinite loop.
33
34
  */
34
35
  adapter?: Adapter;
35
36
  }): {
@@ -1,2 +1,6 @@
1
1
  import { Signal, VirtualSignal } from '../Signal';
2
+ /**
3
+ * The signal itself, or the signal that the SignalContextProvider above holds
4
+ * for a virtual signal. Throws for a virtual signal outside a provider.
5
+ */
2
6
  export declare function useSignalReference<T>(signal: Signal<T> | VirtualSignal<T>): Signal<T>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reactjrx",
3
3
  "private": false,
4
- "version": "4.0.9",
4
+ "version": "5.0.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"