@effect/atom-react 4.0.0-beta.1 → 4.0.0-beta.100
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 +214 -13
- package/dist/Hooks.d.ts.map +1 -1
- package/dist/Hooks.js +186 -12
- package/dist/Hooks.js.map +1 -1
- package/dist/ReactHydration.d.ts +36 -0
- package/dist/ReactHydration.d.ts.map +1 -0
- package/dist/ReactHydration.js +90 -0
- package/dist/ReactHydration.js.map +1 -0
- package/dist/RegistryContext.d.ts +40 -3
- package/dist/RegistryContext.d.ts.map +1 -1
- package/dist/RegistryContext.js +46 -4
- package/dist/RegistryContext.js.map +1 -1
- package/dist/ScopedAtom.d.ts +49 -23
- package/dist/ScopedAtom.d.ts.map +1 -1
- package/dist/ScopedAtom.js +38 -12
- package/dist/ScopedAtom.js.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/package.json +11 -12
- package/src/Hooks.ts +220 -14
- package/src/ReactHydration.ts +109 -0
- package/src/RegistryContext.ts +46 -4
- package/src/ScopedAtom.ts +55 -24
- package/src/index.ts +9 -4
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React helpers for applying dehydrated Effect Atom state to a React subtree.
|
|
3
|
+
* The `HydrationBoundary` component reads the nearest `RegistryContext`,
|
|
4
|
+
* hydrates new Atom values before children render, and delays updates for
|
|
5
|
+
* existing Atom values until after commit so React transitions do not update
|
|
6
|
+
* the current UI too early.
|
|
7
|
+
*
|
|
8
|
+
* @since 4.0.0
|
|
9
|
+
*/
|
|
10
|
+
"use client";
|
|
11
|
+
|
|
12
|
+
import * as Hydration from "effect/unstable/reactivity/Hydration";
|
|
13
|
+
import * as React from "react";
|
|
14
|
+
import { RegistryContext } from "./RegistryContext.js";
|
|
15
|
+
/**
|
|
16
|
+
* Provides a React hydration boundary that loads dehydrated Atom values into
|
|
17
|
+
* the current Atom registry.
|
|
18
|
+
*
|
|
19
|
+
* **When to use**
|
|
20
|
+
*
|
|
21
|
+
* Use to apply dehydrated Atom state to a React subtree that reads from the
|
|
22
|
+
* nearest `RegistryContext`.
|
|
23
|
+
*
|
|
24
|
+
* **Details**
|
|
25
|
+
*
|
|
26
|
+
* New Atom values are hydrated during render so descendants can read them
|
|
27
|
+
* immediately, while values for existing Atoms are deferred until after commit
|
|
28
|
+
* so transition data does not update the current UI before React accepts it.
|
|
29
|
+
*
|
|
30
|
+
* @see {@link Hydration.dehydrate} for producing dehydrated Atom state
|
|
31
|
+
* @see {@link Hydration.hydrate} for lower-level non-React hydration
|
|
32
|
+
*
|
|
33
|
+
* @category components
|
|
34
|
+
* @since 4.0.0
|
|
35
|
+
*/
|
|
36
|
+
export const HydrationBoundary = ({
|
|
37
|
+
children,
|
|
38
|
+
state
|
|
39
|
+
}) => {
|
|
40
|
+
const registry = React.useContext(RegistryContext);
|
|
41
|
+
// This useMemo is for performance reasons only, everything inside it must
|
|
42
|
+
// be safe to run in every render and code here should be read as "in render".
|
|
43
|
+
//
|
|
44
|
+
// This code needs to happen during the render phase, because after initial
|
|
45
|
+
// SSR, hydration needs to happen _before_ children render. Also, if hydrating
|
|
46
|
+
// during a transition, we want to hydrate as much as is safe in render so
|
|
47
|
+
// we can prerender as much as possible.
|
|
48
|
+
//
|
|
49
|
+
// For any Atom values that already exist in the registry, we want to hold back on
|
|
50
|
+
// hydrating until _after_ the render phase. The reason for this is that during
|
|
51
|
+
// transitions, we don't want the existing Atom values and subscribers to update to
|
|
52
|
+
// the new data on the current page, only _after_ the transition is committed.
|
|
53
|
+
// If the transition is aborted, we will have hydrated any _new_ Atom values, but
|
|
54
|
+
// we throw away the fresh data for any existing ones to avoid unexpectedly
|
|
55
|
+
// updating the UI.
|
|
56
|
+
const hydrationQueue = React.useMemo(() => {
|
|
57
|
+
if (state) {
|
|
58
|
+
const dehydratedAtoms = Array.from(state);
|
|
59
|
+
const nodes = registry.getNodes();
|
|
60
|
+
const newDehydratedAtoms = [];
|
|
61
|
+
const existingDehydratedAtoms = [];
|
|
62
|
+
for (const dehydratedAtom of dehydratedAtoms) {
|
|
63
|
+
const existingNode = nodes.get(dehydratedAtom.key);
|
|
64
|
+
if (!existingNode) {
|
|
65
|
+
// This is a new Atom value, safe to hydrate immediately
|
|
66
|
+
newDehydratedAtoms.push(dehydratedAtom);
|
|
67
|
+
} else {
|
|
68
|
+
// This Atom value already exists, queue it for later hydration
|
|
69
|
+
existingDehydratedAtoms.push(dehydratedAtom);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (newDehydratedAtoms.length > 0) {
|
|
73
|
+
// It's actually fine to call this with state that already exists
|
|
74
|
+
// in the registry, or is older. hydrate() is idempotent.
|
|
75
|
+
Hydration.hydrate(registry, newDehydratedAtoms);
|
|
76
|
+
}
|
|
77
|
+
if (existingDehydratedAtoms.length > 0) {
|
|
78
|
+
return existingDehydratedAtoms;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
82
|
+
}, [registry, state]);
|
|
83
|
+
React.useEffect(() => {
|
|
84
|
+
if (hydrationQueue) {
|
|
85
|
+
Hydration.hydrate(registry, hydrationQueue);
|
|
86
|
+
}
|
|
87
|
+
}, [registry, hydrationQueue]);
|
|
88
|
+
return React.createElement(React.Fragment, {}, children);
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=ReactHydration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactHydration.js","names":["Hydration","React","RegistryContext","HydrationBoundary","children","state","registry","useContext","hydrationQueue","useMemo","dehydratedAtoms","Array","from","nodes","getNodes","newDehydratedAtoms","existingDehydratedAtoms","dehydratedAtom","existingNode","get","key","push","length","hydrate","undefined","useEffect","createElement","Fragment"],"sources":["../src/ReactHydration.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;AASA,YAAY;;AACZ,OAAO,KAAKA,SAAS,MAAM,sCAAsC;AACjE,OAAO,KAAKC,KAAK,MAAM,OAAO;AAC9B,SAASC,eAAe,QAAQ,sBAAsB;AActD;;;;;;;;;;;;;;;;;;;;;AAqBA,OAAO,MAAMC,iBAAiB,GAAqCA,CAAC;EAClEC,QAAQ;EACRC;AAAK,CACN,KAAI;EACH,MAAMC,QAAQ,GAAGL,KAAK,CAACM,UAAU,CAACL,eAAe,CAAC;EAElD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMM,cAAc,GAAqDP,KAAK,CAACQ,OAAO,CAAC,MAAK;IAC1F,IAAIJ,KAAK,EAAE;MACT,MAAMK,eAAe,GAAGC,KAAK,CAACC,IAAI,CAACP,KAAK,CAAyC;MACjF,MAAMQ,KAAK,GAAGP,QAAQ,CAACQ,QAAQ,EAAE;MAEjC,MAAMC,kBAAkB,GAAyC,EAAE;MACnE,MAAMC,uBAAuB,GAAyC,EAAE;MAExE,KAAK,MAAMC,cAAc,IAAIP,eAAe,EAAE;QAC5C,MAAMQ,YAAY,GAAGL,KAAK,CAACM,GAAG,CAACF,cAAc,CAACG,GAAG,CAAC;QAElD,IAAI,CAACF,YAAY,EAAE;UACjB;UACAH,kBAAkB,CAACM,IAAI,CAACJ,cAAc,CAAC;QACzC,CAAC,MAAM;UACL;UACAD,uBAAuB,CAACK,IAAI,CAACJ,cAAc,CAAC;QAC9C;MACF;MAEA,IAAIF,kBAAkB,CAACO,MAAM,GAAG,CAAC,EAAE;QACjC;QACA;QACAtB,SAAS,CAACuB,OAAO,CAACjB,QAAQ,EAAES,kBAAkB,CAAC;MACjD;MAEA,IAAIC,uBAAuB,CAACM,MAAM,GAAG,CAAC,EAAE;QACtC,OAAON,uBAAuB;MAChC;IACF;IACA,OAAOQ,SAAS;EAClB,CAAC,EAAE,CAAClB,QAAQ,EAAED,KAAK,CAAC,CAAC;EAErBJ,KAAK,CAACwB,SAAS,CAAC,MAAK;IACnB,IAAIjB,cAAc,EAAE;MAClBR,SAAS,CAACuB,OAAO,CAACjB,QAAQ,EAAEE,cAAc,CAAC;IAC7C;EACF,CAAC,EAAE,CAACF,QAAQ,EAAEE,cAAc,CAAC,CAAC;EAE9B,OAAOP,KAAK,CAACyB,aAAa,CAACzB,KAAK,CAAC0B,QAAQ,EAAE,EAAE,EAAEvB,QAAQ,CAAC;AAC1D,CAAC","ignoreList":[]}
|
|
@@ -2,18 +2,55 @@ import type * as Atom from "effect/unstable/reactivity/Atom";
|
|
|
2
2
|
import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Schedules Atom registry work with React's scheduler at low priority and
|
|
6
|
+
* returns a cancellation function for the scheduled task.
|
|
7
|
+
*
|
|
6
8
|
* @category context
|
|
9
|
+
* @since 4.0.0
|
|
7
10
|
*/
|
|
8
11
|
export declare function scheduleTask(f: () => void): () => void;
|
|
9
12
|
/**
|
|
10
|
-
*
|
|
13
|
+
* Provides a React context that supplies the `AtomRegistry` used by Atom hooks and
|
|
14
|
+
* hydration helpers, defaulting to a standalone registry when no provider is
|
|
15
|
+
* present.
|
|
16
|
+
*
|
|
17
|
+
* **When to use**
|
|
18
|
+
*
|
|
19
|
+
* Use to supply an existing `AtomRegistry` through React context when hooks or
|
|
20
|
+
* hydration helpers need to share registry state that is managed outside
|
|
21
|
+
* `RegistryProvider`.
|
|
22
|
+
*
|
|
23
|
+
* @see {@link RegistryProvider} for creating and providing a registry for a React subtree
|
|
24
|
+
*
|
|
11
25
|
* @category context
|
|
26
|
+
* @since 4.0.0
|
|
12
27
|
*/
|
|
13
28
|
export declare const RegistryContext: React.Context<AtomRegistry.AtomRegistry>;
|
|
14
29
|
/**
|
|
15
|
-
*
|
|
30
|
+
* Provides a stable `AtomRegistry` to a React subtree, optionally seeding
|
|
31
|
+
* initial atom values and overriding registry scheduling or idle settings.
|
|
32
|
+
*
|
|
33
|
+
* **When to use**
|
|
34
|
+
*
|
|
35
|
+
* Use to scope atom state, scheduling, and idle cleanup to a React subtree.
|
|
36
|
+
*
|
|
37
|
+
* **Details**
|
|
38
|
+
*
|
|
39
|
+
* The provider creates one `AtomRegistry` with `AtomRegistry.make`, passes it
|
|
40
|
+
* through `RegistryContext.Provider`, and forwards `initialValues`,
|
|
41
|
+
* `scheduleTask`, `timeoutResolution`, and `defaultIdleTTL` only when that
|
|
42
|
+
* registry is created.
|
|
43
|
+
*
|
|
44
|
+
* **Gotchas**
|
|
45
|
+
*
|
|
46
|
+
* Option changes after the first render do not rebuild the registry. When the
|
|
47
|
+
* provider unmounts, registry disposal is delayed briefly and canceled if the
|
|
48
|
+
* provider remounts before the timeout fires.
|
|
49
|
+
*
|
|
50
|
+
* @see {@link RegistryContext} for the React context supplied by this provider
|
|
51
|
+
*
|
|
16
52
|
* @category context
|
|
53
|
+
* @since 4.0.0
|
|
17
54
|
*/
|
|
18
55
|
export declare const RegistryProvider: (options: {
|
|
19
56
|
readonly children?: React.ReactNode | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegistryContext.d.ts","sourceRoot":"","sources":["../src/RegistryContext.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RegistryContext.d.ts","sourceRoot":"","sources":["../src/RegistryContext.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,IAAI,MAAM,iCAAiC,CAAA;AAC5D,OAAO,KAAK,YAAY,MAAM,yCAAyC,CAAA;AACvE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAGtD;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,0CAGzB,CAAA;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,gBAAgB,YAAa;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAA;IAC/C,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,mFA2BA,CAAA"}
|
package/dist/RegistryContext.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* React 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 React context lets components in the same
|
|
5
|
+
* subtree read and write the same atom state.
|
|
6
|
+
*
|
|
7
|
+
* @since 4.0.0
|
|
3
8
|
*/
|
|
4
9
|
"use client";
|
|
5
10
|
|
|
@@ -7,24 +12,61 @@ import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry";
|
|
|
7
12
|
import * as React from "react";
|
|
8
13
|
import * as Scheduler from "scheduler";
|
|
9
14
|
/**
|
|
10
|
-
*
|
|
15
|
+
* Schedules Atom registry work with React's scheduler at low priority and
|
|
16
|
+
* returns a cancellation function for the scheduled task.
|
|
17
|
+
*
|
|
11
18
|
* @category context
|
|
19
|
+
* @since 4.0.0
|
|
12
20
|
*/
|
|
13
21
|
export function scheduleTask(f) {
|
|
14
22
|
const node = Scheduler.unstable_scheduleCallback(Scheduler.unstable_LowPriority, f);
|
|
15
23
|
return () => Scheduler.unstable_cancelCallback(node);
|
|
16
24
|
}
|
|
17
25
|
/**
|
|
18
|
-
*
|
|
26
|
+
* Provides a React context that supplies the `AtomRegistry` used by Atom hooks and
|
|
27
|
+
* hydration helpers, defaulting to a standalone registry when no provider is
|
|
28
|
+
* present.
|
|
29
|
+
*
|
|
30
|
+
* **When to use**
|
|
31
|
+
*
|
|
32
|
+
* Use to supply an existing `AtomRegistry` through React context when hooks or
|
|
33
|
+
* hydration helpers need to share registry state that is managed outside
|
|
34
|
+
* `RegistryProvider`.
|
|
35
|
+
*
|
|
36
|
+
* @see {@link RegistryProvider} for creating and providing a registry for a React subtree
|
|
37
|
+
*
|
|
19
38
|
* @category context
|
|
39
|
+
* @since 4.0.0
|
|
20
40
|
*/
|
|
21
41
|
export const RegistryContext = /*#__PURE__*/React.createContext(/*#__PURE__*/AtomRegistry.make({
|
|
22
42
|
scheduleTask,
|
|
23
43
|
defaultIdleTTL: 400
|
|
24
44
|
}));
|
|
25
45
|
/**
|
|
26
|
-
*
|
|
46
|
+
* Provides a stable `AtomRegistry` to a React subtree, optionally seeding
|
|
47
|
+
* initial atom values and overriding registry scheduling or idle settings.
|
|
48
|
+
*
|
|
49
|
+
* **When to use**
|
|
50
|
+
*
|
|
51
|
+
* Use to scope atom state, scheduling, and idle cleanup to a React subtree.
|
|
52
|
+
*
|
|
53
|
+
* **Details**
|
|
54
|
+
*
|
|
55
|
+
* The provider creates one `AtomRegistry` with `AtomRegistry.make`, passes it
|
|
56
|
+
* through `RegistryContext.Provider`, and forwards `initialValues`,
|
|
57
|
+
* `scheduleTask`, `timeoutResolution`, and `defaultIdleTTL` only when that
|
|
58
|
+
* registry is created.
|
|
59
|
+
*
|
|
60
|
+
* **Gotchas**
|
|
61
|
+
*
|
|
62
|
+
* Option changes after the first render do not rebuild the registry. When the
|
|
63
|
+
* provider unmounts, registry disposal is delayed briefly and canceled if the
|
|
64
|
+
* provider remounts before the timeout fires.
|
|
65
|
+
*
|
|
66
|
+
* @see {@link RegistryContext} for the React context supplied by this provider
|
|
67
|
+
*
|
|
27
68
|
* @category context
|
|
69
|
+
* @since 4.0.0
|
|
28
70
|
*/
|
|
29
71
|
export const RegistryProvider = options => {
|
|
30
72
|
const ref = React.useRef(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegistryContext.js","names":["AtomRegistry","React","Scheduler","scheduleTask","f","node","unstable_scheduleCallback","unstable_LowPriority","unstable_cancelCallback","RegistryContext","createContext","make","defaultIdleTTL","RegistryProvider","options","ref","useRef","current","registry","initialValues","timeoutResolution","useEffect","timeout","undefined","clearTimeout","setTimeout","dispose","createElement","Provider","value","children"],"sources":["../src/RegistryContext.ts"],"sourcesContent":[null],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"RegistryContext.js","names":["AtomRegistry","React","Scheduler","scheduleTask","f","node","unstable_scheduleCallback","unstable_LowPriority","unstable_cancelCallback","RegistryContext","createContext","make","defaultIdleTTL","RegistryProvider","options","ref","useRef","current","registry","initialValues","timeoutResolution","useEffect","timeout","undefined","clearTimeout","setTimeout","dispose","createElement","Provider","value","children"],"sources":["../src/RegistryContext.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;AAQA,YAAY;;AAGZ,OAAO,KAAKA,YAAY,MAAM,yCAAyC;AACvE,OAAO,KAAKC,KAAK,MAAM,OAAO;AAC9B,OAAO,KAAKC,SAAS,MAAM,WAAW;AAEtC;;;;;;;AAOA,OAAM,SAAUC,YAAYA,CAACC,CAAa;EACxC,MAAMC,IAAI,GAAGH,SAAS,CAACI,yBAAyB,CAACJ,SAAS,CAACK,oBAAoB,EAAEH,CAAC,CAAC;EACnF,OAAO,MAAMF,SAAS,CAACM,uBAAuB,CAACH,IAAI,CAAC;AACtD;AAEA;;;;;;;;;;;;;;;;AAgBA,OAAO,MAAMI,eAAe,gBAAGR,KAAK,CAACS,aAAa,cAA4BV,YAAY,CAACW,IAAI,CAAC;EAC9FR,YAAY;EACZS,cAAc,EAAE;CACjB,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,OAAO,MAAMC,gBAAgB,GAAIC,OAMhC,IAAI;EACH,MAAMC,GAAG,GAAGd,KAAK,CAACe,MAAM,CAGrB,IAAI,CAAC;EACR,IAAID,GAAG,CAACE,OAAO,KAAK,IAAI,EAAE;IACxBF,GAAG,CAACE,OAAO,GAAG;MACZC,QAAQ,EAAElB,YAAY,CAACW,IAAI,CAAC;QAC1BR,YAAY,EAAEW,OAAO,CAACX,YAAY,IAAIA,YAAY;QAClDgB,aAAa,EAAEL,OAAO,CAACK,aAAa;QACpCC,iBAAiB,EAAEN,OAAO,CAACM,iBAAiB;QAC5CR,cAAc,EAAEE,OAAO,CAACF;OACzB;KACF;EACH;EACAX,KAAK,CAACoB,SAAS,CAAC,MAAK;IACnB,IAAIN,GAAG,CAACE,OAAO,EAAEK,OAAO,KAAKC,SAAS,EAAE;MACtCC,YAAY,CAACT,GAAG,CAACE,OAAO,CAACK,OAAO,CAAC;IACnC;IACA,OAAO,MAAK;MACVP,GAAG,CAACE,OAAQ,CAACK,OAAO,GAAGG,UAAU,CAAC,MAAK;QACrCV,GAAG,CAACE,OAAO,EAAEC,QAAQ,CAACQ,OAAO,EAAE;QAC/BX,GAAG,CAACE,OAAO,GAAG,IAAI;MACpB,CAAC,EAAE,GAAG,CAAQ;IAChB,CAAC;EACH,CAAC,EAAE,CAACF,GAAG,CAAC,CAAC;EACT,OAAOd,KAAK,CAAC0B,aAAa,CAAClB,eAAe,CAACmB,QAAQ,EAAE;IAAEC,KAAK,EAAEd,GAAG,CAACE,OAAO,CAACC;EAAQ,CAAE,EAAEJ,OAAO,EAAEgB,QAAQ,CAAC;AAC1G,CAAC","ignoreList":[]}
|
package/dist/ScopedAtom.d.ts
CHANGED
|
@@ -1,33 +1,40 @@
|
|
|
1
1
|
import type * as Atom from "effect/unstable/reactivity/Atom";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* @category Type IDs
|
|
4
|
+
* Literal type used as the `ScopedAtom` type identifier.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
6
|
+
* **Details**
|
|
7
|
+
*
|
|
8
|
+
* Used as the computed property key and marker value stored on `ScopedAtom`
|
|
9
|
+
* objects.
|
|
10
|
+
*
|
|
11
|
+
* @category type IDs
|
|
12
|
+
* @since 4.0.0
|
|
8
13
|
*/
|
|
9
14
|
export type TypeId = "~@effect/atom-react/ScopedAtom";
|
|
10
15
|
/**
|
|
11
|
-
* @since 1.0.0
|
|
12
|
-
* @category Type IDs
|
|
13
|
-
*
|
|
14
16
|
* Type identifier for ScopedAtom.
|
|
17
|
+
*
|
|
18
|
+
* **Details**
|
|
19
|
+
*
|
|
20
|
+
* Used as the computed property key and marker value stored on `ScopedAtom`
|
|
21
|
+
* objects.
|
|
22
|
+
*
|
|
23
|
+
* @category type IDs
|
|
24
|
+
* @since 4.0.0
|
|
15
25
|
*/
|
|
16
26
|
export declare const TypeId: TypeId;
|
|
17
27
|
/**
|
|
18
|
-
* @since 1.0.0
|
|
19
|
-
* @category models
|
|
20
|
-
*
|
|
21
28
|
* Scoped Atom interface with a provider-backed instance.
|
|
22
29
|
*
|
|
23
|
-
*
|
|
30
|
+
* **Example** (Providing and reading a scoped atom)
|
|
31
|
+
*
|
|
24
32
|
* ```ts
|
|
25
|
-
* import
|
|
33
|
+
* import { make, useAtomValue } from "@effect/atom-react"
|
|
34
|
+
* import { Atom } from "effect/unstable/reactivity"
|
|
26
35
|
* import * as React from "react"
|
|
27
|
-
* import * as ScopedAtom from "@effect/atom-react/ScopedAtom"
|
|
28
|
-
* import { useAtomValue } from "@effect/atom-react"
|
|
29
36
|
*
|
|
30
|
-
* const Counter =
|
|
37
|
+
* const Counter = make(() => Atom.make(0))
|
|
31
38
|
*
|
|
32
39
|
* function View() {
|
|
33
40
|
* const atom = Counter.use()
|
|
@@ -39,11 +46,14 @@ export declare const TypeId: TypeId;
|
|
|
39
46
|
* return React.createElement(Counter.Provider, null, React.createElement(View))
|
|
40
47
|
* }
|
|
41
48
|
* ```
|
|
49
|
+
*
|
|
50
|
+
* @category models
|
|
51
|
+
* @since 4.0.0
|
|
42
52
|
*/
|
|
43
53
|
export interface ScopedAtom<A extends Atom.Atom<any>, Input = never> {
|
|
44
54
|
readonly [TypeId]: TypeId;
|
|
45
55
|
use(): A;
|
|
46
|
-
Provider: Input extends never ? React.FC<{
|
|
56
|
+
Provider: [Input] extends [never] ? React.FC<{
|
|
47
57
|
readonly children?: React.ReactNode | undefined;
|
|
48
58
|
}> : React.FC<{
|
|
49
59
|
readonly children?: React.ReactNode | undefined;
|
|
@@ -52,19 +62,32 @@ export interface ScopedAtom<A extends Atom.Atom<any>, Input = never> {
|
|
|
52
62
|
Context: React.Context<A>;
|
|
53
63
|
}
|
|
54
64
|
/**
|
|
55
|
-
* @since 1.0.0
|
|
56
|
-
* @category constructors
|
|
57
|
-
*
|
|
58
65
|
* Creates a ScopedAtom from a factory function.
|
|
59
66
|
*
|
|
60
|
-
*
|
|
67
|
+
* **When to use**
|
|
68
|
+
*
|
|
69
|
+
* Use to create an atom instance that is owned by a React provider and scoped
|
|
70
|
+
* to a component subtree.
|
|
71
|
+
*
|
|
72
|
+
* **Details**
|
|
73
|
+
*
|
|
74
|
+
* The returned scoped atom includes a `Provider`, `Context`, and `use`
|
|
75
|
+
* accessor. The provider creates the atom once for its lifetime, passing the
|
|
76
|
+
* `value` prop to the factory when the scoped atom expects input.
|
|
77
|
+
*
|
|
78
|
+
* **Gotchas**
|
|
79
|
+
*
|
|
80
|
+
* `use` must run under the matching provider. Changing the provider `value`
|
|
81
|
+
* prop after mount does not recreate the atom.
|
|
82
|
+
*
|
|
83
|
+
* **Example** (Creating a scoped atom with input)
|
|
84
|
+
*
|
|
61
85
|
* ```ts
|
|
62
|
-
* import
|
|
86
|
+
* import { make, useAtomValue } from "@effect/atom-react"
|
|
87
|
+
* import { Atom } from "effect/unstable/reactivity"
|
|
63
88
|
* import * as React from "react"
|
|
64
|
-
* import * as ScopedAtom from "@effect/atom-react/ScopedAtom"
|
|
65
|
-
* import { useAtomValue } from "@effect/atom-react"
|
|
66
89
|
*
|
|
67
|
-
* const User =
|
|
90
|
+
* const User = make((name: string) => Atom.make(name))
|
|
68
91
|
*
|
|
69
92
|
* function UserName() {
|
|
70
93
|
* const atom = User.use()
|
|
@@ -80,6 +103,9 @@ export interface ScopedAtom<A extends Atom.Atom<any>, Input = never> {
|
|
|
80
103
|
* )
|
|
81
104
|
* }
|
|
82
105
|
* ```
|
|
106
|
+
*
|
|
107
|
+
* @category constructors
|
|
108
|
+
* @since 4.0.0
|
|
83
109
|
*/
|
|
84
110
|
export declare const make: <A extends Atom.Atom<any>, Input = never>(f: (() => A) | ((input: Input) => A)) => ScopedAtom<A, Input>;
|
|
85
111
|
//# sourceMappingURL=ScopedAtom.d.ts.map
|
package/dist/ScopedAtom.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScopedAtom.d.ts","sourceRoot":"","sources":["../src/ScopedAtom.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ScopedAtom.d.ts","sourceRoot":"","sources":["../src/ScopedAtom.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,IAAI,MAAM,iCAAiC,CAAA;AAC5D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B;;;;;;;;;;GAUG;AACH,MAAM,MAAM,MAAM,GAAG,gCAAgC,CAAA;AAErD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM,EAAE,MAAyC,CAAA;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK;IACjE,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACzB,GAAG,IAAI,CAAC,CAAA;IACR,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAA;KAAE,CAAC,GAC7F,KAAK,CAAC,EAAE,CAAC;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAA;IACxF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,KACvD,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,CAAC,KACnC,UAAU,CAAC,CAAC,EAAE,KAAK,CA6BrB,CAAA"}
|
package/dist/ScopedAtom.js
CHANGED
|
@@ -1,30 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* React helpers for creating Atom instances that belong to one component
|
|
3
|
+
* subtree. `make` returns a scoped atom with a provider, context, and `use`
|
|
4
|
+
* accessor. Each provider creates its own Atom once, so different subtrees can
|
|
5
|
+
* use the same scoped atom definition without sharing state.
|
|
6
|
+
*
|
|
7
|
+
* @since 4.0.0
|
|
3
8
|
*/
|
|
4
9
|
"use client";
|
|
5
10
|
|
|
6
11
|
import * as React from "react";
|
|
7
12
|
/**
|
|
8
|
-
* @since 1.0.0
|
|
9
|
-
* @category Type IDs
|
|
10
|
-
*
|
|
11
13
|
* Type identifier for ScopedAtom.
|
|
14
|
+
*
|
|
15
|
+
* **Details**
|
|
16
|
+
*
|
|
17
|
+
* Used as the computed property key and marker value stored on `ScopedAtom`
|
|
18
|
+
* objects.
|
|
19
|
+
*
|
|
20
|
+
* @category type IDs
|
|
21
|
+
* @since 4.0.0
|
|
12
22
|
*/
|
|
13
23
|
export const TypeId = "~@effect/atom-react/ScopedAtom";
|
|
14
24
|
/**
|
|
15
|
-
* @since 1.0.0
|
|
16
|
-
* @category constructors
|
|
17
|
-
*
|
|
18
25
|
* Creates a ScopedAtom from a factory function.
|
|
19
26
|
*
|
|
20
|
-
*
|
|
27
|
+
* **When to use**
|
|
28
|
+
*
|
|
29
|
+
* Use to create an atom instance that is owned by a React provider and scoped
|
|
30
|
+
* to a component subtree.
|
|
31
|
+
*
|
|
32
|
+
* **Details**
|
|
33
|
+
*
|
|
34
|
+
* The returned scoped atom includes a `Provider`, `Context`, and `use`
|
|
35
|
+
* accessor. The provider creates the atom once for its lifetime, passing the
|
|
36
|
+
* `value` prop to the factory when the scoped atom expects input.
|
|
37
|
+
*
|
|
38
|
+
* **Gotchas**
|
|
39
|
+
*
|
|
40
|
+
* `use` must run under the matching provider. Changing the provider `value`
|
|
41
|
+
* prop after mount does not recreate the atom.
|
|
42
|
+
*
|
|
43
|
+
* **Example** (Creating a scoped atom with input)
|
|
44
|
+
*
|
|
21
45
|
* ```ts
|
|
22
|
-
* import
|
|
46
|
+
* import { make, useAtomValue } from "@effect/atom-react"
|
|
47
|
+
* import { Atom } from "effect/unstable/reactivity"
|
|
23
48
|
* import * as React from "react"
|
|
24
|
-
* import * as ScopedAtom from "@effect/atom-react/ScopedAtom"
|
|
25
|
-
* import { useAtomValue } from "@effect/atom-react"
|
|
26
49
|
*
|
|
27
|
-
* const User =
|
|
50
|
+
* const User = make((name: string) => Atom.make(name))
|
|
28
51
|
*
|
|
29
52
|
* function UserName() {
|
|
30
53
|
* const atom = User.use()
|
|
@@ -40,6 +63,9 @@ export const TypeId = "~@effect/atom-react/ScopedAtom";
|
|
|
40
63
|
* )
|
|
41
64
|
* }
|
|
42
65
|
* ```
|
|
66
|
+
*
|
|
67
|
+
* @category constructors
|
|
68
|
+
* @since 4.0.0
|
|
43
69
|
*/
|
|
44
70
|
export const make = f => {
|
|
45
71
|
const Context = React.createContext(undefined);
|
package/dist/ScopedAtom.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScopedAtom.js","names":["React","TypeId","make","f","Context","createContext","undefined","use","atom","useContext","Error","Provider","props","useRef","current","value","createElement","children"],"sources":["../src/ScopedAtom.ts"],"sourcesContent":[null],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ScopedAtom.js","names":["React","TypeId","make","f","Context","createContext","undefined","use","atom","useContext","Error","Provider","props","useRef","current","value","createElement","children"],"sources":["../src/ScopedAtom.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;AAQA,YAAY;;AAGZ,OAAO,KAAKA,KAAK,MAAM,OAAO;AAe9B;;;;;;;;;;;AAWA,OAAO,MAAMC,MAAM,GAAW,gCAAgC;AAoC9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,OAAO,MAAMC,IAAI,GACfC,CAAoC,IACZ;EACxB,MAAMC,OAAO,GAAGJ,KAAK,CAACK,aAAa,CAAIC,SAAyB,CAAC;EAEjE,MAAMC,GAAG,GAAGA,CAAA,KAAQ;IAClB,MAAMC,IAAI,GAAGR,KAAK,CAACS,UAAU,CAACL,OAAO,CAAC;IACtC,IAAII,IAAI,KAAKF,SAAS,EAAE;MACtB,MAAM,IAAII,KAAK,CAAC,yCAAyC,CAAC;IAC5D;IACA,OAAOF,IAAI;EACb,CAAC;EAED,MAAMG,QAAQ,GAA2FC,KAAK,IAAI;IAChH,MAAMJ,IAAI,GAAGR,KAAK,CAACa,MAAM,CAAW,IAAI,CAAC;IACzC,IAAIL,IAAI,CAACM,OAAO,KAAK,IAAI,EAAE;MACzB,IAAI,OAAO,IAAIF,KAAK,EAAE;QACpBJ,IAAI,CAACM,OAAO,GAAIX,CAAyB,CAACS,KAAK,CAACG,KAAc,CAAC;MACjE,CAAC,MAAM;QACLP,IAAI,CAACM,OAAO,GAAIX,CAAa,EAAE;MACjC;IACF;IACA,OAAOH,KAAK,CAACgB,aAAa,CAACZ,OAAO,CAACO,QAAQ,EAAE;MAAEI,KAAK,EAAEP,IAAI,CAACM;IAAO,CAAE,EAAEF,KAAK,CAACK,QAAQ,CAAC;EACvF,CAAC;EAED,OAAO;IACL,CAAChB,MAAM,GAAGA,MAAM;IAChBM,GAAG;IACHI,QAAQ,EAAEA,QAAe;IACzBP;GACD;AACH,CAAC","ignoreList":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since
|
|
2
|
+
* @since 4.0.0
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* @since
|
|
5
|
+
* @since 4.0.0
|
|
6
6
|
*/
|
|
7
7
|
export * from "./Hooks.ts";
|
|
8
8
|
/**
|
|
9
|
-
* @since
|
|
9
|
+
* @since 4.0.0
|
|
10
10
|
*/
|
|
11
11
|
export * from "./RegistryContext.ts";
|
|
12
12
|
/**
|
|
13
|
-
* @since
|
|
13
|
+
* @since 4.0.0
|
|
14
|
+
*/
|
|
15
|
+
export * from "./ReactHydration.ts";
|
|
16
|
+
/**
|
|
17
|
+
* @since 4.0.0
|
|
14
18
|
*/
|
|
15
19
|
export * from "./ScopedAtom.ts";
|
|
16
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,cAAc,YAAY,CAAA;AAE1B;;GAEG;AACH,cAAc,sBAAsB,CAAA;AAEpC;;GAEG;AACH,cAAc,iBAAiB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,cAAc,YAAY,CAAA;AAE1B;;GAEG;AACH,cAAc,sBAAsB,CAAA;AAEpC;;GAEG;AACH,cAAc,qBAAqB,CAAA;AAEnC;;GAEG;AACH,cAAc,iBAAiB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since
|
|
2
|
+
* @since 4.0.0
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* @since
|
|
5
|
+
* @since 4.0.0
|
|
6
6
|
*/
|
|
7
7
|
export * from "./Hooks.js";
|
|
8
8
|
/**
|
|
9
|
-
* @since
|
|
9
|
+
* @since 4.0.0
|
|
10
10
|
*/
|
|
11
11
|
export * from "./RegistryContext.js";
|
|
12
12
|
/**
|
|
13
|
-
* @since
|
|
13
|
+
* @since 4.0.0
|
|
14
|
+
*/
|
|
15
|
+
export * from "./ReactHydration.js";
|
|
16
|
+
/**
|
|
17
|
+
* @since 4.0.0
|
|
14
18
|
*/
|
|
15
19
|
export * from "./ScopedAtom.js";
|
|
16
20
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAIA;;;AAGA,cAAc,YAAY;AAE1B;;;AAGA,cAAc,sBAAsB;AAEpC;;;AAGA,cAAc,iBAAiB","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAIA;;;AAGA,cAAc,YAAY;AAE1B;;;AAGA,cAAc,sBAAsB;AAEpC;;;AAGA,cAAc,qBAAqB;AAEnC;;;AAGA,cAAc,iBAAiB","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect/atom-react",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.100",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "React bindings for the Effect Atom modules",
|
|
7
7
|
"homepage": "https://effect.website",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/Effect-TS/effect
|
|
10
|
+
"url": "https://github.com/Effect-TS/effect.git",
|
|
11
11
|
"directory": "packages/atom/react"
|
|
12
12
|
},
|
|
13
13
|
"bugs": {
|
|
14
|
-
"url": "https://github.com/Effect-TS/effect
|
|
14
|
+
"url": "https://github.com/Effect-TS/effect/issues"
|
|
15
15
|
},
|
|
16
16
|
"tags": [
|
|
17
17
|
"typescript",
|
|
@@ -45,25 +45,24 @@
|
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"react": "^19.2.4",
|
|
47
47
|
"scheduler": "*",
|
|
48
|
-
"effect": "^4.0.0-beta.
|
|
48
|
+
"effect": "^4.0.0-beta.100"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@testing-library/dom": "^10.4.1",
|
|
52
52
|
"@testing-library/jest-dom": "^6.9.1",
|
|
53
|
-
"@testing-library/react": "^16.3.
|
|
54
|
-
"@types/react": "^19.2.
|
|
53
|
+
"@testing-library/react": "^16.3.2",
|
|
54
|
+
"@types/react": "^19.2.17",
|
|
55
55
|
"@types/react-dom": "^19.2.2",
|
|
56
56
|
"@types/scheduler": "^0.26.0",
|
|
57
|
-
"jsdom": "^
|
|
58
|
-
"react": "19.2.
|
|
59
|
-
"react-dom": "19.2.
|
|
60
|
-
"react-error-boundary": "^6.
|
|
57
|
+
"jsdom": "^29.1.1",
|
|
58
|
+
"react": "19.2.7",
|
|
59
|
+
"react-dom": "19.2.7",
|
|
60
|
+
"react-error-boundary": "^6.1.2",
|
|
61
61
|
"scheduler": "^0.27.0",
|
|
62
|
-
"effect": "^4.0.0-beta.
|
|
62
|
+
"effect": "^4.0.0-beta.100"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
65
|
"build": "tsc -b tsconfig.json && pnpm babel",
|
|
66
|
-
"build:tsgo": "tsgo -b tsconfig.json && pnpm babel",
|
|
67
66
|
"babel": "babel dist --plugins annotate-pure-calls --out-dir dist --source-maps",
|
|
68
67
|
"check": "tsc -b tsconfig.json",
|
|
69
68
|
"test": "vitest",
|