@effect/atom-solid 4.0.0-beta.8 → 4.0.0-beta.81
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 +177 -24
- package/dist/Hooks.js.map +1 -1
- package/dist/RegistryContext.d.ts +44 -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 +208 -42
- package/src/RegistryContext.ts +45 -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,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Solid hooks for using Effect Atoms from components and computations. The
|
|
3
|
+
* hooks read and write atoms through the current `RegistryContext`, mount atoms
|
|
4
|
+
* for cleanup, subscribe callbacks, seed initial values, expose `AsyncResult`
|
|
5
|
+
* atoms as Solid resources, and read values from `AtomRef` references.
|
|
6
|
+
*
|
|
7
|
+
* @since 4.0.0
|
|
3
8
|
*/
|
|
4
9
|
import * as Cause from "effect/Cause";
|
|
5
10
|
import * as Effect from "effect/Effect";
|
|
6
11
|
import * as Exit from "effect/Exit";
|
|
12
|
+
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
|
|
7
13
|
import * as Atom from "effect/unstable/reactivity/Atom";
|
|
8
14
|
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
|
|
9
|
-
import { createSignal, onCleanup, useContext } from "solid-js";
|
|
15
|
+
import { createComputed, createEffect, createMemo, createResource, createSignal, onCleanup, useContext } from "solid-js";
|
|
10
16
|
import { RegistryContext } from "./RegistryContext.js";
|
|
11
17
|
const initialValuesSet = /*#__PURE__*/new WeakMap();
|
|
12
18
|
/**
|
|
13
|
-
*
|
|
19
|
+
* Seeds initial atom values in the current Solid atom registry.
|
|
20
|
+
*
|
|
21
|
+
* **When to use**
|
|
22
|
+
*
|
|
23
|
+
* Use to seed atom values from a Solid component after the current registry
|
|
24
|
+
* already exists.
|
|
25
|
+
*
|
|
26
|
+
* **Details**
|
|
27
|
+
*
|
|
28
|
+
* For each atom in the current registry, this hook applies the first value
|
|
29
|
+
* supplied through the hook. Later calls for the same atom in that registry are
|
|
30
|
+
* ignored.
|
|
31
|
+
*
|
|
14
32
|
* @category hooks
|
|
33
|
+
* @since 4.0.0
|
|
15
34
|
*/
|
|
16
35
|
export const useAtomInitialValues = initialValues => {
|
|
17
36
|
const registry = useContext(RegistryContext);
|
|
@@ -28,33 +47,44 @@ export const useAtomInitialValues = initialValues => {
|
|
|
28
47
|
}
|
|
29
48
|
};
|
|
30
49
|
/**
|
|
31
|
-
*
|
|
50
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
51
|
+
* a Solid accessor.
|
|
52
|
+
*
|
|
32
53
|
* @category hooks
|
|
54
|
+
* @since 4.0.0
|
|
33
55
|
*/
|
|
34
56
|
export const useAtomValue = (atom, f) => {
|
|
35
57
|
const registry = useContext(RegistryContext);
|
|
36
|
-
return createAtomAccessor(registry, f ? Atom.map(atom, f) : atom);
|
|
58
|
+
return createAtomAccessor(registry, f ? () => Atom.map(atom(), f) : atom);
|
|
37
59
|
};
|
|
38
60
|
function createAtomAccessor(registry, atom) {
|
|
39
|
-
const [value, setValue] = createSignal(
|
|
40
|
-
|
|
61
|
+
const [value, setValue] = createSignal(null);
|
|
62
|
+
createComputed(() => {
|
|
63
|
+
onCleanup(registry.subscribe(atom(), setValue, constImmediate));
|
|
64
|
+
});
|
|
41
65
|
return value;
|
|
42
66
|
}
|
|
67
|
+
const constImmediate = {
|
|
68
|
+
immediate: true
|
|
69
|
+
};
|
|
43
70
|
function mountAtom(registry, atom) {
|
|
44
|
-
|
|
71
|
+
createComputed(() => {
|
|
72
|
+
onCleanup(registry.mount(atom()));
|
|
73
|
+
});
|
|
45
74
|
}
|
|
46
75
|
function setAtom(registry, atom, options) {
|
|
76
|
+
const memo = createMemo(atom);
|
|
47
77
|
if (options?.mode === "promise" || options?.mode === "promiseExit") {
|
|
48
78
|
return value => {
|
|
49
|
-
registry.set(
|
|
50
|
-
const promise = Effect.runPromiseExit(AtomRegistry.getResult(registry,
|
|
79
|
+
registry.set(memo(), value);
|
|
80
|
+
const promise = Effect.runPromiseExit(AtomRegistry.getResult(registry, memo(), {
|
|
51
81
|
suspendOnWaiting: true
|
|
52
82
|
}));
|
|
53
83
|
return options.mode === "promise" ? promise.then(flattenExit) : promise;
|
|
54
84
|
};
|
|
55
85
|
}
|
|
56
86
|
return value => {
|
|
57
|
-
registry.set(
|
|
87
|
+
registry.set(memo(), typeof value === "function" ? value(registry.get(memo())) : value);
|
|
58
88
|
};
|
|
59
89
|
}
|
|
60
90
|
const flattenExit = exit => {
|
|
@@ -62,16 +92,35 @@ const flattenExit = exit => {
|
|
|
62
92
|
throw Cause.squash(exit.cause);
|
|
63
93
|
};
|
|
64
94
|
/**
|
|
65
|
-
*
|
|
95
|
+
* Mounts an atom in the current Solid registry for the lifetime of the current
|
|
96
|
+
* Solid computation.
|
|
97
|
+
*
|
|
98
|
+
* **When to use**
|
|
99
|
+
*
|
|
100
|
+
* Use to keep an atom mounted from a Solid owner without reading, writing, or
|
|
101
|
+
* refreshing it.
|
|
102
|
+
*
|
|
103
|
+
* **Details**
|
|
104
|
+
*
|
|
105
|
+
* The hook uses the current `RegistryContext`, mounts inside a Solid
|
|
106
|
+
* computation, and releases the mount through Solid cleanup when the
|
|
107
|
+
* computation changes or the owner is disposed.
|
|
108
|
+
*
|
|
109
|
+
* @see {@link useAtomSet} for mounting a writable atom while returning a setter
|
|
110
|
+
* @see {@link useAtomRefresh} for mounting an atom while returning a refresh callback
|
|
111
|
+
*
|
|
66
112
|
* @category hooks
|
|
113
|
+
* @since 4.0.0
|
|
67
114
|
*/
|
|
68
115
|
export const useAtomMount = atom => {
|
|
69
116
|
const registry = useContext(RegistryContext);
|
|
70
117
|
mountAtom(registry, atom);
|
|
71
118
|
};
|
|
72
119
|
/**
|
|
73
|
-
*
|
|
120
|
+
* Returns a setter for a writable atom without subscribing to its value.
|
|
121
|
+
*
|
|
74
122
|
* @category hooks
|
|
123
|
+
* @since 4.0.0
|
|
75
124
|
*/
|
|
76
125
|
export const useAtomSet = (atom, options) => {
|
|
77
126
|
const registry = useContext(RegistryContext);
|
|
@@ -79,47 +128,151 @@ export const useAtomSet = (atom, options) => {
|
|
|
79
128
|
return setAtom(registry, atom, options);
|
|
80
129
|
};
|
|
81
130
|
/**
|
|
82
|
-
*
|
|
131
|
+
* Mounts an atom and returns a callback that refreshes the current atom.
|
|
132
|
+
*
|
|
83
133
|
* @category hooks
|
|
134
|
+
* @since 4.0.0
|
|
84
135
|
*/
|
|
85
136
|
export const useAtomRefresh = atom => {
|
|
86
137
|
const registry = useContext(RegistryContext);
|
|
87
138
|
mountAtom(registry, atom);
|
|
88
|
-
|
|
139
|
+
const memo = createMemo(atom);
|
|
140
|
+
return () => registry.refresh(memo());
|
|
89
141
|
};
|
|
90
142
|
/**
|
|
91
|
-
*
|
|
143
|
+
* Returns a Solid accessor for a writable atom together with a setter for
|
|
144
|
+
* updating it.
|
|
145
|
+
*
|
|
146
|
+
* **When to use**
|
|
147
|
+
*
|
|
148
|
+
* Use when a Solid component or computation needs both a reactive accessor for
|
|
149
|
+
* a writable atom and a write function for that same atom.
|
|
150
|
+
*
|
|
151
|
+
* **Details**
|
|
152
|
+
*
|
|
153
|
+
* The setter accepts either a write value or an updater function. For
|
|
154
|
+
* `AsyncResult` atoms, `promise` and `promiseExit` modes return promises for the
|
|
155
|
+
* success value or full `Exit`.
|
|
156
|
+
*
|
|
157
|
+
* @see {@link useAtomValue} for subscribing to an atom without a setter
|
|
158
|
+
* @see {@link useAtomSet} for updating a writable atom without subscribing to its value
|
|
159
|
+
*
|
|
92
160
|
* @category hooks
|
|
161
|
+
* @since 4.0.0
|
|
93
162
|
*/
|
|
94
163
|
export const useAtom = (atom, options) => {
|
|
95
164
|
const registry = useContext(RegistryContext);
|
|
96
165
|
return [createAtomAccessor(registry, atom), setAtom(registry, atom, options)];
|
|
97
166
|
};
|
|
98
167
|
/**
|
|
99
|
-
*
|
|
168
|
+
* Subscribes a callback to an atom in the current Solid registry.
|
|
169
|
+
*
|
|
100
170
|
* @category hooks
|
|
171
|
+
* @since 4.0.0
|
|
101
172
|
*/
|
|
102
173
|
export const useAtomSubscribe = (atom, f, options) => {
|
|
103
174
|
const registry = useContext(RegistryContext);
|
|
104
|
-
|
|
175
|
+
createEffect(() => {
|
|
176
|
+
onCleanup(registry.subscribe(atom(), f, options));
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* Converts an `AsyncResult` atom into a Solid resource.
|
|
181
|
+
*
|
|
182
|
+
* @category hooks
|
|
183
|
+
* @since 4.0.0
|
|
184
|
+
*/
|
|
185
|
+
export const useAtomResource = (atom, options) => {
|
|
186
|
+
const result = useAtomValue(atom);
|
|
187
|
+
return createResource(result, result => {
|
|
188
|
+
if (AsyncResult.isInitial(result) || options?.suspendOnWaiting && result.waiting) {
|
|
189
|
+
return constUnresolvedPromise;
|
|
190
|
+
} else if (AsyncResult.isSuccess(result)) {
|
|
191
|
+
return Promise.resolve(result.value);
|
|
192
|
+
}
|
|
193
|
+
return Promise.reject(Cause.squash(result.cause));
|
|
194
|
+
});
|
|
105
195
|
};
|
|
196
|
+
const constUnresolvedPromise = /*#__PURE__*/new Promise(() => {});
|
|
106
197
|
/**
|
|
107
|
-
*
|
|
198
|
+
* Subscribes to an atom ref and returns its value as a Solid accessor.
|
|
199
|
+
*
|
|
200
|
+
* **When to use**
|
|
201
|
+
*
|
|
202
|
+
* Use when a Solid component or computation should render from an
|
|
203
|
+
* `AtomRef.ReadonlyRef` directly instead of reading an atom through the current
|
|
204
|
+
* registry.
|
|
205
|
+
*
|
|
206
|
+
* **Details**
|
|
207
|
+
*
|
|
208
|
+
* The hook accepts a thunk for the ref, reads `ref().value`, subscribes with
|
|
209
|
+
* `ref.subscribe`, and releases the subscription through Solid cleanup when
|
|
210
|
+
* the selected ref changes or the owner is disposed.
|
|
211
|
+
*
|
|
212
|
+
* @see {@link useAtomValue} for reading an `Atom` from the current registry
|
|
213
|
+
* @see {@link useAtomRefPropValue} for reading a property ref value
|
|
214
|
+
*
|
|
108
215
|
* @category hooks
|
|
216
|
+
* @since 4.0.0
|
|
109
217
|
*/
|
|
110
218
|
export const useAtomRef = ref => {
|
|
111
|
-
const [value, setValue] = createSignal(
|
|
112
|
-
|
|
219
|
+
const [value, setValue] = createSignal(null);
|
|
220
|
+
createComputed(() => {
|
|
221
|
+
const r = ref();
|
|
222
|
+
setValue(r.value);
|
|
223
|
+
onCleanup(r.subscribe(setValue));
|
|
224
|
+
});
|
|
113
225
|
return value;
|
|
114
226
|
};
|
|
115
227
|
/**
|
|
116
|
-
*
|
|
228
|
+
* Returns a Solid accessor for a property ref derived from an atom ref.
|
|
229
|
+
*
|
|
230
|
+
* **When to use**
|
|
231
|
+
*
|
|
232
|
+
* Use to derive an `AtomRef` for one property of an object-shaped atom ref in a
|
|
233
|
+
* Solid computation.
|
|
234
|
+
*
|
|
235
|
+
* **Details**
|
|
236
|
+
*
|
|
237
|
+
* The returned accessor memoizes `ref().prop(prop)`, updating when the source
|
|
238
|
+
* ref thunk produces a different ref.
|
|
239
|
+
*
|
|
240
|
+
* **Gotchas**
|
|
241
|
+
*
|
|
242
|
+
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
|
243
|
+
* the property key should change.
|
|
244
|
+
*
|
|
245
|
+
* @see {@link useAtomRef} for subscribing to an atom ref value
|
|
246
|
+
* @see {@link useAtomRefPropValue} for subscribing directly to a property value
|
|
247
|
+
*
|
|
117
248
|
* @category hooks
|
|
249
|
+
* @since 4.0.0
|
|
118
250
|
*/
|
|
119
|
-
export const useAtomRefProp = (ref, prop) => ref.prop(prop);
|
|
251
|
+
export const useAtomRefProp = (ref, prop) => createMemo(() => ref().prop(prop));
|
|
120
252
|
/**
|
|
121
|
-
*
|
|
253
|
+
* Returns a Solid accessor for the value of a property ref derived from an atom
|
|
254
|
+
* ref.
|
|
255
|
+
*
|
|
256
|
+
* **When to use**
|
|
257
|
+
*
|
|
258
|
+
* Use when a Solid component or computation needs the value of one property
|
|
259
|
+
* from an object-shaped `AtomRef` without keeping the intermediate property ref.
|
|
260
|
+
*
|
|
261
|
+
* **Details**
|
|
262
|
+
*
|
|
263
|
+
* The hook composes `useAtomRefProp(ref, prop)` with `useAtomRef`, returning a
|
|
264
|
+
* Solid accessor for the selected property value.
|
|
265
|
+
*
|
|
266
|
+
* **Gotchas**
|
|
267
|
+
*
|
|
268
|
+
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
|
269
|
+
* the property key should change.
|
|
270
|
+
*
|
|
271
|
+
* @see {@link useAtomRef} for subscribing to a whole atom ref value
|
|
272
|
+
* @see {@link useAtomRefProp} for returning the property ref directly
|
|
273
|
+
*
|
|
122
274
|
* @category hooks
|
|
275
|
+
* @since 4.0.0
|
|
123
276
|
*/
|
|
124
277
|
export const useAtomRefPropValue = (ref, prop) => useAtomRef(useAtomRefProp(ref, prop));
|
|
125
278
|
//# 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,58 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Solid context and provider for the Atom registry used by Effect Atom hooks.
|
|
3
|
+
* The registry stores atom values, schedules update work, and cleans up unused
|
|
4
|
+
* atoms. Sharing one registry through Solid context lets components and
|
|
5
|
+
* computations in the same owner tree read and write the same atom state.
|
|
6
|
+
*
|
|
7
|
+
* @since 4.0.0
|
|
3
8
|
*/
|
|
4
9
|
import type * as Atom from "effect/unstable/reactivity/Atom";
|
|
5
10
|
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
|
|
6
11
|
import type { JSX } from "solid-js";
|
|
7
12
|
/**
|
|
8
|
-
*
|
|
13
|
+
* Provides a Solid context that carries the `AtomRegistry` used by atom hooks in the
|
|
14
|
+
* current owner tree.
|
|
15
|
+
*
|
|
16
|
+
* **When to use**
|
|
17
|
+
*
|
|
18
|
+
* Use when you need to integrate lower-level Solid context APIs, such as custom
|
|
19
|
+
* providers or hooks, instead of using the default atom hook setup.
|
|
20
|
+
*
|
|
21
|
+
* **Details**
|
|
22
|
+
*
|
|
23
|
+
* When no provider is present, the context uses a standalone default registry.
|
|
24
|
+
*
|
|
25
|
+
* @see {@link RegistryProvider} for creating and providing a registry for a Solid subtree
|
|
26
|
+
*
|
|
9
27
|
* @category context
|
|
28
|
+
* @since 4.0.0
|
|
10
29
|
*/
|
|
11
30
|
export declare const RegistryContext: import("solid-js").Context<AtomRegistry.AtomRegistry>;
|
|
12
31
|
/**
|
|
13
|
-
*
|
|
32
|
+
* Creates an `AtomRegistry` for a Solid subtree, optionally seeding initial atom
|
|
33
|
+
* values and scheduler settings, and disposes the registry when the owner is
|
|
34
|
+
* cleaned up.
|
|
35
|
+
*
|
|
36
|
+
* **When to use**
|
|
37
|
+
*
|
|
38
|
+
* Use to scope atom state, scheduling, and cleanup to a Solid subtree.
|
|
39
|
+
*
|
|
40
|
+
* **Details**
|
|
41
|
+
*
|
|
42
|
+
* The provider creates an `AtomRegistry` with `AtomRegistry.make`, forwards
|
|
43
|
+
* `initialValues`, `scheduleTask`, `timeoutResolution`, and
|
|
44
|
+
* `defaultIdleTTL`, and supplies the registry through `RegistryContext`.
|
|
45
|
+
*
|
|
46
|
+
* **Gotchas**
|
|
47
|
+
*
|
|
48
|
+
* Provider options are consumed when the registry is created; they are not
|
|
49
|
+
* reactive updates. A custom `scheduleTask` should return a cancellation
|
|
50
|
+
* function that is safe to call during Solid cleanup.
|
|
51
|
+
*
|
|
52
|
+
* @see {@link RegistryContext} for the context supplied by this provider
|
|
53
|
+
*
|
|
14
54
|
* @category context
|
|
55
|
+
* @since 4.0.0
|
|
15
56
|
*/
|
|
16
57
|
export declare const RegistryProvider: (options: {
|
|
17
58
|
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;;;;;;;GAOG;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
|
+
* Provides 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 you need to integrate lower-level Solid context APIs, such as custom
|
|
10
|
+
* providers or hooks, instead of using the default atom hook setup.
|
|
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":"AASA,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.81",
|
|
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.81"
|
|
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.81"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "tsc -b tsconfig.json && pnpm babel",
|
package/src/Hooks.ts
CHANGED
|
@@ -1,22 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Solid hooks for using Effect Atoms from components and computations. The
|
|
3
|
+
* hooks read and write atoms through the current `RegistryContext`, mount atoms
|
|
4
|
+
* for cleanup, subscribe callbacks, seed initial values, expose `AsyncResult`
|
|
5
|
+
* atoms as Solid resources, and read values from `AtomRef` references.
|
|
6
|
+
*
|
|
7
|
+
* @since 4.0.0
|
|
3
8
|
*/
|
|
4
9
|
import * as Cause from "effect/Cause"
|
|
5
10
|
import * as Effect from "effect/Effect"
|
|
6
11
|
import * as Exit from "effect/Exit"
|
|
7
|
-
import
|
|
12
|
+
import * as AsyncResult from "effect/unstable/reactivity/AsyncResult"
|
|
8
13
|
import * as Atom from "effect/unstable/reactivity/Atom"
|
|
9
14
|
import type * as AtomRef from "effect/unstable/reactivity/AtomRef"
|
|
10
15
|
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
|
11
|
-
import type { Accessor } from "solid-js"
|
|
12
|
-
import { createSignal, onCleanup, useContext } from "solid-js"
|
|
16
|
+
import type { Accessor, ResourceOptions, ResourceReturn } from "solid-js"
|
|
17
|
+
import { createComputed, createEffect, createMemo, createResource, createSignal, onCleanup, useContext } from "solid-js"
|
|
13
18
|
import { RegistryContext } from "./RegistryContext.ts"
|
|
14
19
|
|
|
15
20
|
const initialValuesSet = new WeakMap<AtomRegistry.AtomRegistry, WeakSet<Atom.Atom<any>>>()
|
|
16
21
|
|
|
17
22
|
/**
|
|
18
|
-
*
|
|
23
|
+
* Seeds initial atom values in the current Solid atom registry.
|
|
24
|
+
*
|
|
25
|
+
* **When to use**
|
|
26
|
+
*
|
|
27
|
+
* Use to seed atom values from a Solid component after the current registry
|
|
28
|
+
* already exists.
|
|
29
|
+
*
|
|
30
|
+
* **Details**
|
|
31
|
+
*
|
|
32
|
+
* For each atom in the current registry, this hook applies the first value
|
|
33
|
+
* supplied through the hook. Later calls for the same atom in that registry are
|
|
34
|
+
* ignored.
|
|
35
|
+
*
|
|
19
36
|
* @category hooks
|
|
37
|
+
* @since 4.0.0
|
|
20
38
|
*/
|
|
21
39
|
export const useAtomInitialValues = (initialValues: Iterable<readonly [Atom.Atom<any>, any]>): void => {
|
|
22
40
|
const registry = useContext(RegistryContext)
|
|
@@ -34,38 +52,53 @@ export const useAtomInitialValues = (initialValues: Iterable<readonly [Atom.Atom
|
|
|
34
52
|
}
|
|
35
53
|
|
|
36
54
|
/**
|
|
37
|
-
*
|
|
55
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
56
|
+
* a Solid accessor.
|
|
57
|
+
*
|
|
38
58
|
* @category hooks
|
|
59
|
+
* @since 4.0.0
|
|
39
60
|
*/
|
|
40
61
|
export const useAtomValue: {
|
|
41
62
|
/**
|
|
42
|
-
*
|
|
63
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
64
|
+
* a Solid accessor.
|
|
65
|
+
*
|
|
43
66
|
* @category hooks
|
|
67
|
+
* @since 4.0.0
|
|
44
68
|
*/
|
|
45
|
-
<A>(atom: Atom.Atom<A>): Accessor<A>
|
|
69
|
+
<A>(atom: () => Atom.Atom<A>): Accessor<A>
|
|
46
70
|
/**
|
|
47
|
-
*
|
|
71
|
+
* Subscribes to an atom in the current Solid registry and returns its value as
|
|
72
|
+
* a Solid accessor.
|
|
73
|
+
*
|
|
48
74
|
* @category hooks
|
|
75
|
+
* @since 4.0.0
|
|
49
76
|
*/
|
|
50
|
-
<A, B>(atom: Atom.Atom<A>, f: (_: A) => B): Accessor<B>
|
|
51
|
-
} = <A>(atom: Atom.Atom<A>, f?: (_: A) => A): Accessor<A> => {
|
|
77
|
+
<A, B>(atom: () => Atom.Atom<A>, f: (_: A) => B): Accessor<B>
|
|
78
|
+
} = <A>(atom: () => Atom.Atom<A>, f?: (_: A) => A): Accessor<A> => {
|
|
52
79
|
const registry = useContext(RegistryContext)
|
|
53
|
-
return createAtomAccessor(registry, f ? Atom.map(atom, f) : atom)
|
|
80
|
+
return createAtomAccessor(registry, f ? () => Atom.map(atom(), f) : atom)
|
|
54
81
|
}
|
|
55
82
|
|
|
56
|
-
function createAtomAccessor<A>(registry: AtomRegistry.AtomRegistry, atom: Atom.Atom<A>): Accessor<A> {
|
|
57
|
-
const [value, setValue] = createSignal<A>(
|
|
58
|
-
|
|
83
|
+
function createAtomAccessor<A>(registry: AtomRegistry.AtomRegistry, atom: () => Atom.Atom<A>): Accessor<A> {
|
|
84
|
+
const [value, setValue] = createSignal<A>(null as any)
|
|
85
|
+
createComputed(() => {
|
|
86
|
+
onCleanup(registry.subscribe(atom(), setValue as any, constImmediate))
|
|
87
|
+
})
|
|
59
88
|
return value
|
|
60
89
|
}
|
|
61
90
|
|
|
62
|
-
|
|
63
|
-
|
|
91
|
+
const constImmediate = { immediate: true }
|
|
92
|
+
|
|
93
|
+
function mountAtom<A>(registry: AtomRegistry.AtomRegistry, atom: () => Atom.Atom<A>): void {
|
|
94
|
+
createComputed(() => {
|
|
95
|
+
onCleanup(registry.mount(atom()))
|
|
96
|
+
})
|
|
64
97
|
}
|
|
65
98
|
|
|
66
99
|
function setAtom<R, W, Mode extends "value" | "promise" | "promiseExit" = never>(
|
|
67
100
|
registry: AtomRegistry.AtomRegistry,
|
|
68
|
-
atom: Atom.Writable<R, W>,
|
|
101
|
+
atom: () => Atom.Writable<R, W>,
|
|
69
102
|
options?: {
|
|
70
103
|
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
|
71
104
|
}
|
|
@@ -77,11 +110,12 @@ function setAtom<R, W, Mode extends "value" | "promise" | "promiseExit" = never>
|
|
|
77
110
|
) :
|
|
78
111
|
((value: W | ((value: R) => W)) => void)
|
|
79
112
|
{
|
|
113
|
+
const memo = createMemo(atom)
|
|
80
114
|
if (options?.mode === "promise" || options?.mode === "promiseExit") {
|
|
81
115
|
return ((value: W) => {
|
|
82
|
-
registry.set(
|
|
116
|
+
registry.set(memo(), value)
|
|
83
117
|
const promise = Effect.runPromiseExit(
|
|
84
|
-
AtomRegistry.getResult(registry,
|
|
118
|
+
AtomRegistry.getResult(registry, memo() as Atom.Atom<AsyncResult.AsyncResult<any, any>>, {
|
|
85
119
|
suspendOnWaiting: true
|
|
86
120
|
})
|
|
87
121
|
)
|
|
@@ -89,7 +123,7 @@ function setAtom<R, W, Mode extends "value" | "promise" | "promiseExit" = never>
|
|
|
89
123
|
}) as any
|
|
90
124
|
}
|
|
91
125
|
return ((value: W | ((value: R) => W)) => {
|
|
92
|
-
registry.set(
|
|
126
|
+
registry.set(memo(), typeof value === "function" ? (value as any)(registry.get(memo())) : value)
|
|
93
127
|
}) as any
|
|
94
128
|
}
|
|
95
129
|
|
|
@@ -99,24 +133,43 @@ const flattenExit = <A, E>(exit: Exit.Exit<A, E>): A => {
|
|
|
99
133
|
}
|
|
100
134
|
|
|
101
135
|
/**
|
|
102
|
-
*
|
|
136
|
+
* Mounts an atom in the current Solid registry for the lifetime of the current
|
|
137
|
+
* Solid computation.
|
|
138
|
+
*
|
|
139
|
+
* **When to use**
|
|
140
|
+
*
|
|
141
|
+
* Use to keep an atom mounted from a Solid owner without reading, writing, or
|
|
142
|
+
* refreshing it.
|
|
143
|
+
*
|
|
144
|
+
* **Details**
|
|
145
|
+
*
|
|
146
|
+
* The hook uses the current `RegistryContext`, mounts inside a Solid
|
|
147
|
+
* computation, and releases the mount through Solid cleanup when the
|
|
148
|
+
* computation changes or the owner is disposed.
|
|
149
|
+
*
|
|
150
|
+
* @see {@link useAtomSet} for mounting a writable atom while returning a setter
|
|
151
|
+
* @see {@link useAtomRefresh} for mounting an atom while returning a refresh callback
|
|
152
|
+
*
|
|
103
153
|
* @category hooks
|
|
154
|
+
* @since 4.0.0
|
|
104
155
|
*/
|
|
105
|
-
export const useAtomMount = <A>(atom: Atom.Atom<A>): void => {
|
|
156
|
+
export const useAtomMount = <A>(atom: () => Atom.Atom<A>): void => {
|
|
106
157
|
const registry = useContext(RegistryContext)
|
|
107
158
|
mountAtom(registry, atom)
|
|
108
159
|
}
|
|
109
160
|
|
|
110
161
|
/**
|
|
111
|
-
*
|
|
162
|
+
* Returns a setter for a writable atom without subscribing to its value.
|
|
163
|
+
*
|
|
112
164
|
* @category hooks
|
|
165
|
+
* @since 4.0.0
|
|
113
166
|
*/
|
|
114
167
|
export const useAtomSet = <
|
|
115
168
|
R,
|
|
116
169
|
W,
|
|
117
170
|
Mode extends "value" | "promise" | "promiseExit" = never
|
|
118
171
|
>(
|
|
119
|
-
atom: Atom.Writable<R, W>,
|
|
172
|
+
atom: () => Atom.Writable<R, W>,
|
|
120
173
|
options?: {
|
|
121
174
|
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
|
122
175
|
}
|
|
@@ -134,21 +187,41 @@ export const useAtomSet = <
|
|
|
134
187
|
}
|
|
135
188
|
|
|
136
189
|
/**
|
|
137
|
-
*
|
|
190
|
+
* Mounts an atom and returns a callback that refreshes the current atom.
|
|
191
|
+
*
|
|
138
192
|
* @category hooks
|
|
193
|
+
* @since 4.0.0
|
|
139
194
|
*/
|
|
140
|
-
export const useAtomRefresh = <A>(atom: Atom.Atom<A>): () => void => {
|
|
195
|
+
export const useAtomRefresh = <A>(atom: () => Atom.Atom<A>): () => void => {
|
|
141
196
|
const registry = useContext(RegistryContext)
|
|
142
197
|
mountAtom(registry, atom)
|
|
143
|
-
|
|
198
|
+
const memo = createMemo(atom)
|
|
199
|
+
return () => registry.refresh(memo())
|
|
144
200
|
}
|
|
145
201
|
|
|
146
202
|
/**
|
|
147
|
-
*
|
|
203
|
+
* Returns a Solid accessor for a writable atom together with a setter for
|
|
204
|
+
* updating it.
|
|
205
|
+
*
|
|
206
|
+
* **When to use**
|
|
207
|
+
*
|
|
208
|
+
* Use when a Solid component or computation needs both a reactive accessor for
|
|
209
|
+
* a writable atom and a write function for that same atom.
|
|
210
|
+
*
|
|
211
|
+
* **Details**
|
|
212
|
+
*
|
|
213
|
+
* The setter accepts either a write value or an updater function. For
|
|
214
|
+
* `AsyncResult` atoms, `promise` and `promiseExit` modes return promises for the
|
|
215
|
+
* success value or full `Exit`.
|
|
216
|
+
*
|
|
217
|
+
* @see {@link useAtomValue} for subscribing to an atom without a setter
|
|
218
|
+
* @see {@link useAtomSet} for updating a writable atom without subscribing to its value
|
|
219
|
+
*
|
|
148
220
|
* @category hooks
|
|
221
|
+
* @since 4.0.0
|
|
149
222
|
*/
|
|
150
223
|
export const useAtom = <R, W, const Mode extends "value" | "promise" | "promiseExit" = never>(
|
|
151
|
-
atom: Atom.Writable<R, W>,
|
|
224
|
+
atom: () => Atom.Writable<R, W>,
|
|
152
225
|
options?: {
|
|
153
226
|
readonly mode?: ([R] extends [AsyncResult.AsyncResult<any, any>] ? Mode : "value") | undefined
|
|
154
227
|
}
|
|
@@ -170,38 +243,131 @@ export const useAtom = <R, W, const Mode extends "value" | "promise" | "promiseE
|
|
|
170
243
|
}
|
|
171
244
|
|
|
172
245
|
/**
|
|
173
|
-
*
|
|
246
|
+
* Subscribes a callback to an atom in the current Solid registry.
|
|
247
|
+
*
|
|
174
248
|
* @category hooks
|
|
249
|
+
* @since 4.0.0
|
|
175
250
|
*/
|
|
176
251
|
export const useAtomSubscribe = <A>(
|
|
177
|
-
atom: Atom.Atom<A>,
|
|
252
|
+
atom: () => Atom.Atom<A>,
|
|
178
253
|
f: (_: A) => void,
|
|
179
254
|
options?: { readonly immediate?: boolean }
|
|
180
255
|
): void => {
|
|
181
256
|
const registry = useContext(RegistryContext)
|
|
182
|
-
|
|
257
|
+
createEffect(() => {
|
|
258
|
+
onCleanup(registry.subscribe(atom(), f, options))
|
|
259
|
+
})
|
|
183
260
|
}
|
|
184
261
|
|
|
185
262
|
/**
|
|
186
|
-
*
|
|
263
|
+
* Converts an `AsyncResult` atom into a Solid resource.
|
|
264
|
+
*
|
|
265
|
+
* @category hooks
|
|
266
|
+
* @since 4.0.0
|
|
267
|
+
*/
|
|
268
|
+
export const useAtomResource = <A, E>(
|
|
269
|
+
atom: () => Atom.Atom<AsyncResult.AsyncResult<A, E>>,
|
|
270
|
+
options?: ResourceOptions<A> & {
|
|
271
|
+
readonly suspendOnWaiting?: boolean | undefined
|
|
272
|
+
}
|
|
273
|
+
): ResourceReturn<A, void> => {
|
|
274
|
+
const result = useAtomValue(atom)
|
|
275
|
+
return createResource(result, (result) => {
|
|
276
|
+
if (AsyncResult.isInitial(result) || (options?.suspendOnWaiting && result.waiting)) {
|
|
277
|
+
return constUnresolvedPromise
|
|
278
|
+
} else if (AsyncResult.isSuccess(result)) {
|
|
279
|
+
return Promise.resolve(result.value)
|
|
280
|
+
}
|
|
281
|
+
return Promise.reject(Cause.squash(result.cause))
|
|
282
|
+
})
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const constUnresolvedPromise = new Promise<never>(() => {})
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Subscribes to an atom ref and returns its value as a Solid accessor.
|
|
289
|
+
*
|
|
290
|
+
* **When to use**
|
|
291
|
+
*
|
|
292
|
+
* Use when a Solid component or computation should render from an
|
|
293
|
+
* `AtomRef.ReadonlyRef` directly instead of reading an atom through the current
|
|
294
|
+
* registry.
|
|
295
|
+
*
|
|
296
|
+
* **Details**
|
|
297
|
+
*
|
|
298
|
+
* The hook accepts a thunk for the ref, reads `ref().value`, subscribes with
|
|
299
|
+
* `ref.subscribe`, and releases the subscription through Solid cleanup when
|
|
300
|
+
* the selected ref changes or the owner is disposed.
|
|
301
|
+
*
|
|
302
|
+
* @see {@link useAtomValue} for reading an `Atom` from the current registry
|
|
303
|
+
* @see {@link useAtomRefPropValue} for reading a property ref value
|
|
304
|
+
*
|
|
187
305
|
* @category hooks
|
|
306
|
+
* @since 4.0.0
|
|
188
307
|
*/
|
|
189
|
-
export const useAtomRef = <A>(ref: AtomRef.ReadonlyRef<A>): Accessor<A> => {
|
|
190
|
-
const [value, setValue] = createSignal(
|
|
191
|
-
|
|
308
|
+
export const useAtomRef = <A>(ref: () => AtomRef.ReadonlyRef<A>): Accessor<A> => {
|
|
309
|
+
const [value, setValue] = createSignal(null as A)
|
|
310
|
+
createComputed(() => {
|
|
311
|
+
const r = ref()
|
|
312
|
+
setValue(r.value as any)
|
|
313
|
+
onCleanup(r.subscribe(setValue))
|
|
314
|
+
})
|
|
192
315
|
return value
|
|
193
316
|
}
|
|
194
317
|
|
|
195
318
|
/**
|
|
196
|
-
*
|
|
319
|
+
* Returns a Solid accessor for a property ref derived from an atom ref.
|
|
320
|
+
*
|
|
321
|
+
* **When to use**
|
|
322
|
+
*
|
|
323
|
+
* Use to derive an `AtomRef` for one property of an object-shaped atom ref in a
|
|
324
|
+
* Solid computation.
|
|
325
|
+
*
|
|
326
|
+
* **Details**
|
|
327
|
+
*
|
|
328
|
+
* The returned accessor memoizes `ref().prop(prop)`, updating when the source
|
|
329
|
+
* ref thunk produces a different ref.
|
|
330
|
+
*
|
|
331
|
+
* **Gotchas**
|
|
332
|
+
*
|
|
333
|
+
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
|
334
|
+
* the property key should change.
|
|
335
|
+
*
|
|
336
|
+
* @see {@link useAtomRef} for subscribing to an atom ref value
|
|
337
|
+
* @see {@link useAtomRefPropValue} for subscribing directly to a property value
|
|
338
|
+
*
|
|
197
339
|
* @category hooks
|
|
340
|
+
* @since 4.0.0
|
|
198
341
|
*/
|
|
199
|
-
export const useAtomRefProp = <A, K extends keyof A>(
|
|
200
|
-
ref
|
|
342
|
+
export const useAtomRefProp = <A, K extends keyof A>(
|
|
343
|
+
ref: () => AtomRef.AtomRef<A>,
|
|
344
|
+
prop: K
|
|
345
|
+
): Accessor<AtomRef.AtomRef<A[K]>> => createMemo(() => ref().prop(prop))
|
|
201
346
|
|
|
202
347
|
/**
|
|
203
|
-
*
|
|
348
|
+
* Returns a Solid accessor for the value of a property ref derived from an atom
|
|
349
|
+
* ref.
|
|
350
|
+
*
|
|
351
|
+
* **When to use**
|
|
352
|
+
*
|
|
353
|
+
* Use when a Solid component or computation needs the value of one property
|
|
354
|
+
* from an object-shaped `AtomRef` without keeping the intermediate property ref.
|
|
355
|
+
*
|
|
356
|
+
* **Details**
|
|
357
|
+
*
|
|
358
|
+
* The hook composes `useAtomRefProp(ref, prop)` with `useAtomRef`, returning a
|
|
359
|
+
* Solid accessor for the selected property value.
|
|
360
|
+
*
|
|
361
|
+
* **Gotchas**
|
|
362
|
+
*
|
|
363
|
+
* The `prop` argument is captured as a plain value. Recreate the hook call when
|
|
364
|
+
* the property key should change.
|
|
365
|
+
*
|
|
366
|
+
* @see {@link useAtomRef} for subscribing to a whole atom ref value
|
|
367
|
+
* @see {@link useAtomRefProp} for returning the property ref directly
|
|
368
|
+
*
|
|
204
369
|
* @category hooks
|
|
370
|
+
* @since 4.0.0
|
|
205
371
|
*/
|
|
206
|
-
export const useAtomRefPropValue = <A, K extends keyof A>(ref: AtomRef.AtomRef<A>, prop: K): Accessor<A[K]> =>
|
|
372
|
+
export const useAtomRefPropValue = <A, K extends keyof A>(ref: () => AtomRef.AtomRef<A>, prop: K): Accessor<A[K]> =>
|
|
207
373
|
useAtomRef(useAtomRefProp(ref, prop))
|
package/src/RegistryContext.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Solid context and provider for the Atom registry used by Effect Atom hooks.
|
|
3
|
+
* The registry stores atom values, schedules update work, and cleans up unused
|
|
4
|
+
* atoms. Sharing one registry through Solid context lets components and
|
|
5
|
+
* computations in the same owner tree read and write the same atom state.
|
|
6
|
+
*
|
|
7
|
+
* @since 4.0.0
|
|
3
8
|
*/
|
|
4
9
|
import type * as Atom from "effect/unstable/reactivity/Atom"
|
|
5
10
|
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry"
|
|
@@ -7,14 +12,50 @@ import type { JSX } from "solid-js"
|
|
|
7
12
|
import { createComponent, createContext, onCleanup } from "solid-js"
|
|
8
13
|
|
|
9
14
|
/**
|
|
10
|
-
*
|
|
15
|
+
* Provides a Solid context that carries the `AtomRegistry` used by atom hooks in the
|
|
16
|
+
* current owner tree.
|
|
17
|
+
*
|
|
18
|
+
* **When to use**
|
|
19
|
+
*
|
|
20
|
+
* Use when you need to integrate lower-level Solid context APIs, such as custom
|
|
21
|
+
* providers or hooks, instead of using the default atom hook setup.
|
|
22
|
+
*
|
|
23
|
+
* **Details**
|
|
24
|
+
*
|
|
25
|
+
* When no provider is present, the context uses a standalone default registry.
|
|
26
|
+
*
|
|
27
|
+
* @see {@link RegistryProvider} for creating and providing a registry for a Solid subtree
|
|
28
|
+
*
|
|
11
29
|
* @category context
|
|
30
|
+
* @since 4.0.0
|
|
12
31
|
*/
|
|
13
32
|
export const RegistryContext = createContext<AtomRegistry.AtomRegistry>(AtomRegistry.make())
|
|
14
33
|
|
|
15
34
|
/**
|
|
16
|
-
*
|
|
35
|
+
* Creates an `AtomRegistry` for a Solid subtree, optionally seeding initial atom
|
|
36
|
+
* values and scheduler settings, and disposes the registry when the owner is
|
|
37
|
+
* cleaned up.
|
|
38
|
+
*
|
|
39
|
+
* **When to use**
|
|
40
|
+
*
|
|
41
|
+
* Use to scope atom state, scheduling, and cleanup to a Solid subtree.
|
|
42
|
+
*
|
|
43
|
+
* **Details**
|
|
44
|
+
*
|
|
45
|
+
* The provider creates an `AtomRegistry` with `AtomRegistry.make`, forwards
|
|
46
|
+
* `initialValues`, `scheduleTask`, `timeoutResolution`, and
|
|
47
|
+
* `defaultIdleTTL`, and supplies the registry through `RegistryContext`.
|
|
48
|
+
*
|
|
49
|
+
* **Gotchas**
|
|
50
|
+
*
|
|
51
|
+
* Provider options are consumed when the registry is created; they are not
|
|
52
|
+
* reactive updates. A custom `scheduleTask` should return a cancellation
|
|
53
|
+
* function that is safe to call during Solid cleanup.
|
|
54
|
+
*
|
|
55
|
+
* @see {@link RegistryContext} for the context supplied by this provider
|
|
56
|
+
*
|
|
17
57
|
* @category context
|
|
58
|
+
* @since 4.0.0
|
|
18
59
|
*/
|
|
19
60
|
export const RegistryProvider = (options: {
|
|
20
61
|
readonly children?: JSX.Element | undefined
|
|
@@ -27,7 +68,7 @@ export const RegistryProvider = (options: {
|
|
|
27
68
|
scheduleTask: options.scheduleTask,
|
|
28
69
|
initialValues: options.initialValues,
|
|
29
70
|
timeoutResolution: options.timeoutResolution,
|
|
30
|
-
defaultIdleTTL: options.defaultIdleTTL
|
|
71
|
+
defaultIdleTTL: options.defaultIdleTTL ?? 400
|
|
31
72
|
})
|
|
32
73
|
onCleanup(() => registry.dispose())
|
|
33
74
|
return createComponent(RegistryContext.Provider, {
|