@effect/atom-solid 4.0.0-beta.7 → 4.0.0-beta.71
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/Hooks.d.ts +153 -24
- package/dist/Hooks.d.ts.map +1 -1
- package/dist/Hooks.js +193 -24
- package/dist/Hooks.js.map +1 -1
- package/dist/RegistryContext.d.ts +61 -3
- package/dist/RegistryContext.d.ts.map +1 -1
- package/dist/RegistryContext.js +39 -3
- package/dist/RegistryContext.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/package.json +5 -5
- package/src/Hooks.ts +224 -42
- package/src/RegistryContext.ts +62 -4
- package/src/index.ts +3 -3
package/dist/Hooks.d.ts
CHANGED
|
@@ -1,73 +1,202 @@
|
|
|
1
1
|
import * as Exit from "effect/Exit";
|
|
2
|
-
import
|
|
2
|
+
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
|
|
3
3
|
import * as Atom from "effect/unstable/reactivity/Atom";
|
|
4
4
|
import type * as AtomRef from "effect/unstable/reactivity/AtomRef";
|
|
5
|
-
import type { Accessor } from "solid-js";
|
|
5
|
+
import type { Accessor, ResourceOptions, ResourceReturn } from "solid-js";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Seeds initial atom values in the current Solid atom registry.
|
|
8
|
+
*
|
|
9
|
+
* **When to use**
|
|
10
|
+
*
|
|
11
|
+
* Use to seed atom values from a Solid component after the current registry
|
|
12
|
+
* already exists.
|
|
13
|
+
*
|
|
14
|
+
* **Details**
|
|
15
|
+
*
|
|
16
|
+
* For each atom in the current registry, this hook applies the first value
|
|
17
|
+
* supplied through the hook. Later calls for the same atom in that registry are
|
|
18
|
+
* ignored.
|
|
19
|
+
*
|
|
8
20
|
* @category hooks
|
|
21
|
+
* @since 4.0.0
|
|
9
22
|
*/
|
|
10
23
|
export declare const useAtomInitialValues: (initialValues: Iterable<readonly [Atom.Atom<any>, any]>) => void;
|
|
11
24
|
/**
|
|
12
|
-
*
|
|
25
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
26
|
+
* a Solid accessor.
|
|
27
|
+
*
|
|
13
28
|
* @category hooks
|
|
29
|
+
* @since 4.0.0
|
|
14
30
|
*/
|
|
15
31
|
export declare const useAtomValue: {
|
|
16
32
|
/**
|
|
17
|
-
*
|
|
33
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
34
|
+
* a Solid accessor.
|
|
35
|
+
*
|
|
18
36
|
* @category hooks
|
|
37
|
+
* @since 4.0.0
|
|
19
38
|
*/
|
|
20
|
-
<A>(atom: Atom.Atom<A>): Accessor<A>;
|
|
39
|
+
<A>(atom: () => Atom.Atom<A>): Accessor<A>;
|
|
21
40
|
/**
|
|
22
|
-
*
|
|
41
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
42
|
+
* a Solid accessor.
|
|
43
|
+
*
|
|
23
44
|
* @category hooks
|
|
45
|
+
* @since 4.0.0
|
|
24
46
|
*/
|
|
25
|
-
<A, B>(atom: Atom.Atom<A>, f: (_: A) => B): Accessor<B>;
|
|
47
|
+
<A, B>(atom: () => Atom.Atom<A>, f: (_: A) => B): Accessor<B>;
|
|
26
48
|
};
|
|
27
49
|
/**
|
|
28
|
-
*
|
|
50
|
+
* Mounts an atom in the current Solid registry for the lifetime of the current
|
|
51
|
+
* Solid computation.
|
|
52
|
+
*
|
|
53
|
+
* **When to use**
|
|
54
|
+
*
|
|
55
|
+
* Use to keep an atom mounted from a Solid owner without reading, writing, or
|
|
56
|
+
* refreshing it.
|
|
57
|
+
*
|
|
58
|
+
* **Details**
|
|
59
|
+
*
|
|
60
|
+
* The hook uses the current `RegistryContext`, mounts inside a Solid
|
|
61
|
+
* computation, and releases the mount through Solid cleanup when the
|
|
62
|
+
* computation changes or the owner is disposed.
|
|
63
|
+
*
|
|
64
|
+
* @see {@link useAtomSet} for mounting a writable atom while returning a setter
|
|
65
|
+
* @see {@link useAtomRefresh} for mounting an atom while returning a refresh callback
|
|
66
|
+
*
|
|
29
67
|
* @category hooks
|
|
68
|
+
* @since 4.0.0
|
|
30
69
|
*/
|
|
31
|
-
export declare const useAtomMount: <A>(atom: Atom.Atom<A>) => void;
|
|
70
|
+
export declare const useAtomMount: <A>(atom: () => Atom.Atom<A>) => void;
|
|
32
71
|
/**
|
|
33
|
-
*
|
|
72
|
+
* Returns a setter for a writable atom without subscribing to its value.
|
|
73
|
+
*
|
|
34
74
|
* @category hooks
|
|
75
|
+
* @since 4.0.0
|
|
35
76
|
*/
|
|
36
|
-
export declare const useAtomSet: <R, W, Mode extends "value" | "promise" | "promiseExit" = never>(atom: Atom.Writable<R, W>, options?: {
|
|
77
|
+
export declare const useAtomSet: <R, W, Mode extends "value" | "promise" | "promiseExit" = never>(atom: () => Atom.Writable<R, W>, options?: {
|
|
37
78
|
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined;
|
|
38
79
|
}) => "promise" extends Mode ? ((value: W) => Promise<AsyncResult.AsyncResult.Success<R>>) : "promiseExit" extends Mode ? ((value: W) => Promise<Exit.Exit<AsyncResult.AsyncResult.Success<R>, AsyncResult.AsyncResult.Failure<R>>>) : ((value: W | ((value: R) => W)) => void);
|
|
39
80
|
/**
|
|
40
|
-
*
|
|
81
|
+
* Mounts an atom and returns a callback that refreshes the current atom.
|
|
82
|
+
*
|
|
41
83
|
* @category hooks
|
|
84
|
+
* @since 4.0.0
|
|
42
85
|
*/
|
|
43
|
-
export declare const useAtomRefresh: <A>(atom: Atom.Atom<A>) => () => void;
|
|
86
|
+
export declare const useAtomRefresh: <A>(atom: () => Atom.Atom<A>) => () => void;
|
|
44
87
|
/**
|
|
45
|
-
*
|
|
88
|
+
* Returns a Solid accessor for a writable atom together with a setter for
|
|
89
|
+
* updating it.
|
|
90
|
+
*
|
|
91
|
+
* **When to use**
|
|
92
|
+
*
|
|
93
|
+
* Use when a Solid component or computation needs both a reactive accessor for
|
|
94
|
+
* a writable atom and a write function for that same atom.
|
|
95
|
+
*
|
|
96
|
+
* **Details**
|
|
97
|
+
*
|
|
98
|
+
* The setter accepts either a write value or an updater function. For
|
|
99
|
+
* `AsyncResult` atoms, `promise` and `promiseExit` modes return promises for the
|
|
100
|
+
* success value or full `Exit`.
|
|
101
|
+
*
|
|
102
|
+
* @see {@link useAtomValue} for subscribing to an atom without a setter
|
|
103
|
+
* @see {@link useAtomSet} for updating a writable atom without subscribing to its value
|
|
104
|
+
*
|
|
46
105
|
* @category hooks
|
|
106
|
+
* @since 4.0.0
|
|
47
107
|
*/
|
|
48
|
-
export declare const useAtom: <R, W, const Mode extends "value" | "promise" | "promiseExit" = never>(atom: Atom.Writable<R, W>, options?: {
|
|
108
|
+
export declare const useAtom: <R, W, const Mode extends "value" | "promise" | "promiseExit" = never>(atom: () => Atom.Writable<R, W>, options?: {
|
|
49
109
|
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined;
|
|
50
110
|
}) => readonly [value: Accessor<R>, write: "promise" extends Mode ? ((value: W) => Promise<AsyncResult.AsyncResult.Success<R>>) : "promiseExit" extends Mode ? ((value: W) => Promise<Exit.Exit<AsyncResult.AsyncResult.Success<R>, AsyncResult.AsyncResult.Failure<R>>>) : ((value: W | ((value: R) => W)) => void)];
|
|
51
111
|
/**
|
|
52
|
-
*
|
|
112
|
+
* Subscribes a callback to an atom in the current Solid registry.
|
|
113
|
+
*
|
|
53
114
|
* @category hooks
|
|
115
|
+
* @since 4.0.0
|
|
54
116
|
*/
|
|
55
|
-
export declare const useAtomSubscribe: <A>(atom: Atom.Atom<A>, f: (_: A) => void, options?: {
|
|
117
|
+
export declare const useAtomSubscribe: <A>(atom: () => Atom.Atom<A>, f: (_: A) => void, options?: {
|
|
56
118
|
readonly immediate?: boolean;
|
|
57
119
|
}) => void;
|
|
58
120
|
/**
|
|
59
|
-
*
|
|
121
|
+
* Converts an `AsyncResult` atom into a Solid resource.
|
|
122
|
+
*
|
|
60
123
|
* @category hooks
|
|
124
|
+
* @since 4.0.0
|
|
61
125
|
*/
|
|
62
|
-
export declare const
|
|
126
|
+
export declare const useAtomResource: <A, E>(atom: () => Atom.Atom<AsyncResult.AsyncResult<A, E>>, options?: ResourceOptions<A> & {
|
|
127
|
+
readonly suspendOnWaiting?: boolean | undefined;
|
|
128
|
+
}) => ResourceReturn<A, void>;
|
|
63
129
|
/**
|
|
64
|
-
*
|
|
130
|
+
* Subscribes to an atom ref and returns its value as a Solid accessor.
|
|
131
|
+
*
|
|
132
|
+
* **When to use**
|
|
133
|
+
*
|
|
134
|
+
* Use when a Solid component or computation should render from an
|
|
135
|
+
* `AtomRef.ReadonlyRef` directly instead of reading an atom through the current
|
|
136
|
+
* registry.
|
|
137
|
+
*
|
|
138
|
+
* **Details**
|
|
139
|
+
*
|
|
140
|
+
* The hook accepts a thunk for the ref, reads `ref().value`, subscribes with
|
|
141
|
+
* `ref.subscribe`, and releases the subscription through Solid cleanup when
|
|
142
|
+
* the selected ref changes or the owner is disposed.
|
|
143
|
+
*
|
|
144
|
+
* @see {@link useAtomValue} for reading an `Atom` from the current registry
|
|
145
|
+
* @see {@link useAtomRefPropValue} for reading a property ref value
|
|
146
|
+
*
|
|
65
147
|
* @category hooks
|
|
148
|
+
* @since 4.0.0
|
|
66
149
|
*/
|
|
67
|
-
export declare const
|
|
150
|
+
export declare const useAtomRef: <A>(ref: () => AtomRef.ReadonlyRef<A>) => Accessor<A>;
|
|
68
151
|
/**
|
|
69
|
-
*
|
|
152
|
+
* Returns a Solid accessor for a property ref derived from an atom ref.
|
|
153
|
+
*
|
|
154
|
+
* **When to use**
|
|
155
|
+
*
|
|
156
|
+
* Use to derive an `AtomRef` for one property of an object-shaped atom ref in a
|
|
157
|
+
* Solid computation.
|
|
158
|
+
*
|
|
159
|
+
* **Details**
|
|
160
|
+
*
|
|
161
|
+
* The returned accessor memoizes `ref().prop(prop)`, updating when the source
|
|
162
|
+
* ref thunk produces a different ref.
|
|
163
|
+
*
|
|
164
|
+
* **Gotchas**
|
|
165
|
+
*
|
|
166
|
+
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
|
167
|
+
* the property key should change.
|
|
168
|
+
*
|
|
169
|
+
* @see {@link useAtomRef} for subscribing to an atom ref value
|
|
170
|
+
* @see {@link useAtomRefPropValue} for subscribing directly to a property value
|
|
171
|
+
*
|
|
70
172
|
* @category hooks
|
|
173
|
+
* @since 4.0.0
|
|
71
174
|
*/
|
|
72
|
-
export declare const
|
|
175
|
+
export declare const useAtomRefProp: <A, K extends keyof A>(ref: () => AtomRef.AtomRef<A>, prop: K) => Accessor<AtomRef.AtomRef<A[K]>>;
|
|
176
|
+
/**
|
|
177
|
+
* Returns a Solid accessor for the value of a property ref derived from an atom
|
|
178
|
+
* ref.
|
|
179
|
+
*
|
|
180
|
+
* **When to use**
|
|
181
|
+
*
|
|
182
|
+
* Use when a Solid component or computation needs the value of one property
|
|
183
|
+
* from an object-shaped `AtomRef` without keeping the intermediate property ref.
|
|
184
|
+
*
|
|
185
|
+
* **Details**
|
|
186
|
+
*
|
|
187
|
+
* The hook composes `useAtomRefProp(ref, prop)` with `useAtomRef`, returning a
|
|
188
|
+
* Solid accessor for the selected property value.
|
|
189
|
+
*
|
|
190
|
+
* **Gotchas**
|
|
191
|
+
*
|
|
192
|
+
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
|
193
|
+
* the property key should change.
|
|
194
|
+
*
|
|
195
|
+
* @see {@link useAtomRef} for subscribing to a whole atom ref value
|
|
196
|
+
* @see {@link useAtomRefProp} for returning the property ref directly
|
|
197
|
+
*
|
|
198
|
+
* @category hooks
|
|
199
|
+
* @since 4.0.0
|
|
200
|
+
*/
|
|
201
|
+
export declare const useAtomRefPropValue: <A, K extends keyof A>(ref: () => AtomRef.AtomRef<A>, prop: K) => Accessor<A[K]>;
|
|
73
202
|
//# sourceMappingURL=Hooks.d.ts.map
|
package/dist/Hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Hooks.d.ts","sourceRoot":"","sources":["../src/Hooks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Hooks.d.ts","sourceRoot":"","sources":["../src/Hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/Hooks.js
CHANGED
|
@@ -1,17 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The `Hooks` module provides SolidJS hooks for reading, writing, mounting, and
|
|
3
|
+
* subscribing to Effect atoms through the current Solid atom registry.
|
|
4
|
+
*
|
|
5
|
+
* **Common tasks**
|
|
6
|
+
*
|
|
7
|
+
* - Read an atom as a Solid accessor with {@link useAtomValue}
|
|
8
|
+
* - Read and write a writable atom with {@link useAtom}
|
|
9
|
+
* - Write without subscribing to the value with {@link useAtomSet}
|
|
10
|
+
* - Refresh or mount atoms from components with {@link useAtomRefresh} and {@link useAtomMount}
|
|
11
|
+
* - Convert `AsyncResult` atoms into Solid resources with {@link useAtomResource}
|
|
12
|
+
* - Work with atom refs and nested ref properties with {@link useAtomRef}, {@link useAtomRefProp},
|
|
13
|
+
* and {@link useAtomRefPropValue}
|
|
14
|
+
*
|
|
15
|
+
* **Solid integration notes**
|
|
16
|
+
*
|
|
17
|
+
* Hooks in this module read the registry from {@link RegistryContext}, so they
|
|
18
|
+
* should be used under the matching provider for the atom graph you want to
|
|
19
|
+
* observe. Atom arguments are thunks so Solid can track dynamic atom selection;
|
|
20
|
+
* subscriptions are registered in Solid computations and disposed with
|
|
21
|
+
* `onCleanup` when the computation changes or the component unmounts.
|
|
22
|
+
*
|
|
23
|
+
* @since 4.0.0
|
|
3
24
|
*/
|
|
4
25
|
import * as Cause from "effect/Cause";
|
|
5
26
|
import * as Effect from "effect/Effect";
|
|
6
27
|
import * as Exit from "effect/Exit";
|
|
28
|
+
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
|
|
7
29
|
import * as Atom from "effect/unstable/reactivity/Atom";
|
|
8
30
|
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
|
|
9
|
-
import { createSignal, onCleanup, useContext } from "solid-js";
|
|
31
|
+
import { createComputed, createEffect, createMemo, createResource, createSignal, onCleanup, useContext } from "solid-js";
|
|
10
32
|
import { RegistryContext } from "./RegistryContext.js";
|
|
11
33
|
const initialValuesSet = /*#__PURE__*/new WeakMap();
|
|
12
34
|
/**
|
|
13
|
-
*
|
|
35
|
+
* Seeds initial atom values in the current Solid atom registry.
|
|
36
|
+
*
|
|
37
|
+
* **When to use**
|
|
38
|
+
*
|
|
39
|
+
* Use to seed atom values from a Solid component after the current registry
|
|
40
|
+
* already exists.
|
|
41
|
+
*
|
|
42
|
+
* **Details**
|
|
43
|
+
*
|
|
44
|
+
* For each atom in the current registry, this hook applies the first value
|
|
45
|
+
* supplied through the hook. Later calls for the same atom in that registry are
|
|
46
|
+
* ignored.
|
|
47
|
+
*
|
|
14
48
|
* @category hooks
|
|
49
|
+
* @since 4.0.0
|
|
15
50
|
*/
|
|
16
51
|
export const useAtomInitialValues = initialValues => {
|
|
17
52
|
const registry = useContext(RegistryContext);
|
|
@@ -28,33 +63,44 @@ export const useAtomInitialValues = initialValues => {
|
|
|
28
63
|
}
|
|
29
64
|
};
|
|
30
65
|
/**
|
|
31
|
-
*
|
|
66
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
67
|
+
* a Solid accessor.
|
|
68
|
+
*
|
|
32
69
|
* @category hooks
|
|
70
|
+
* @since 4.0.0
|
|
33
71
|
*/
|
|
34
72
|
export const useAtomValue = (atom, f) => {
|
|
35
73
|
const registry = useContext(RegistryContext);
|
|
36
|
-
return createAtomAccessor(registry, f ? Atom.map(atom, f) : atom);
|
|
74
|
+
return createAtomAccessor(registry, f ? () => Atom.map(atom(), f) : atom);
|
|
37
75
|
};
|
|
38
76
|
function createAtomAccessor(registry, atom) {
|
|
39
|
-
const [value, setValue] = createSignal(
|
|
40
|
-
|
|
77
|
+
const [value, setValue] = createSignal(null);
|
|
78
|
+
createComputed(() => {
|
|
79
|
+
onCleanup(registry.subscribe(atom(), setValue, constImmediate));
|
|
80
|
+
});
|
|
41
81
|
return value;
|
|
42
82
|
}
|
|
83
|
+
const constImmediate = {
|
|
84
|
+
immediate: true
|
|
85
|
+
};
|
|
43
86
|
function mountAtom(registry, atom) {
|
|
44
|
-
|
|
87
|
+
createComputed(() => {
|
|
88
|
+
onCleanup(registry.mount(atom()));
|
|
89
|
+
});
|
|
45
90
|
}
|
|
46
91
|
function setAtom(registry, atom, options) {
|
|
92
|
+
const memo = createMemo(atom);
|
|
47
93
|
if (options?.mode === "promise" || options?.mode === "promiseExit") {
|
|
48
94
|
return value => {
|
|
49
|
-
registry.set(
|
|
50
|
-
const promise = Effect.runPromiseExit(AtomRegistry.getResult(registry,
|
|
95
|
+
registry.set(memo(), value);
|
|
96
|
+
const promise = Effect.runPromiseExit(AtomRegistry.getResult(registry, memo(), {
|
|
51
97
|
suspendOnWaiting: true
|
|
52
98
|
}));
|
|
53
99
|
return options.mode === "promise" ? promise.then(flattenExit) : promise;
|
|
54
100
|
};
|
|
55
101
|
}
|
|
56
102
|
return value => {
|
|
57
|
-
registry.set(
|
|
103
|
+
registry.set(memo(), typeof value === "function" ? value(registry.get(memo())) : value);
|
|
58
104
|
};
|
|
59
105
|
}
|
|
60
106
|
const flattenExit = exit => {
|
|
@@ -62,16 +108,35 @@ const flattenExit = exit => {
|
|
|
62
108
|
throw Cause.squash(exit.cause);
|
|
63
109
|
};
|
|
64
110
|
/**
|
|
65
|
-
*
|
|
111
|
+
* Mounts an atom in the current Solid registry for the lifetime of the current
|
|
112
|
+
* Solid computation.
|
|
113
|
+
*
|
|
114
|
+
* **When to use**
|
|
115
|
+
*
|
|
116
|
+
* Use to keep an atom mounted from a Solid owner without reading, writing, or
|
|
117
|
+
* refreshing it.
|
|
118
|
+
*
|
|
119
|
+
* **Details**
|
|
120
|
+
*
|
|
121
|
+
* The hook uses the current `RegistryContext`, mounts inside a Solid
|
|
122
|
+
* computation, and releases the mount through Solid cleanup when the
|
|
123
|
+
* computation changes or the owner is disposed.
|
|
124
|
+
*
|
|
125
|
+
* @see {@link useAtomSet} for mounting a writable atom while returning a setter
|
|
126
|
+
* @see {@link useAtomRefresh} for mounting an atom while returning a refresh callback
|
|
127
|
+
*
|
|
66
128
|
* @category hooks
|
|
129
|
+
* @since 4.0.0
|
|
67
130
|
*/
|
|
68
131
|
export const useAtomMount = atom => {
|
|
69
132
|
const registry = useContext(RegistryContext);
|
|
70
133
|
mountAtom(registry, atom);
|
|
71
134
|
};
|
|
72
135
|
/**
|
|
73
|
-
*
|
|
136
|
+
* Returns a setter for a writable atom without subscribing to its value.
|
|
137
|
+
*
|
|
74
138
|
* @category hooks
|
|
139
|
+
* @since 4.0.0
|
|
75
140
|
*/
|
|
76
141
|
export const useAtomSet = (atom, options) => {
|
|
77
142
|
const registry = useContext(RegistryContext);
|
|
@@ -79,47 +144,151 @@ export const useAtomSet = (atom, options) => {
|
|
|
79
144
|
return setAtom(registry, atom, options);
|
|
80
145
|
};
|
|
81
146
|
/**
|
|
82
|
-
*
|
|
147
|
+
* Mounts an atom and returns a callback that refreshes the current atom.
|
|
148
|
+
*
|
|
83
149
|
* @category hooks
|
|
150
|
+
* @since 4.0.0
|
|
84
151
|
*/
|
|
85
152
|
export const useAtomRefresh = atom => {
|
|
86
153
|
const registry = useContext(RegistryContext);
|
|
87
154
|
mountAtom(registry, atom);
|
|
88
|
-
|
|
155
|
+
const memo = createMemo(atom);
|
|
156
|
+
return () => registry.refresh(memo());
|
|
89
157
|
};
|
|
90
158
|
/**
|
|
91
|
-
*
|
|
159
|
+
* Returns a Solid accessor for a writable atom together with a setter for
|
|
160
|
+
* updating it.
|
|
161
|
+
*
|
|
162
|
+
* **When to use**
|
|
163
|
+
*
|
|
164
|
+
* Use when a Solid component or computation needs both a reactive accessor for
|
|
165
|
+
* a writable atom and a write function for that same atom.
|
|
166
|
+
*
|
|
167
|
+
* **Details**
|
|
168
|
+
*
|
|
169
|
+
* The setter accepts either a write value or an updater function. For
|
|
170
|
+
* `AsyncResult` atoms, `promise` and `promiseExit` modes return promises for the
|
|
171
|
+
* success value or full `Exit`.
|
|
172
|
+
*
|
|
173
|
+
* @see {@link useAtomValue} for subscribing to an atom without a setter
|
|
174
|
+
* @see {@link useAtomSet} for updating a writable atom without subscribing to its value
|
|
175
|
+
*
|
|
92
176
|
* @category hooks
|
|
177
|
+
* @since 4.0.0
|
|
93
178
|
*/
|
|
94
179
|
export const useAtom = (atom, options) => {
|
|
95
180
|
const registry = useContext(RegistryContext);
|
|
96
181
|
return [createAtomAccessor(registry, atom), setAtom(registry, atom, options)];
|
|
97
182
|
};
|
|
98
183
|
/**
|
|
99
|
-
*
|
|
184
|
+
* Subscribes a callback to an atom in the current Solid registry.
|
|
185
|
+
*
|
|
100
186
|
* @category hooks
|
|
187
|
+
* @since 4.0.0
|
|
101
188
|
*/
|
|
102
189
|
export const useAtomSubscribe = (atom, f, options) => {
|
|
103
190
|
const registry = useContext(RegistryContext);
|
|
104
|
-
|
|
191
|
+
createEffect(() => {
|
|
192
|
+
onCleanup(registry.subscribe(atom(), f, options));
|
|
193
|
+
});
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* Converts an `AsyncResult` atom into a Solid resource.
|
|
197
|
+
*
|
|
198
|
+
* @category hooks
|
|
199
|
+
* @since 4.0.0
|
|
200
|
+
*/
|
|
201
|
+
export const useAtomResource = (atom, options) => {
|
|
202
|
+
const result = useAtomValue(atom);
|
|
203
|
+
return createResource(result, result => {
|
|
204
|
+
if (AsyncResult.isInitial(result) || options?.suspendOnWaiting && result.waiting) {
|
|
205
|
+
return constUnresolvedPromise;
|
|
206
|
+
} else if (AsyncResult.isSuccess(result)) {
|
|
207
|
+
return Promise.resolve(result.value);
|
|
208
|
+
}
|
|
209
|
+
return Promise.reject(Cause.squash(result.cause));
|
|
210
|
+
});
|
|
105
211
|
};
|
|
212
|
+
const constUnresolvedPromise = /*#__PURE__*/new Promise(() => {});
|
|
106
213
|
/**
|
|
107
|
-
*
|
|
214
|
+
* Subscribes to an atom ref and returns its value as a Solid accessor.
|
|
215
|
+
*
|
|
216
|
+
* **When to use**
|
|
217
|
+
*
|
|
218
|
+
* Use when a Solid component or computation should render from an
|
|
219
|
+
* `AtomRef.ReadonlyRef` directly instead of reading an atom through the current
|
|
220
|
+
* registry.
|
|
221
|
+
*
|
|
222
|
+
* **Details**
|
|
223
|
+
*
|
|
224
|
+
* The hook accepts a thunk for the ref, reads `ref().value`, subscribes with
|
|
225
|
+
* `ref.subscribe`, and releases the subscription through Solid cleanup when
|
|
226
|
+
* the selected ref changes or the owner is disposed.
|
|
227
|
+
*
|
|
228
|
+
* @see {@link useAtomValue} for reading an `Atom` from the current registry
|
|
229
|
+
* @see {@link useAtomRefPropValue} for reading a property ref value
|
|
230
|
+
*
|
|
108
231
|
* @category hooks
|
|
232
|
+
* @since 4.0.0
|
|
109
233
|
*/
|
|
110
234
|
export const useAtomRef = ref => {
|
|
111
|
-
const [value, setValue] = createSignal(
|
|
112
|
-
|
|
235
|
+
const [value, setValue] = createSignal(null);
|
|
236
|
+
createComputed(() => {
|
|
237
|
+
const r = ref();
|
|
238
|
+
setValue(r.value);
|
|
239
|
+
onCleanup(r.subscribe(setValue));
|
|
240
|
+
});
|
|
113
241
|
return value;
|
|
114
242
|
};
|
|
115
243
|
/**
|
|
116
|
-
*
|
|
244
|
+
* Returns a Solid accessor for a property ref derived from an atom ref.
|
|
245
|
+
*
|
|
246
|
+
* **When to use**
|
|
247
|
+
*
|
|
248
|
+
* Use to derive an `AtomRef` for one property of an object-shaped atom ref in a
|
|
249
|
+
* Solid computation.
|
|
250
|
+
*
|
|
251
|
+
* **Details**
|
|
252
|
+
*
|
|
253
|
+
* The returned accessor memoizes `ref().prop(prop)`, updating when the source
|
|
254
|
+
* ref thunk produces a different ref.
|
|
255
|
+
*
|
|
256
|
+
* **Gotchas**
|
|
257
|
+
*
|
|
258
|
+
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
|
259
|
+
* the property key should change.
|
|
260
|
+
*
|
|
261
|
+
* @see {@link useAtomRef} for subscribing to an atom ref value
|
|
262
|
+
* @see {@link useAtomRefPropValue} for subscribing directly to a property value
|
|
263
|
+
*
|
|
117
264
|
* @category hooks
|
|
265
|
+
* @since 4.0.0
|
|
118
266
|
*/
|
|
119
|
-
export const useAtomRefProp = (ref, prop) => ref.prop(prop);
|
|
267
|
+
export const useAtomRefProp = (ref, prop) => createMemo(() => ref().prop(prop));
|
|
120
268
|
/**
|
|
121
|
-
*
|
|
269
|
+
* Returns a Solid accessor for the value of a property ref derived from an atom
|
|
270
|
+
* ref.
|
|
271
|
+
*
|
|
272
|
+
* **When to use**
|
|
273
|
+
*
|
|
274
|
+
* Use when a Solid component or computation needs the value of one property
|
|
275
|
+
* from an object-shaped `AtomRef` without keeping the intermediate property ref.
|
|
276
|
+
*
|
|
277
|
+
* **Details**
|
|
278
|
+
*
|
|
279
|
+
* The hook composes `useAtomRefProp(ref, prop)` with `useAtomRef`, returning a
|
|
280
|
+
* Solid accessor for the selected property value.
|
|
281
|
+
*
|
|
282
|
+
* **Gotchas**
|
|
283
|
+
*
|
|
284
|
+
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
|
285
|
+
* the property key should change.
|
|
286
|
+
*
|
|
287
|
+
* @see {@link useAtomRef} for subscribing to a whole atom ref value
|
|
288
|
+
* @see {@link useAtomRefProp} for returning the property ref directly
|
|
289
|
+
*
|
|
122
290
|
* @category hooks
|
|
291
|
+
* @since 4.0.0
|
|
123
292
|
*/
|
|
124
293
|
export const useAtomRefPropValue = (ref, prop) => useAtomRef(useAtomRefProp(ref, prop));
|
|
125
294
|
//# sourceMappingURL=Hooks.js.map
|
package/dist/Hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Hooks.js","names":["Cause","Effect","Exit","Atom","AtomRegistry","createSignal","onCleanup","useContext","RegistryContext","initialValuesSet","WeakMap","useAtomInitialValues","initialValues","registry","set","get","undefined","WeakSet","atom","value","has","add","ensureNode","setValue","useAtomValue","f","createAtomAccessor","map","subscribe","mountAtom","mount","setAtom","options","mode","promise","runPromiseExit","getResult","suspendOnWaiting","then","flattenExit","exit","isSuccess","squash","cause","useAtomMount","useAtomSet","useAtomRefresh","refresh","useAtom","useAtomSubscribe","useAtomRef","ref","useAtomRefProp","prop","useAtomRefPropValue"],"sources":["../src/Hooks.ts"],"sourcesContent":[null],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Hooks.js","names":["Cause","Effect","Exit","AsyncResult","Atom","AtomRegistry","createComputed","createEffect","createMemo","createResource","createSignal","onCleanup","useContext","RegistryContext","initialValuesSet","WeakMap","useAtomInitialValues","initialValues","registry","set","get","undefined","WeakSet","atom","value","has","add","ensureNode","setValue","useAtomValue","f","createAtomAccessor","map","subscribe","constImmediate","immediate","mountAtom","mount","setAtom","options","memo","mode","promise","runPromiseExit","getResult","suspendOnWaiting","then","flattenExit","exit","isSuccess","squash","cause","useAtomMount","useAtomSet","useAtomRefresh","refresh","useAtom","useAtomSubscribe","useAtomResource","result","isInitial","waiting","constUnresolvedPromise","Promise","resolve","reject","useAtomRef","ref","r","useAtomRefProp","prop","useAtomRefPropValue"],"sources":["../src/Hooks.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -1,17 +1,75 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The `RegistryContext` module provides the Solid context used by Effect Atom
|
|
3
|
+
* hooks to share an `AtomRegistry` across an owner tree. The registry owns atom
|
|
4
|
+
* state, scheduling, and idle cleanup, so Solid components that read or write
|
|
5
|
+
* atoms coordinate through the same runtime instead of creating isolated
|
|
6
|
+
* registries.
|
|
7
|
+
*
|
|
8
|
+
* **Common tasks**
|
|
9
|
+
*
|
|
10
|
+
* - Use {@link RegistryProvider} to scope atom state to a Solid subtree
|
|
11
|
+
* - Seed atoms for tests, examples, or server-provided data with `initialValues`
|
|
12
|
+
* - Override scheduling or idle timing for custom rendering environments
|
|
13
|
+
* - Read {@link RegistryContext} when integrating lower-level atom APIs
|
|
14
|
+
*
|
|
15
|
+
* **Gotchas**
|
|
16
|
+
*
|
|
17
|
+
* - The provider creates a registry for the current Solid owner and disposes it
|
|
18
|
+
* with `onCleanup`
|
|
19
|
+
* - `initialValues` are applied when the provider creates the registry, not as
|
|
20
|
+
* reactive updates after creation
|
|
21
|
+
* - Overriding `scheduleTask` changes when atom work is flushed, so it should
|
|
22
|
+
* return a cancellation function that is safe to call during Solid cleanup
|
|
23
|
+
*
|
|
24
|
+
* @since 4.0.0
|
|
3
25
|
*/
|
|
4
26
|
import type * as Atom from "effect/unstable/reactivity/Atom";
|
|
5
27
|
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
|
|
6
28
|
import type { JSX } from "solid-js";
|
|
7
29
|
/**
|
|
8
|
-
*
|
|
30
|
+
* A Solid context that carries the `AtomRegistry` used by atom hooks in the
|
|
31
|
+
* current owner tree.
|
|
32
|
+
*
|
|
33
|
+
* **When to use**
|
|
34
|
+
*
|
|
35
|
+
* Use when integrating lower-level Solid atom APIs that need direct access to,
|
|
36
|
+
* or direct provisioning of, the `AtomRegistry` for the current owner tree.
|
|
37
|
+
*
|
|
38
|
+
* **Details**
|
|
39
|
+
*
|
|
40
|
+
* When no provider is present, the context uses a standalone default registry.
|
|
41
|
+
*
|
|
42
|
+
* @see {@link RegistryProvider} for creating and providing a registry for a Solid subtree
|
|
43
|
+
*
|
|
9
44
|
* @category context
|
|
45
|
+
* @since 4.0.0
|
|
10
46
|
*/
|
|
11
47
|
export declare const RegistryContext: import("solid-js").Context<AtomRegistry.AtomRegistry>;
|
|
12
48
|
/**
|
|
13
|
-
*
|
|
49
|
+
* Creates an `AtomRegistry` for a Solid subtree, optionally seeding initial atom
|
|
50
|
+
* values and scheduler settings, and disposes the registry when the owner is
|
|
51
|
+
* cleaned up.
|
|
52
|
+
*
|
|
53
|
+
* **When to use**
|
|
54
|
+
*
|
|
55
|
+
* Use to scope atom state, scheduling, and cleanup to a Solid subtree.
|
|
56
|
+
*
|
|
57
|
+
* **Details**
|
|
58
|
+
*
|
|
59
|
+
* The provider creates an `AtomRegistry` with `AtomRegistry.make`, forwards
|
|
60
|
+
* `initialValues`, `scheduleTask`, `timeoutResolution`, and
|
|
61
|
+
* `defaultIdleTTL`, and supplies the registry through `RegistryContext`.
|
|
62
|
+
*
|
|
63
|
+
* **Gotchas**
|
|
64
|
+
*
|
|
65
|
+
* Provider options are consumed when the registry is created; they are not
|
|
66
|
+
* reactive updates. A custom `scheduleTask` should return a cancellation
|
|
67
|
+
* function that is safe to call during Solid cleanup.
|
|
68
|
+
*
|
|
69
|
+
* @see {@link RegistryContext} for the context supplied by this provider
|
|
70
|
+
*
|
|
14
71
|
* @category context
|
|
72
|
+
* @since 4.0.0
|
|
15
73
|
*/
|
|
16
74
|
export declare const RegistryProvider: (options: {
|
|
17
75
|
readonly children?: JSX.Element | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegistryContext.d.ts","sourceRoot":"","sources":["../src/RegistryContext.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"RegistryContext.d.ts","sourceRoot":"","sources":["../src/RegistryContext.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,KAAK,IAAI,MAAM,iCAAiC,CAAA;AAC5D,OAAO,KAAK,YAAY,MAAM,yCAAyC,CAAA;AACvE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAGnC;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,eAAe,uDAAgE,CAAA;AAE5F;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,SAAS,CAAA;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,SAAS,CAAA;IAC7E,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC,GAAG,SAAS,CAAA;IACnE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC7C,gBAcA,CAAA"}
|
package/dist/RegistryContext.js
CHANGED
|
@@ -1,20 +1,56 @@
|
|
|
1
1
|
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
|
|
2
2
|
import { createComponent, createContext, onCleanup } from "solid-js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* A Solid context that carries the `AtomRegistry` used by atom hooks in the
|
|
5
|
+
* current owner tree.
|
|
6
|
+
*
|
|
7
|
+
* **When to use**
|
|
8
|
+
*
|
|
9
|
+
* Use when integrating lower-level Solid atom APIs that need direct access to,
|
|
10
|
+
* or direct provisioning of, the `AtomRegistry` for the current owner tree.
|
|
11
|
+
*
|
|
12
|
+
* **Details**
|
|
13
|
+
*
|
|
14
|
+
* When no provider is present, the context uses a standalone default registry.
|
|
15
|
+
*
|
|
16
|
+
* @see {@link RegistryProvider} for creating and providing a registry for a Solid subtree
|
|
17
|
+
*
|
|
5
18
|
* @category context
|
|
19
|
+
* @since 4.0.0
|
|
6
20
|
*/
|
|
7
21
|
export const RegistryContext = /*#__PURE__*/createContext(/*#__PURE__*/AtomRegistry.make());
|
|
8
22
|
/**
|
|
9
|
-
*
|
|
23
|
+
* Creates an `AtomRegistry` for a Solid subtree, optionally seeding initial atom
|
|
24
|
+
* values and scheduler settings, and disposes the registry when the owner is
|
|
25
|
+
* cleaned up.
|
|
26
|
+
*
|
|
27
|
+
* **When to use**
|
|
28
|
+
*
|
|
29
|
+
* Use to scope atom state, scheduling, and cleanup to a Solid subtree.
|
|
30
|
+
*
|
|
31
|
+
* **Details**
|
|
32
|
+
*
|
|
33
|
+
* The provider creates an `AtomRegistry` with `AtomRegistry.make`, forwards
|
|
34
|
+
* `initialValues`, `scheduleTask`, `timeoutResolution`, and
|
|
35
|
+
* `defaultIdleTTL`, and supplies the registry through `RegistryContext`.
|
|
36
|
+
*
|
|
37
|
+
* **Gotchas**
|
|
38
|
+
*
|
|
39
|
+
* Provider options are consumed when the registry is created; they are not
|
|
40
|
+
* reactive updates. A custom `scheduleTask` should return a cancellation
|
|
41
|
+
* function that is safe to call during Solid cleanup.
|
|
42
|
+
*
|
|
43
|
+
* @see {@link RegistryContext} for the context supplied by this provider
|
|
44
|
+
*
|
|
10
45
|
* @category context
|
|
46
|
+
* @since 4.0.0
|
|
11
47
|
*/
|
|
12
48
|
export const RegistryProvider = options => {
|
|
13
49
|
const registry = AtomRegistry.make({
|
|
14
50
|
scheduleTask: options.scheduleTask,
|
|
15
51
|
initialValues: options.initialValues,
|
|
16
52
|
timeoutResolution: options.timeoutResolution,
|
|
17
|
-
defaultIdleTTL: options.defaultIdleTTL
|
|
53
|
+
defaultIdleTTL: options.defaultIdleTTL ?? 400
|
|
18
54
|
});
|
|
19
55
|
onCleanup(() => registry.dispose());
|
|
20
56
|
return createComponent(RegistryContext.Provider, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegistryContext.js","names":["AtomRegistry","createComponent","createContext","onCleanup","RegistryContext","make","RegistryProvider","options","registry","scheduleTask","initialValues","timeoutResolution","defaultIdleTTL","dispose","Provider","value","children"],"sources":["../src/RegistryContext.ts"],"sourcesContent":[null],"mappings":"
|
|
1
|
+
{"version":3,"file":"RegistryContext.js","names":["AtomRegistry","createComponent","createContext","onCleanup","RegistryContext","make","RegistryProvider","options","registry","scheduleTask","initialValues","timeoutResolution","defaultIdleTTL","dispose","Provider","value","children"],"sources":["../src/RegistryContext.ts"],"sourcesContent":[null],"mappings":"AA0BA,OAAO,KAAKA,YAAY,MAAM,yCAAyC;AAEvE,SAASC,eAAe,EAAEC,aAAa,EAAEC,SAAS,QAAQ,UAAU;AAEpE;;;;;;;;;;;;;;;;;;AAkBA,OAAO,MAAMC,eAAe,gBAAGF,aAAa,cAA4BF,YAAY,CAACK,IAAI,EAAE,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,OAAO,MAAMC,gBAAgB,GAAIC,OAMhC,IAAI;EACH,MAAMC,QAAQ,GAAGR,YAAY,CAACK,IAAI,CAAC;IACjCI,YAAY,EAAEF,OAAO,CAACE,YAAY;IAClCC,aAAa,EAAEH,OAAO,CAACG,aAAa;IACpCC,iBAAiB,EAAEJ,OAAO,CAACI,iBAAiB;IAC5CC,cAAc,EAAEL,OAAO,CAACK,cAAc,IAAI;GAC3C,CAAC;EACFT,SAAS,CAAC,MAAMK,QAAQ,CAACK,OAAO,EAAE,CAAC;EACnC,OAAOZ,eAAe,CAACG,eAAe,CAACU,QAAQ,EAAE;IAC/CC,KAAK,EAAEP,QAAQ;IACf,IAAIQ,QAAQA,CAAA;MACV,OAAOT,OAAO,CAACS,QAAQ;IACzB;GACD,CAAC;AACJ,CAAC","ignoreList":[]}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect/atom-solid",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.71",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "SolidJS bindings for the Effect Atom modules",
|
|
@@ -44,15 +44,15 @@
|
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"solid-js": ">=1 <2",
|
|
47
|
-
"effect": "^4.0.0-beta.
|
|
47
|
+
"effect": "^4.0.0-beta.71"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@solidjs/testing-library": "^0.8.0",
|
|
51
51
|
"@testing-library/dom": "^10.4.1",
|
|
52
52
|
"@testing-library/jest-dom": "^6.9.1",
|
|
53
|
-
"jsdom": "^
|
|
54
|
-
"solid-js": "^1.9.
|
|
55
|
-
"effect": "^4.0.0-beta.
|
|
53
|
+
"jsdom": "^29.1.1",
|
|
54
|
+
"solid-js": "^1.9.12",
|
|
55
|
+
"effect": "^4.0.0-beta.71"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "tsc -b tsconfig.json && pnpm babel",
|
package/src/Hooks.ts
CHANGED
|
@@ -1,22 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The `Hooks` module provides SolidJS hooks for reading, writing, mounting, and
|
|
3
|
+
* subscribing to Effect atoms through the current Solid atom registry.
|
|
4
|
+
*
|
|
5
|
+
* **Common tasks**
|
|
6
|
+
*
|
|
7
|
+
* - Read an atom as a Solid accessor with {@link useAtomValue}
|
|
8
|
+
* - Read and write a writable atom with {@link useAtom}
|
|
9
|
+
* - Write without subscribing to the value with {@link useAtomSet}
|
|
10
|
+
* - Refresh or mount atoms from components with {@link useAtomRefresh} and {@link useAtomMount}
|
|
11
|
+
* - Convert `AsyncResult` atoms into Solid resources with {@link useAtomResource}
|
|
12
|
+
* - Work with atom refs and nested ref properties with {@link useAtomRef}, {@link useAtomRefProp},
|
|
13
|
+
* and {@link useAtomRefPropValue}
|
|
14
|
+
*
|
|
15
|
+
* **Solid integration notes**
|
|
16
|
+
*
|
|
17
|
+
* Hooks in this module read the registry from {@link RegistryContext}, so they
|
|
18
|
+
* should be used under the matching provider for the atom graph you want to
|
|
19
|
+
* observe. Atom arguments are thunks so Solid can track dynamic atom selection;
|
|
20
|
+
* subscriptions are registered in Solid computations and disposed with
|
|
21
|
+
* `onCleanup` when the computation changes or the component unmounts.
|
|
22
|
+
*
|
|
23
|
+
* @since 4.0.0
|
|
3
24
|
*/
|
|
4
25
|
import * as Cause from "effect/Cause"
|
|
5
26
|
import * as Effect from "effect/Effect"
|
|
6
27
|
import * as Exit from "effect/Exit"
|
|
7
|
-
import
|
|
28
|
+
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
|
8
29
|
import * as Atom from "effect/unstable/reactivity/Atom"
|
|
9
30
|
import type * as AtomRef from "effect/unstable/reactivity/AtomRef"
|
|
10
31
|
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
|
11
|
-
import type { Accessor } from "solid-js"
|
|
12
|
-
import { createSignal, onCleanup, useContext } from "solid-js"
|
|
32
|
+
import type { Accessor, ResourceOptions, ResourceReturn } from "solid-js"
|
|
33
|
+
import { createComputed, createEffect, createMemo, createResource, createSignal, onCleanup, useContext } from "solid-js"
|
|
13
34
|
import { RegistryContext } from "./RegistryContext.ts"
|
|
14
35
|
|
|
15
36
|
const initialValuesSet = new WeakMap<AtomRegistry.AtomRegistry, WeakSet<Atom.Atom<any>>>()
|
|
16
37
|
|
|
17
38
|
/**
|
|
18
|
-
*
|
|
39
|
+
* Seeds initial atom values in the current Solid atom registry.
|
|
40
|
+
*
|
|
41
|
+
* **When to use**
|
|
42
|
+
*
|
|
43
|
+
* Use to seed atom values from a Solid component after the current registry
|
|
44
|
+
* already exists.
|
|
45
|
+
*
|
|
46
|
+
* **Details**
|
|
47
|
+
*
|
|
48
|
+
* For each atom in the current registry, this hook applies the first value
|
|
49
|
+
* supplied through the hook. Later calls for the same atom in that registry are
|
|
50
|
+
* ignored.
|
|
51
|
+
*
|
|
19
52
|
* @category hooks
|
|
53
|
+
* @since 4.0.0
|
|
20
54
|
*/
|
|
21
55
|
export const useAtomInitialValues = (initialValues: Iterable<readonly [Atom.Atom<any>, any]>): void => {
|
|
22
56
|
const registry = useContext(RegistryContext)
|
|
@@ -34,38 +68,53 @@ export const useAtomInitialValues = (initialValues: Iterable<readonly [Atom.Atom
|
|
|
34
68
|
}
|
|
35
69
|
|
|
36
70
|
/**
|
|
37
|
-
*
|
|
71
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
72
|
+
* a Solid accessor.
|
|
73
|
+
*
|
|
38
74
|
* @category hooks
|
|
75
|
+
* @since 4.0.0
|
|
39
76
|
*/
|
|
40
77
|
export const useAtomValue: {
|
|
41
78
|
/**
|
|
42
|
-
*
|
|
79
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
80
|
+
* a Solid accessor.
|
|
81
|
+
*
|
|
43
82
|
* @category hooks
|
|
83
|
+
* @since 4.0.0
|
|
44
84
|
*/
|
|
45
|
-
<A>(atom: Atom.Atom<A>): Accessor<A>
|
|
85
|
+
<A>(atom: () => Atom.Atom<A>): Accessor<A>
|
|
46
86
|
/**
|
|
47
|
-
*
|
|
87
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
88
|
+
* a Solid accessor.
|
|
89
|
+
*
|
|
48
90
|
* @category hooks
|
|
91
|
+
* @since 4.0.0
|
|
49
92
|
*/
|
|
50
|
-
<A, B>(atom: Atom.Atom<A>, f: (_: A) => B): Accessor<B>
|
|
51
|
-
} = <A>(atom: Atom.Atom<A>, f?: (_: A) => A): Accessor<A> => {
|
|
93
|
+
<A, B>(atom: () => Atom.Atom<A>, f: (_: A) => B): Accessor<B>
|
|
94
|
+
} = <A>(atom: () => Atom.Atom<A>, f?: (_: A) => A): Accessor<A> => {
|
|
52
95
|
const registry = useContext(RegistryContext)
|
|
53
|
-
return createAtomAccessor(registry, f ? Atom.map(atom, f) : atom)
|
|
96
|
+
return createAtomAccessor(registry, f ? () => Atom.map(atom(), f) : atom)
|
|
54
97
|
}
|
|
55
98
|
|
|
56
|
-
function createAtomAccessor<A>(registry: AtomRegistry.AtomRegistry, atom: Atom.Atom<A>): Accessor<A> {
|
|
57
|
-
const [value, setValue] = createSignal<A>(
|
|
58
|
-
|
|
99
|
+
function createAtomAccessor<A>(registry: AtomRegistry.AtomRegistry, atom: () => Atom.Atom<A>): Accessor<A> {
|
|
100
|
+
const [value, setValue] = createSignal<A>(null as any)
|
|
101
|
+
createComputed(() => {
|
|
102
|
+
onCleanup(registry.subscribe(atom(), setValue as any, constImmediate))
|
|
103
|
+
})
|
|
59
104
|
return value
|
|
60
105
|
}
|
|
61
106
|
|
|
62
|
-
|
|
63
|
-
|
|
107
|
+
const constImmediate = { immediate: true }
|
|
108
|
+
|
|
109
|
+
function mountAtom<A>(registry: AtomRegistry.AtomRegistry, atom: () => Atom.Atom<A>): void {
|
|
110
|
+
createComputed(() => {
|
|
111
|
+
onCleanup(registry.mount(atom()))
|
|
112
|
+
})
|
|
64
113
|
}
|
|
65
114
|
|
|
66
115
|
function setAtom<R, W, Mode extends "value" | "promise" | "promiseExit" = never>(
|
|
67
116
|
registry: AtomRegistry.AtomRegistry,
|
|
68
|
-
atom: Atom.Writable<R, W>,
|
|
117
|
+
atom: () => Atom.Writable<R, W>,
|
|
69
118
|
options?: {
|
|
70
119
|
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
|
71
120
|
}
|
|
@@ -77,11 +126,12 @@ function setAtom<R, W, Mode extends "value" | "promise" | "promiseExit" = never>
|
|
|
77
126
|
) :
|
|
78
127
|
((value: W | ((value: R) => W)) => void)
|
|
79
128
|
{
|
|
129
|
+
const memo = createMemo(atom)
|
|
80
130
|
if (options?.mode === "promise" || options?.mode === "promiseExit") {
|
|
81
131
|
return ((value: W) => {
|
|
82
|
-
registry.set(
|
|
132
|
+
registry.set(memo(), value)
|
|
83
133
|
const promise = Effect.runPromiseExit(
|
|
84
|
-
AtomRegistry.getResult(registry,
|
|
134
|
+
AtomRegistry.getResult(registry, memo() as Atom.Atom<AsyncResult.AsyncResult<any, any>>, {
|
|
85
135
|
suspendOnWaiting: true
|
|
86
136
|
})
|
|
87
137
|
)
|
|
@@ -89,7 +139,7 @@ function setAtom<R, W, Mode extends "value" | "promise" | "promiseExit" = never>
|
|
|
89
139
|
}) as any
|
|
90
140
|
}
|
|
91
141
|
return ((value: W | ((value: R) => W)) => {
|
|
92
|
-
registry.set(
|
|
142
|
+
registry.set(memo(), typeof value === "function" ? (value as any)(registry.get(memo())) : value)
|
|
93
143
|
}) as any
|
|
94
144
|
}
|
|
95
145
|
|
|
@@ -99,24 +149,43 @@ const flattenExit = <A, E>(exit: Exit.Exit<A, E>): A => {
|
|
|
99
149
|
}
|
|
100
150
|
|
|
101
151
|
/**
|
|
102
|
-
*
|
|
152
|
+
* Mounts an atom in the current Solid registry for the lifetime of the current
|
|
153
|
+
* Solid computation.
|
|
154
|
+
*
|
|
155
|
+
* **When to use**
|
|
156
|
+
*
|
|
157
|
+
* Use to keep an atom mounted from a Solid owner without reading, writing, or
|
|
158
|
+
* refreshing it.
|
|
159
|
+
*
|
|
160
|
+
* **Details**
|
|
161
|
+
*
|
|
162
|
+
* The hook uses the current `RegistryContext`, mounts inside a Solid
|
|
163
|
+
* computation, and releases the mount through Solid cleanup when the
|
|
164
|
+
* computation changes or the owner is disposed.
|
|
165
|
+
*
|
|
166
|
+
* @see {@link useAtomSet} for mounting a writable atom while returning a setter
|
|
167
|
+
* @see {@link useAtomRefresh} for mounting an atom while returning a refresh callback
|
|
168
|
+
*
|
|
103
169
|
* @category hooks
|
|
170
|
+
* @since 4.0.0
|
|
104
171
|
*/
|
|
105
|
-
export const useAtomMount = <A>(atom: Atom.Atom<A>): void => {
|
|
172
|
+
export const useAtomMount = <A>(atom: () => Atom.Atom<A>): void => {
|
|
106
173
|
const registry = useContext(RegistryContext)
|
|
107
174
|
mountAtom(registry, atom)
|
|
108
175
|
}
|
|
109
176
|
|
|
110
177
|
/**
|
|
111
|
-
*
|
|
178
|
+
* Returns a setter for a writable atom without subscribing to its value.
|
|
179
|
+
*
|
|
112
180
|
* @category hooks
|
|
181
|
+
* @since 4.0.0
|
|
113
182
|
*/
|
|
114
183
|
export const useAtomSet = <
|
|
115
184
|
R,
|
|
116
185
|
W,
|
|
117
186
|
Mode extends "value" | "promise" | "promiseExit" = never
|
|
118
187
|
>(
|
|
119
|
-
atom: Atom.Writable<R, W>,
|
|
188
|
+
atom: () => Atom.Writable<R, W>,
|
|
120
189
|
options?: {
|
|
121
190
|
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
|
122
191
|
}
|
|
@@ -134,21 +203,41 @@ export const useAtomSet = <
|
|
|
134
203
|
}
|
|
135
204
|
|
|
136
205
|
/**
|
|
137
|
-
*
|
|
206
|
+
* Mounts an atom and returns a callback that refreshes the current atom.
|
|
207
|
+
*
|
|
138
208
|
* @category hooks
|
|
209
|
+
* @since 4.0.0
|
|
139
210
|
*/
|
|
140
|
-
export const useAtomRefresh = <A>(atom: Atom.Atom<A>): () => void => {
|
|
211
|
+
export const useAtomRefresh = <A>(atom: () => Atom.Atom<A>): () => void => {
|
|
141
212
|
const registry = useContext(RegistryContext)
|
|
142
213
|
mountAtom(registry, atom)
|
|
143
|
-
|
|
214
|
+
const memo = createMemo(atom)
|
|
215
|
+
return () => registry.refresh(memo())
|
|
144
216
|
}
|
|
145
217
|
|
|
146
218
|
/**
|
|
147
|
-
*
|
|
219
|
+
* Returns a Solid accessor for a writable atom together with a setter for
|
|
220
|
+
* updating it.
|
|
221
|
+
*
|
|
222
|
+
* **When to use**
|
|
223
|
+
*
|
|
224
|
+
* Use when a Solid component or computation needs both a reactive accessor for
|
|
225
|
+
* a writable atom and a write function for that same atom.
|
|
226
|
+
*
|
|
227
|
+
* **Details**
|
|
228
|
+
*
|
|
229
|
+
* The setter accepts either a write value or an updater function. For
|
|
230
|
+
* `AsyncResult` atoms, `promise` and `promiseExit` modes return promises for the
|
|
231
|
+
* success value or full `Exit`.
|
|
232
|
+
*
|
|
233
|
+
* @see {@link useAtomValue} for subscribing to an atom without a setter
|
|
234
|
+
* @see {@link useAtomSet} for updating a writable atom without subscribing to its value
|
|
235
|
+
*
|
|
148
236
|
* @category hooks
|
|
237
|
+
* @since 4.0.0
|
|
149
238
|
*/
|
|
150
239
|
export const useAtom = <R, W, const Mode extends "value" | "promise" | "promiseExit" = never>(
|
|
151
|
-
atom: Atom.Writable<R, W>,
|
|
240
|
+
atom: () => Atom.Writable<R, W>,
|
|
152
241
|
options?: {
|
|
153
242
|
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
|
154
243
|
}
|
|
@@ -170,38 +259,131 @@ export const useAtom = <R, W, const Mode extends "value" | "promise" | "promiseE
|
|
|
170
259
|
}
|
|
171
260
|
|
|
172
261
|
/**
|
|
173
|
-
*
|
|
262
|
+
* Subscribes a callback to an atom in the current Solid registry.
|
|
263
|
+
*
|
|
174
264
|
* @category hooks
|
|
265
|
+
* @since 4.0.0
|
|
175
266
|
*/
|
|
176
267
|
export const useAtomSubscribe = <A>(
|
|
177
|
-
atom: Atom.Atom<A>,
|
|
268
|
+
atom: () => Atom.Atom<A>,
|
|
178
269
|
f: (_: A) => void,
|
|
179
270
|
options?: { readonly immediate?: boolean }
|
|
180
271
|
): void => {
|
|
181
272
|
const registry = useContext(RegistryContext)
|
|
182
|
-
|
|
273
|
+
createEffect(() => {
|
|
274
|
+
onCleanup(registry.subscribe(atom(), f, options))
|
|
275
|
+
})
|
|
183
276
|
}
|
|
184
277
|
|
|
185
278
|
/**
|
|
186
|
-
*
|
|
279
|
+
* Converts an `AsyncResult` atom into a Solid resource.
|
|
280
|
+
*
|
|
281
|
+
* @category hooks
|
|
282
|
+
* @since 4.0.0
|
|
283
|
+
*/
|
|
284
|
+
export const useAtomResource = <A, E>(
|
|
285
|
+
atom: () => Atom.Atom<AsyncResult.AsyncResult<A, E>>,
|
|
286
|
+
options?: ResourceOptions<A> & {
|
|
287
|
+
readonly suspendOnWaiting?: boolean | undefined
|
|
288
|
+
}
|
|
289
|
+
): ResourceReturn<A, void> => {
|
|
290
|
+
const result = useAtomValue(atom)
|
|
291
|
+
return createResource(result, (result) => {
|
|
292
|
+
if (AsyncResult.isInitial(result) || (options?.suspendOnWaiting && result.waiting)) {
|
|
293
|
+
return constUnresolvedPromise
|
|
294
|
+
} else if (AsyncResult.isSuccess(result)) {
|
|
295
|
+
return Promise.resolve(result.value)
|
|
296
|
+
}
|
|
297
|
+
return Promise.reject(Cause.squash(result.cause))
|
|
298
|
+
})
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const constUnresolvedPromise = new Promise<never>(() => {})
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Subscribes to an atom ref and returns its value as a Solid accessor.
|
|
305
|
+
*
|
|
306
|
+
* **When to use**
|
|
307
|
+
*
|
|
308
|
+
* Use when a Solid component or computation should render from an
|
|
309
|
+
* `AtomRef.ReadonlyRef` directly instead of reading an atom through the current
|
|
310
|
+
* registry.
|
|
311
|
+
*
|
|
312
|
+
* **Details**
|
|
313
|
+
*
|
|
314
|
+
* The hook accepts a thunk for the ref, reads `ref().value`, subscribes with
|
|
315
|
+
* `ref.subscribe`, and releases the subscription through Solid cleanup when
|
|
316
|
+
* the selected ref changes or the owner is disposed.
|
|
317
|
+
*
|
|
318
|
+
* @see {@link useAtomValue} for reading an `Atom` from the current registry
|
|
319
|
+
* @see {@link useAtomRefPropValue} for reading a property ref value
|
|
320
|
+
*
|
|
187
321
|
* @category hooks
|
|
322
|
+
* @since 4.0.0
|
|
188
323
|
*/
|
|
189
|
-
export const useAtomRef = <A>(ref: AtomRef.ReadonlyRef<A>): Accessor<A> => {
|
|
190
|
-
const [value, setValue] = createSignal(
|
|
191
|
-
|
|
324
|
+
export const useAtomRef = <A>(ref: () => AtomRef.ReadonlyRef<A>): Accessor<A> => {
|
|
325
|
+
const [value, setValue] = createSignal(null as A)
|
|
326
|
+
createComputed(() => {
|
|
327
|
+
const r = ref()
|
|
328
|
+
setValue(r.value as any)
|
|
329
|
+
onCleanup(r.subscribe(setValue))
|
|
330
|
+
})
|
|
192
331
|
return value
|
|
193
332
|
}
|
|
194
333
|
|
|
195
334
|
/**
|
|
196
|
-
*
|
|
335
|
+
* Returns a Solid accessor for a property ref derived from an atom ref.
|
|
336
|
+
*
|
|
337
|
+
* **When to use**
|
|
338
|
+
*
|
|
339
|
+
* Use to derive an `AtomRef` for one property of an object-shaped atom ref in a
|
|
340
|
+
* Solid computation.
|
|
341
|
+
*
|
|
342
|
+
* **Details**
|
|
343
|
+
*
|
|
344
|
+
* The returned accessor memoizes `ref().prop(prop)`, updating when the source
|
|
345
|
+
* ref thunk produces a different ref.
|
|
346
|
+
*
|
|
347
|
+
* **Gotchas**
|
|
348
|
+
*
|
|
349
|
+
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
|
350
|
+
* the property key should change.
|
|
351
|
+
*
|
|
352
|
+
* @see {@link useAtomRef} for subscribing to an atom ref value
|
|
353
|
+
* @see {@link useAtomRefPropValue} for subscribing directly to a property value
|
|
354
|
+
*
|
|
197
355
|
* @category hooks
|
|
356
|
+
* @since 4.0.0
|
|
198
357
|
*/
|
|
199
|
-
export const useAtomRefProp = <A, K extends keyof A>(
|
|
200
|
-
ref
|
|
358
|
+
export const useAtomRefProp = <A, K extends keyof A>(
|
|
359
|
+
ref: () => AtomRef.AtomRef<A>,
|
|
360
|
+
prop: K
|
|
361
|
+
): Accessor<AtomRef.AtomRef<A[K]>> => createMemo(() => ref().prop(prop))
|
|
201
362
|
|
|
202
363
|
/**
|
|
203
|
-
*
|
|
364
|
+
* Returns a Solid accessor for the value of a property ref derived from an atom
|
|
365
|
+
* ref.
|
|
366
|
+
*
|
|
367
|
+
* **When to use**
|
|
368
|
+
*
|
|
369
|
+
* Use when a Solid component or computation needs the value of one property
|
|
370
|
+
* from an object-shaped `AtomRef` without keeping the intermediate property ref.
|
|
371
|
+
*
|
|
372
|
+
* **Details**
|
|
373
|
+
*
|
|
374
|
+
* The hook composes `useAtomRefProp(ref, prop)` with `useAtomRef`, returning a
|
|
375
|
+
* Solid accessor for the selected property value.
|
|
376
|
+
*
|
|
377
|
+
* **Gotchas**
|
|
378
|
+
*
|
|
379
|
+
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
|
380
|
+
* the property key should change.
|
|
381
|
+
*
|
|
382
|
+
* @see {@link useAtomRef} for subscribing to a whole atom ref value
|
|
383
|
+
* @see {@link useAtomRefProp} for returning the property ref directly
|
|
384
|
+
*
|
|
204
385
|
* @category hooks
|
|
386
|
+
* @since 4.0.0
|
|
205
387
|
*/
|
|
206
|
-
export const useAtomRefPropValue = <A, K extends keyof A>(ref: AtomRef.AtomRef<A>, prop: K): Accessor<A[K]> =>
|
|
388
|
+
export const useAtomRefPropValue = <A, K extends keyof A>(ref: () => AtomRef.AtomRef<A>, prop: K): Accessor<A[K]> =>
|
|
207
389
|
useAtomRef(useAtomRefProp(ref, prop))
|
package/src/RegistryContext.ts
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The `RegistryContext` module provides the Solid context used by Effect Atom
|
|
3
|
+
* hooks to share an `AtomRegistry` across an owner tree. The registry owns atom
|
|
4
|
+
* state, scheduling, and idle cleanup, so Solid components that read or write
|
|
5
|
+
* atoms coordinate through the same runtime instead of creating isolated
|
|
6
|
+
* registries.
|
|
7
|
+
*
|
|
8
|
+
* **Common tasks**
|
|
9
|
+
*
|
|
10
|
+
* - Use {@link RegistryProvider} to scope atom state to a Solid subtree
|
|
11
|
+
* - Seed atoms for tests, examples, or server-provided data with `initialValues`
|
|
12
|
+
* - Override scheduling or idle timing for custom rendering environments
|
|
13
|
+
* - Read {@link RegistryContext} when integrating lower-level atom APIs
|
|
14
|
+
*
|
|
15
|
+
* **Gotchas**
|
|
16
|
+
*
|
|
17
|
+
* - The provider creates a registry for the current Solid owner and disposes it
|
|
18
|
+
* with `onCleanup`
|
|
19
|
+
* - `initialValues` are applied when the provider creates the registry, not as
|
|
20
|
+
* reactive updates after creation
|
|
21
|
+
* - Overriding `scheduleTask` changes when atom work is flushed, so it should
|
|
22
|
+
* return a cancellation function that is safe to call during Solid cleanup
|
|
23
|
+
*
|
|
24
|
+
* @since 4.0.0
|
|
3
25
|
*/
|
|
4
26
|
import type * as Atom from "effect/unstable/reactivity/Atom"
|
|
5
27
|
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
|
@@ -7,14 +29,50 @@ import type { JSX } from "solid-js"
|
|
|
7
29
|
import { createComponent, createContext, onCleanup } from "solid-js"
|
|
8
30
|
|
|
9
31
|
/**
|
|
10
|
-
*
|
|
32
|
+
* A Solid context that carries the `AtomRegistry` used by atom hooks in the
|
|
33
|
+
* current owner tree.
|
|
34
|
+
*
|
|
35
|
+
* **When to use**
|
|
36
|
+
*
|
|
37
|
+
* Use when integrating lower-level Solid atom APIs that need direct access to,
|
|
38
|
+
* or direct provisioning of, the `AtomRegistry` for the current owner tree.
|
|
39
|
+
*
|
|
40
|
+
* **Details**
|
|
41
|
+
*
|
|
42
|
+
* When no provider is present, the context uses a standalone default registry.
|
|
43
|
+
*
|
|
44
|
+
* @see {@link RegistryProvider} for creating and providing a registry for a Solid subtree
|
|
45
|
+
*
|
|
11
46
|
* @category context
|
|
47
|
+
* @since 4.0.0
|
|
12
48
|
*/
|
|
13
49
|
export const RegistryContext = createContext<AtomRegistry.AtomRegistry>(AtomRegistry.make())
|
|
14
50
|
|
|
15
51
|
/**
|
|
16
|
-
*
|
|
52
|
+
* Creates an `AtomRegistry` for a Solid subtree, optionally seeding initial atom
|
|
53
|
+
* values and scheduler settings, and disposes the registry when the owner is
|
|
54
|
+
* cleaned up.
|
|
55
|
+
*
|
|
56
|
+
* **When to use**
|
|
57
|
+
*
|
|
58
|
+
* Use to scope atom state, scheduling, and cleanup to a Solid subtree.
|
|
59
|
+
*
|
|
60
|
+
* **Details**
|
|
61
|
+
*
|
|
62
|
+
* The provider creates an `AtomRegistry` with `AtomRegistry.make`, forwards
|
|
63
|
+
* `initialValues`, `scheduleTask`, `timeoutResolution`, and
|
|
64
|
+
* `defaultIdleTTL`, and supplies the registry through `RegistryContext`.
|
|
65
|
+
*
|
|
66
|
+
* **Gotchas**
|
|
67
|
+
*
|
|
68
|
+
* Provider options are consumed when the registry is created; they are not
|
|
69
|
+
* reactive updates. A custom `scheduleTask` should return a cancellation
|
|
70
|
+
* function that is safe to call during Solid cleanup.
|
|
71
|
+
*
|
|
72
|
+
* @see {@link RegistryContext} for the context supplied by this provider
|
|
73
|
+
*
|
|
17
74
|
* @category context
|
|
75
|
+
* @since 4.0.0
|
|
18
76
|
*/
|
|
19
77
|
export const RegistryProvider = (options: {
|
|
20
78
|
readonly children?: JSX.Element | undefined
|
|
@@ -27,7 +85,7 @@ export const RegistryProvider = (options: {
|
|
|
27
85
|
scheduleTask: options.scheduleTask,
|
|
28
86
|
initialValues: options.initialValues,
|
|
29
87
|
timeoutResolution: options.timeoutResolution,
|
|
30
|
-
defaultIdleTTL: options.defaultIdleTTL
|
|
88
|
+
defaultIdleTTL: options.defaultIdleTTL ?? 400
|
|
31
89
|
})
|
|
32
90
|
onCleanup(() => registry.dispose())
|
|
33
91
|
return createComponent(RegistryContext.Provider, {
|