atomirx 0.1.1 → 0.1.2
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/core/abortable.d.ts +196 -0
- package/dist/core/abortable.test.d.ts +1 -0
- package/dist/core/derived.d.ts +6 -3
- package/dist/core/effect.d.ts +3 -0
- package/dist/core/event.d.ts +152 -0
- package/dist/core/event.test.d.ts +1 -0
- package/dist/core/onCreateHook.d.ts +16 -3
- package/dist/core/promiseCache.d.ts +35 -0
- package/dist/core/select.d.ts +18 -10
- package/dist/core/types.d.ts +219 -9
- package/dist/core/withReady.d.ts +36 -45
- package/dist/index-B1Kum0se.cjs +1 -0
- package/dist/index-DbZ2r2Im.js +1756 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.js +32 -25
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.js +90 -83
- package/package.json +1 -1
- package/skills/atomirx/SKILL.md +154 -15
- package/skills/atomirx/references/async-patterns.md +92 -9
- package/skills/atomirx/references/select-context.md +31 -18
- package/dist/index-BZEnfIcB.cjs +0 -1
- package/dist/index-BbPZhsDl.js +0 -1653
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-B1Kum0se.cjs"),r=require("./onErrorHook-DHBASmYw.cjs");exports.AllAtomsRejectedError=e.AllAtomsRejectedError;exports.abortable=e.abortable;exports.atom=e.atom;exports.batch=e.batch;exports.createAbortError=e.createAbortError;exports.createRejectedPromise=e.createRejectedPromise;exports.createResolvedPromise=e.createResolvedPromise;exports.define=e.define;exports.derived=e.derived;exports.effect=e.effect;exports.emitter=e.emitter;exports.event=e.event;exports.getAtomState=e.getAtomState;exports.isAbortError=e.isAbortError;exports.isAtom=e.isAtom;exports.isDerived=e.isDerived;exports.isEvent=e.isEvent;exports.isFulfilled=e.isFulfilled;exports.isPending=e.isPending;exports.isPool=e.isPool;exports.isRejected=e.isRejected;exports.isScopedAtom=e.isScopedAtom;exports.pool=e.pool;exports.promisesEqual=e.promisesEqual;exports.readonly=e.readonly;exports.select=e.select;exports.trackPromise=e.trackPromise;exports.unwrap=e.unwrap;exports.onCreateHook=r.onCreateHook;exports.onErrorHook=r.onErrorHook;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
|
+
export { abortable, isAbortError, createAbortError } from './core/abortable';
|
|
2
|
+
export type { AbortableOptions, AbortablePromise } from './core/abortable';
|
|
1
3
|
export { atom, readonly } from './core/atom';
|
|
2
4
|
export { batch } from './core/batch';
|
|
3
5
|
export { define } from './core/define';
|
|
4
6
|
export { derived, type DerivedContext } from './core/derived';
|
|
5
7
|
export { effect, type EffectContext } from './core/effect';
|
|
6
8
|
export { emitter } from './core/emitter';
|
|
9
|
+
export { event, isEvent } from './core/event';
|
|
10
|
+
export type { EventOptions } from './core/event';
|
|
7
11
|
export { isAtom, isDerived } from './core/isAtom';
|
|
8
12
|
export { pool, isPool } from './core/pool';
|
|
9
13
|
export { select, AllAtomsRejectedError, isScopedAtom, type Condition, } from './core/select';
|
|
10
14
|
export { getAtomState } from './core/getAtomState';
|
|
11
|
-
export { isPending, isFulfilled, isRejected, trackPromise, unwrap, } from './core/promiseCache';
|
|
12
|
-
export type { Atom, AtomMeta, AtomOptions, AtomState, AtomValue, AnyAtom, DerivedAtom, DerivedAtomMeta, DerivedOptions, EffectOptions, Equality, EqualityShorthand, Getter, KeyedResult, MutableAtom, MutableAtomMeta, Pipeable, Pool, PoolEvent, PoolMeta, PoolOptions, SelectStateResult, SettledResult, ScopedAtom, } from './core/types';
|
|
15
|
+
export { isPending, isFulfilled, isRejected, trackPromise, unwrap, createResolvedPromise, createRejectedPromise, } from './core/promiseCache';
|
|
16
|
+
export type { Atom, AtomMeta, AtomOptions, AtomState, AtomValue, AnyAtom, DerivedAtom, DerivedAtomMeta, DerivedOptions, EffectOptions, Equality, EqualityShorthand, Event, EventMeta, Getter, KeyedResult, MutableAtom, MutableAtomMeta, Pipeable, Pool, PoolEvent, PoolMeta, PoolOptions, SelectStateResult, SettledResult, ScopedAtom, } from './core/types';
|
|
13
17
|
export { onCreateHook } from './core/onCreateHook';
|
|
14
|
-
export type { CreateInfo, MutableInfo, DerivedInfo, EffectInfo, ModuleInfo, } from './core/onCreateHook';
|
|
18
|
+
export type { CreateInfo, MutableInfo, DerivedInfo, EffectInfo, EventInfo, ModuleInfo, } from './core/onCreateHook';
|
|
15
19
|
export { onErrorHook } from './core/onErrorHook';
|
|
16
20
|
export type { ErrorInfo } from './core/onErrorHook';
|
|
17
21
|
export type { SelectContext, SelectOutput, SelectResult, ReactiveSelector as ContextSelectorFn, SafeResult, } from './core/select';
|
package/dist/index.js
CHANGED
|
@@ -1,27 +1,34 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
import { o as
|
|
1
|
+
import { A as a, c as o, g as r, j as t, f as i, G as l, F as m, k as c, l as d, m as n, n as A, o as f, y as p, e as E, i as v, q as b, p as P, B as j, z as k, v as u, C as R, x as g, u as x, H, h, s as q, D as y, E as C } from "./index-DbZ2r2Im.js";
|
|
2
|
+
import { o as F, a as S } from "./onErrorHook-BGGy3tqK.js";
|
|
3
3
|
export {
|
|
4
|
-
|
|
5
|
-
o as
|
|
6
|
-
r as
|
|
7
|
-
t as
|
|
8
|
-
i as
|
|
9
|
-
l as
|
|
10
|
-
m as
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
n as
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
4
|
+
a as AllAtomsRejectedError,
|
|
5
|
+
o as abortable,
|
|
6
|
+
r as atom,
|
|
7
|
+
t as batch,
|
|
8
|
+
i as createAbortError,
|
|
9
|
+
l as createRejectedPromise,
|
|
10
|
+
m as createResolvedPromise,
|
|
11
|
+
c as define,
|
|
12
|
+
d as derived,
|
|
13
|
+
n as effect,
|
|
14
|
+
A as emitter,
|
|
15
|
+
f as event,
|
|
16
|
+
p as getAtomState,
|
|
17
|
+
E as isAbortError,
|
|
18
|
+
v as isAtom,
|
|
19
|
+
b as isDerived,
|
|
20
|
+
P as isEvent,
|
|
21
|
+
j as isFulfilled,
|
|
22
|
+
k as isPending,
|
|
23
|
+
u as isPool,
|
|
24
|
+
R as isRejected,
|
|
25
|
+
g as isScopedAtom,
|
|
26
|
+
F as onCreateHook,
|
|
27
|
+
S as onErrorHook,
|
|
28
|
+
x as pool,
|
|
29
|
+
H as promisesEqual,
|
|
30
|
+
h as readonly,
|
|
31
|
+
q as select,
|
|
32
|
+
y as trackPromise,
|
|
33
|
+
C as unwrap
|
|
27
34
|
};
|
package/dist/react/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var F=Object.defineProperty;var z=(r,e,n)=>e in r?F(r,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):r[e]=n;var w=(r,e,n)=>z(r,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react"),t=require("../index-
|
|
1
|
+
"use strict";var F=Object.defineProperty;var z=(r,e,n)=>e in r?F(r,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):r[e]=n;var w=(r,e,n)=>z(r,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react"),t=require("../index-B1Kum0se.cjs"),A=require("../onDispatchHook-C8yLzr-o.cjs"),d=require("react/jsx-runtime"),H=require("../onErrorHook-DHBASmYw.cjs");function C(r,e){const n=t.isAtom(r)?({read:b})=>b(r):r,m=t.resolveEquality(e??"shallow"),s=o.useRef(n),h=o.useRef(m);s.current=n,h.current=m;const a=o.useRef(new Map),u=o.useRef(new Set),c=o.useRef([]),R=o.useRef(new Map),l=o.useRef({value:void 0,initialized:!1}),y=o.useCallback(()=>{const{result:b}=t.select(s.current);if(u.current=b._atomDeps,R.current=b._poolDeps,b.promise!==void 0)throw b.promise;if(b.error!==void 0)throw b.error;const E=b.value;return(!l.current.initialized||!h.current(E,l.current.value))&&(l.current={value:E,initialized:!0}),l.current.value},[]),k=o.useCallback(b=>{const E=a.current,D=()=>{const{result:f}=t.select(s.current);u.current=f._atomDeps,R.current=f._poolDeps,i(),b()},i=()=>{const f=u.current,g=R.current;for(const[p,v]of E)f.has(p)||(v(),E.delete(p));for(const p of f)E.has(p)||E.set(p,p.on(D));for(const p of c.current)p();c.current=[];for(const[p,v]of g)for(const x of v)c.current.push(p._onRemove(x,D))};return i(),()=>{for(const f of E.values())f();E.clear();for(const f of c.current)f();c.current=[]}},[]);return o.useSyncExternalStore(k,y,y)}function _(r){return r==null?Object.is:Array.isArray(r)?"shallow":r instanceof Date?t.deepEqual:typeof r=="object"?t.shallowEqual:Object.is}function I(r,e){const n=o.useRef({}),m=o.useRef(null);m.current===null&&(m.current={});const s=n.current,h=m.current;for(const a of Object.keys(r)){const u=r[a],c=s[a];if(typeof u=="function"){const[k]=t.tryStabilize(c,u,()=>!1);s[a]={value:k},h[a]=k;continue}const R=e==null?void 0:e[a],l=R?t.resolveEquality(R):t.resolveEquality(_(u)),[y]=t.tryStabilize(c,u,l);s[a]={value:y},h[a]=y}for(const a of Object.keys(s))a in r||(delete s[a],delete h[a]);return h}const P={status:"idle",result:void 0,error:void 0},T={status:"loading",result:void 0,error:void 0};function L(r,e){switch(e.type){case"START":return T;case"SUCCESS":return{status:"success",result:e.result,error:void 0};case"ERROR":return{status:"error",result:void 0,error:e.error};case"RESET":return P;default:return r}}function M(r,e={}){const{lazy:n=!0,exclusive:m=!0,deps:s=[]}=e,h=n?P:T,[a,u]=o.useReducer(L,h),c=o.useRef(null),R=o.useRef(r);R.current=r;const l=o.useCallback(()=>{const i=c.current;return i?(i.abort(),c.current=null,!0):!1},[]),y=(n?[]:s??[]).filter(t.isAtom),k=C(({read:i})=>y.map(f=>i(f))),b=o.useCallback(()=>{var g,p,v,x,q,O;m&&l();const i=new AbortController;c.current=i,u({type:"START"}),(p=(g=A.onDispatchHook).current)==null||p.call(g,{type:"start",meta:e.meta,deps:s});let f;try{f=R.current(t.withUse({signal:i.signal}))}catch(j){return u({type:"ERROR",error:j}),(x=(v=A.onDispatchHook).current)==null||x.call(v,{type:"error",meta:e.meta,deps:s,error:j}),Object.assign(Promise.reject(j),{abort:()=>i.abort()})}if(t.isPromiseLike(f)){const j=f;return(O=(q=A.onDispatchHook).current)==null||O.call(q,{type:"loading",meta:e.meta,deps:s}),j.then(S=>{c.current===i&&(u({type:"SUCCESS",result:S}),A.onDispatchHook.current&&A.onDispatchHook.current({type:"resolved",meta:e.meta,deps:s}))},S=>{if(S instanceof DOMException&&S.name==="AbortError"){(c.current===null||c.current===i)&&(u({type:"ERROR",error:S}),A.onDispatchHook.current&&A.onDispatchHook.current({type:"abort",meta:e.meta,deps:s,error:S}));return}c.current===i&&(u({type:"ERROR",error:S}),A.onDispatchHook.current&&A.onDispatchHook.current({type:"rejected",meta:e.meta,deps:s,error:S}))}),Object.assign(j,{abort:()=>{i.abort(),c.current===i&&(c.current=null)}})}else A.onDispatchHook.current&&A.onDispatchHook.current({type:"success",meta:e.meta,deps:s});return u({type:"SUCCESS",result:f}),Object.assign(Promise.resolve(f),{abort:()=>i.abort()})},[m,l]),E=(s??[]).filter(i=>!t.isAtom(i));o.useEffect(()=>{n||b()},[n,...k,...E]),o.useEffect(()=>()=>{m&&l()},[m,l]);const D=o.useCallback(()=>{m&&l(),u({type:"RESET"})},[m,l]);return Object.assign(b,{...a,abort:l,reset:D})}function U(r,e){const n=e===void 0?void 0:typeof e=="object"&&e!==null&&!Array.isArray(e)&&("equals"in e||"loading"in e||"error"in e)?e:{equals:e};return d.jsx(J,{selectorOrAtom:r,options:n})}class V extends o.Component{constructor(){super(...arguments);w(this,"state",{error:null})}static getDerivedStateFromError(n){return{error:n}}componentDidCatch(n,m){}render(){if(this.state.error!==null&&this.props.onError)return d.jsx(d.Fragment,{children:this.props.onError({error:this.state.error})});if(this.state.error!==null)throw this.state.error;return this.props.children}}function W(r){const e=C(r.selector,r.equals);return d.jsx(d.Fragment,{children:e??null})}function B(r){return d.jsx(d.Fragment,{children:r.render()})}function G(r){return r.fallback?d.jsx(o.Suspense,{fallback:d.jsx(B,{render:r.fallback}),children:r.children}):d.jsx(d.Fragment,{children:r.children})}function N(r){return r.onError?d.jsx(V,{onError:r.onError,children:r.children}):d.jsx(d.Fragment,{children:r.children})}const J=o.memo(function(e){var u,c,R,l;const n=o.useRef(e.selectorOrAtom);n.current=e.selectorOrAtom;const m=t.isAtom(e.selectorOrAtom),s=(u=e.options)==null?void 0:u.deps,h=m?[e.selectorOrAtom,...s??[]]:s??[{}],a=o.useCallback(y=>t.isAtom(n.current)?y.read(n.current):n.current(y),h);return d.jsx(N,{onError:(c=e.options)==null?void 0:c.error,children:d.jsx(G,{fallback:(R=e.options)==null?void 0:R.loading,children:d.jsx(W,{selector:a,equals:(l=e.options)==null?void 0:l.equals})})})},(r,e)=>t.shallowEqual(r.selectorOrAtom,e.selectorOrAtom)&&t.shallowEqual(r.options,e.options));exports.AllAtomsRejectedError=t.AllAtomsRejectedError;exports.abortable=t.abortable;exports.atom=t.atom;exports.batch=t.batch;exports.createAbortError=t.createAbortError;exports.createRejectedPromise=t.createRejectedPromise;exports.createResolvedPromise=t.createResolvedPromise;exports.define=t.define;exports.derived=t.derived;exports.effect=t.effect;exports.emitter=t.emitter;exports.event=t.event;exports.getAtomState=t.getAtomState;exports.isAbortError=t.isAbortError;exports.isAtom=t.isAtom;exports.isDerived=t.isDerived;exports.isEvent=t.isEvent;exports.isFulfilled=t.isFulfilled;exports.isPending=t.isPending;exports.isPool=t.isPool;exports.isRejected=t.isRejected;exports.isScopedAtom=t.isScopedAtom;exports.pool=t.pool;exports.promisesEqual=t.promisesEqual;exports.readonly=t.readonly;exports.select=t.select;exports.trackPromise=t.trackPromise;exports.unwrap=t.unwrap;exports.onCreateHook=H.onCreateHook;exports.onErrorHook=H.onErrorHook;exports.rx=U;exports.useAction=M;exports.useSelector=C;exports.useStable=I;
|
package/dist/react/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
var M = Object.defineProperty;
|
|
2
2
|
var V = (r, e, t) => e in r ? M(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
|
|
3
|
-
var
|
|
4
|
-
import { useRef as
|
|
5
|
-
import { i as O, r as w, s as F, t as I, d as K, a as q, w as Q, b as X } from "../index-
|
|
6
|
-
import { A as he, c as Re,
|
|
3
|
+
var P = (r, e, t) => V(r, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { useRef as b, useCallback as D, useSyncExternalStore as B, useReducer as G, useEffect as _, memo as W, Suspense as N, Component as J } from "react";
|
|
5
|
+
import { i as O, r as w, s as F, t as I, d as K, a as q, w as Q, b as X } from "../index-DbZ2r2Im.js";
|
|
6
|
+
import { A as he, c as Re, g as Ee, j as ye, f as Se, G as Ae, F as ve, k as ge, l as De, m as Oe, n as je, o as Ce, y as ke, e as xe, q as we, p as qe, B as Te, z as ze, v as Pe, C as _e, x as Fe, u as Ie, H as He, h as Le, D as Ue, E as Me } from "../index-DbZ2r2Im.js";
|
|
7
7
|
import { o as E } from "../onDispatchHook-SKbiIUaJ.js";
|
|
8
|
-
import { jsx as
|
|
9
|
-
import { o as
|
|
10
|
-
function
|
|
11
|
-
const t = O(r) ? ({ read: f }) => f(r) : r, l = w(e ?? "shallow"), n =
|
|
8
|
+
import { jsx as p, Fragment as j } from "react/jsx-runtime";
|
|
9
|
+
import { o as Be, a as Ge } from "../onErrorHook-BGGy3tqK.js";
|
|
10
|
+
function H(r, e) {
|
|
11
|
+
const t = O(r) ? ({ read: f }) => f(r) : r, l = w(e ?? "shallow"), n = b(t), h = b(l);
|
|
12
12
|
n.current = t, h.current = l;
|
|
13
|
-
const
|
|
13
|
+
const a = b(/* @__PURE__ */ new Map()), s = b(/* @__PURE__ */ new Set()), o = b([]), m = b(/* @__PURE__ */ new Map()), u = b({
|
|
14
14
|
value: void 0,
|
|
15
15
|
initialized: !1
|
|
16
16
|
}), y = D(() => {
|
|
@@ -20,23 +20,23 @@ function L(r, e) {
|
|
|
20
20
|
if (f.error !== void 0)
|
|
21
21
|
throw f.error;
|
|
22
22
|
const R = f.value;
|
|
23
|
-
return (!
|
|
23
|
+
return (!u.current.initialized || !h.current(R, u.current.value)) && (u.current = { value: R, initialized: !0 }), u.current.value;
|
|
24
24
|
}, []), A = D((f) => {
|
|
25
|
-
const R =
|
|
25
|
+
const R = a.current, C = () => {
|
|
26
26
|
const { result: i } = F(n.current);
|
|
27
27
|
s.current = i._atomDeps, m.current = i._poolDeps, c(), f();
|
|
28
28
|
}, c = () => {
|
|
29
|
-
const i = s.current,
|
|
29
|
+
const i = s.current, k = m.current;
|
|
30
30
|
for (const [d, v] of R)
|
|
31
31
|
i.has(d) || (v(), R.delete(d));
|
|
32
32
|
for (const d of i)
|
|
33
|
-
R.has(d) || R.set(d, d.on(
|
|
33
|
+
R.has(d) || R.set(d, d.on(C));
|
|
34
34
|
for (const d of o.current)
|
|
35
35
|
d();
|
|
36
36
|
o.current = [];
|
|
37
|
-
for (const [d, v] of
|
|
38
|
-
for (const
|
|
39
|
-
o.current.push(d._onRemove(
|
|
37
|
+
for (const [d, v] of k)
|
|
38
|
+
for (const x of v)
|
|
39
|
+
o.current.push(d._onRemove(x, C));
|
|
40
40
|
};
|
|
41
41
|
return c(), () => {
|
|
42
42
|
for (const i of R.values())
|
|
@@ -47,17 +47,17 @@ function L(r, e) {
|
|
|
47
47
|
o.current = [];
|
|
48
48
|
};
|
|
49
49
|
}, []);
|
|
50
|
-
return
|
|
50
|
+
return B(A, y, y);
|
|
51
51
|
}
|
|
52
52
|
function Y(r) {
|
|
53
53
|
return r == null ? Object.is : Array.isArray(r) ? "shallow" : r instanceof Date ? K : typeof r == "object" ? q : Object.is;
|
|
54
54
|
}
|
|
55
55
|
function fe(r, e) {
|
|
56
|
-
const t =
|
|
56
|
+
const t = b({}), l = b(null);
|
|
57
57
|
l.current === null && (l.current = {});
|
|
58
58
|
const n = t.current, h = l.current;
|
|
59
|
-
for (const
|
|
60
|
-
const s = r[
|
|
59
|
+
for (const a of Object.keys(r)) {
|
|
60
|
+
const s = r[a], o = n[a];
|
|
61
61
|
if (typeof s == "function") {
|
|
62
62
|
const [A] = I(
|
|
63
63
|
o,
|
|
@@ -65,25 +65,25 @@ function fe(r, e) {
|
|
|
65
65
|
() => !1
|
|
66
66
|
// Equality doesn't matter for functions
|
|
67
67
|
);
|
|
68
|
-
n[
|
|
68
|
+
n[a] = { value: A }, h[a] = A;
|
|
69
69
|
continue;
|
|
70
70
|
}
|
|
71
|
-
const m = e == null ? void 0 : e[
|
|
71
|
+
const m = e == null ? void 0 : e[a], u = m ? w(m) : w(Y(s)), [y] = I(
|
|
72
72
|
o,
|
|
73
73
|
s,
|
|
74
|
-
|
|
74
|
+
u
|
|
75
75
|
);
|
|
76
|
-
n[
|
|
76
|
+
n[a] = { value: y }, h[a] = y;
|
|
77
77
|
}
|
|
78
|
-
for (const
|
|
79
|
-
|
|
78
|
+
for (const a of Object.keys(n))
|
|
79
|
+
a in r || (delete n[a], delete h[a]);
|
|
80
80
|
return h;
|
|
81
81
|
}
|
|
82
|
-
const
|
|
82
|
+
const L = {
|
|
83
83
|
status: "idle",
|
|
84
84
|
result: void 0,
|
|
85
85
|
error: void 0
|
|
86
|
-
},
|
|
86
|
+
}, U = {
|
|
87
87
|
status: "loading",
|
|
88
88
|
result: void 0,
|
|
89
89
|
error: void 0
|
|
@@ -91,7 +91,7 @@ const U = {
|
|
|
91
91
|
function Z(r, e) {
|
|
92
92
|
switch (e.type) {
|
|
93
93
|
case "START":
|
|
94
|
-
return
|
|
94
|
+
return U;
|
|
95
95
|
case "SUCCESS":
|
|
96
96
|
return {
|
|
97
97
|
status: "success",
|
|
@@ -105,30 +105,30 @@ function Z(r, e) {
|
|
|
105
105
|
error: e.error
|
|
106
106
|
};
|
|
107
107
|
case "RESET":
|
|
108
|
-
return
|
|
108
|
+
return L;
|
|
109
109
|
default:
|
|
110
110
|
return r;
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
function de(r, e = {}) {
|
|
114
|
-
const { lazy: t = !0, exclusive: l = !0, deps: n = [] } = e, h = t ?
|
|
114
|
+
const { lazy: t = !0, exclusive: l = !0, deps: n = [] } = e, h = t ? L : U, [a, s] = G(
|
|
115
115
|
Z,
|
|
116
116
|
h
|
|
117
|
-
), o =
|
|
117
|
+
), o = b(null), m = b(r);
|
|
118
118
|
m.current = r;
|
|
119
|
-
const
|
|
119
|
+
const u = D(() => {
|
|
120
120
|
const c = o.current;
|
|
121
121
|
return c ? (c.abort(), o.current = null, !0) : !1;
|
|
122
|
-
}, []), y = (t ? [] : n ?? []).filter(O), A =
|
|
123
|
-
var
|
|
124
|
-
l &&
|
|
122
|
+
}, []), y = (t ? [] : n ?? []).filter(O), A = H(({ read: c }) => y.map((i) => c(i))), f = D(() => {
|
|
123
|
+
var k, d, v, x, T, z;
|
|
124
|
+
l && u();
|
|
125
125
|
const c = new AbortController();
|
|
126
|
-
o.current = c, s({ type: "START" }), (d = (
|
|
126
|
+
o.current = c, s({ type: "START" }), (d = (k = E).current) == null || d.call(k, { type: "start", meta: e.meta, deps: n });
|
|
127
127
|
let i;
|
|
128
128
|
try {
|
|
129
129
|
i = m.current(Q({ signal: c.signal }));
|
|
130
130
|
} catch (g) {
|
|
131
|
-
return s({ type: "ERROR", error: g }), (
|
|
131
|
+
return s({ type: "ERROR", error: g }), (x = (v = E).current) == null || x.call(v, {
|
|
132
132
|
type: "error",
|
|
133
133
|
meta: e.meta,
|
|
134
134
|
deps: n,
|
|
@@ -182,24 +182,24 @@ function de(r, e = {}) {
|
|
|
182
182
|
return s({ type: "SUCCESS", result: i }), Object.assign(Promise.resolve(i), {
|
|
183
183
|
abort: () => c.abort()
|
|
184
184
|
});
|
|
185
|
-
}, [l,
|
|
186
|
-
|
|
185
|
+
}, [l, u]), R = (n ?? []).filter((c) => !O(c));
|
|
186
|
+
_(() => {
|
|
187
187
|
t || f();
|
|
188
|
-
}, [t, ...A, ...R]),
|
|
189
|
-
l &&
|
|
190
|
-
}, [l,
|
|
191
|
-
const
|
|
192
|
-
l &&
|
|
193
|
-
}, [l,
|
|
188
|
+
}, [t, ...A, ...R]), _(() => () => {
|
|
189
|
+
l && u();
|
|
190
|
+
}, [l, u]);
|
|
191
|
+
const C = D(() => {
|
|
192
|
+
l && u(), s({ type: "RESET" });
|
|
193
|
+
}, [l, u]);
|
|
194
194
|
return Object.assign(f, {
|
|
195
|
-
...
|
|
196
|
-
abort:
|
|
197
|
-
reset:
|
|
195
|
+
...a,
|
|
196
|
+
abort: u,
|
|
197
|
+
reset: C
|
|
198
198
|
});
|
|
199
199
|
}
|
|
200
200
|
function me(r, e) {
|
|
201
201
|
const t = e === void 0 ? void 0 : typeof e == "object" && e !== null && !Array.isArray(e) && ("equals" in e || "loading" in e || "error" in e) ? e : { equals: e };
|
|
202
|
-
return /* @__PURE__ */
|
|
202
|
+
return /* @__PURE__ */ p(
|
|
203
203
|
oe,
|
|
204
204
|
{
|
|
205
205
|
selectorOrAtom: r,
|
|
@@ -210,7 +210,7 @@ function me(r, e) {
|
|
|
210
210
|
class $ extends J {
|
|
211
211
|
constructor() {
|
|
212
212
|
super(...arguments);
|
|
213
|
-
|
|
213
|
+
P(this, "state", { error: null });
|
|
214
214
|
}
|
|
215
215
|
static getDerivedStateFromError(t) {
|
|
216
216
|
return { error: t };
|
|
@@ -220,64 +220,71 @@ class $ extends J {
|
|
|
220
220
|
}
|
|
221
221
|
render() {
|
|
222
222
|
if (this.state.error !== null && this.props.onError)
|
|
223
|
-
return /* @__PURE__ */
|
|
223
|
+
return /* @__PURE__ */ p(j, { children: this.props.onError({ error: this.state.error }) });
|
|
224
224
|
if (this.state.error !== null)
|
|
225
225
|
throw this.state.error;
|
|
226
226
|
return this.props.children;
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
function ee(r) {
|
|
230
|
-
const e =
|
|
231
|
-
return /* @__PURE__ */
|
|
230
|
+
const e = H(r.selector, r.equals);
|
|
231
|
+
return /* @__PURE__ */ p(j, { children: e ?? null });
|
|
232
232
|
}
|
|
233
233
|
function re(r) {
|
|
234
|
-
return /* @__PURE__ */
|
|
234
|
+
return /* @__PURE__ */ p(j, { children: r.render() });
|
|
235
235
|
}
|
|
236
236
|
function te(r) {
|
|
237
|
-
return r.fallback ? /* @__PURE__ */
|
|
237
|
+
return r.fallback ? /* @__PURE__ */ p(N, { fallback: /* @__PURE__ */ p(re, { render: r.fallback }), children: r.children }) : /* @__PURE__ */ p(j, { children: r.children });
|
|
238
238
|
}
|
|
239
239
|
function ne(r) {
|
|
240
|
-
return r.onError ? /* @__PURE__ */
|
|
240
|
+
return r.onError ? /* @__PURE__ */ p($, { onError: r.onError, children: r.children }) : /* @__PURE__ */ p(j, { children: r.children });
|
|
241
241
|
}
|
|
242
|
-
const oe =
|
|
242
|
+
const oe = W(
|
|
243
243
|
function(e) {
|
|
244
|
-
var s, o, m,
|
|
245
|
-
const t =
|
|
244
|
+
var s, o, m, u;
|
|
245
|
+
const t = b(e.selectorOrAtom);
|
|
246
246
|
t.current = e.selectorOrAtom;
|
|
247
|
-
const l = O(e.selectorOrAtom), n = (s = e.options) == null ? void 0 : s.deps, h = l ? [e.selectorOrAtom, ...n ?? []] : n ?? [{}],
|
|
247
|
+
const l = O(e.selectorOrAtom), n = (s = e.options) == null ? void 0 : s.deps, h = l ? [e.selectorOrAtom, ...n ?? []] : n ?? [{}], a = D(
|
|
248
248
|
(y) => O(t.current) ? y.read(t.current) : t.current(y),
|
|
249
249
|
h
|
|
250
250
|
);
|
|
251
|
-
return /* @__PURE__ */
|
|
251
|
+
return /* @__PURE__ */ p(ne, { onError: (o = e.options) == null ? void 0 : o.error, children: /* @__PURE__ */ p(te, { fallback: (m = e.options) == null ? void 0 : m.loading, children: /* @__PURE__ */ p(ee, { selector: a, equals: (u = e.options) == null ? void 0 : u.equals }) }) });
|
|
252
252
|
},
|
|
253
253
|
(r, e) => q(r.selectorOrAtom, e.selectorOrAtom) && q(r.options, e.options)
|
|
254
254
|
);
|
|
255
255
|
export {
|
|
256
256
|
he as AllAtomsRejectedError,
|
|
257
|
-
Re as
|
|
258
|
-
Ee as
|
|
259
|
-
ye as
|
|
260
|
-
Se as
|
|
261
|
-
Ae as
|
|
262
|
-
ve as
|
|
263
|
-
ge as
|
|
257
|
+
Re as abortable,
|
|
258
|
+
Ee as atom,
|
|
259
|
+
ye as batch,
|
|
260
|
+
Se as createAbortError,
|
|
261
|
+
Ae as createRejectedPromise,
|
|
262
|
+
ve as createResolvedPromise,
|
|
263
|
+
ge as define,
|
|
264
|
+
De as derived,
|
|
265
|
+
Oe as effect,
|
|
266
|
+
je as emitter,
|
|
267
|
+
Ce as event,
|
|
268
|
+
ke as getAtomState,
|
|
269
|
+
xe as isAbortError,
|
|
264
270
|
O as isAtom,
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
Fe as
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
271
|
+
we as isDerived,
|
|
272
|
+
qe as isEvent,
|
|
273
|
+
Te as isFulfilled,
|
|
274
|
+
ze as isPending,
|
|
275
|
+
Pe as isPool,
|
|
276
|
+
_e as isRejected,
|
|
277
|
+
Fe as isScopedAtom,
|
|
278
|
+
Be as onCreateHook,
|
|
279
|
+
Ge as onErrorHook,
|
|
280
|
+
Ie as pool,
|
|
281
|
+
He as promisesEqual,
|
|
282
|
+
Le as readonly,
|
|
276
283
|
me as rx,
|
|
277
284
|
F as select,
|
|
278
|
-
|
|
279
|
-
|
|
285
|
+
Ue as trackPromise,
|
|
286
|
+
Me as unwrap,
|
|
280
287
|
de as useAction,
|
|
281
|
-
|
|
288
|
+
H as useSelector,
|
|
282
289
|
fe as useStable
|
|
283
290
|
};
|
package/package.json
CHANGED
package/skills/atomirx/SKILL.md
CHANGED
|
@@ -106,6 +106,7 @@ main();
|
|
|
106
106
|
| `atom<T>(initial)` | Mutable state | No |
|
|
107
107
|
| `derived(fn)` | Computed value | Yes (lazy) |
|
|
108
108
|
| `effect(fn)` | Side effects on changes | Yes (eager) |
|
|
109
|
+
| `event<T>(opts)` | Block until fired | Yes |
|
|
109
110
|
| `select(fn)` | One-time read, no subscription | No |
|
|
110
111
|
| `pool(fn, opts)` | Parameterized atoms with GC | Per-entry |
|
|
111
112
|
| `batch(fn)` | Group updates, single notify | No |
|
|
@@ -113,25 +114,131 @@ main();
|
|
|
113
114
|
| `onCreateHook` | Track atom/effect creation | No |
|
|
114
115
|
| `onErrorHook` | Global error handling | No |
|
|
115
116
|
|
|
117
|
+
## Events (Block Until Fired)
|
|
118
|
+
|
|
119
|
+
Events block computation until `fire()` is called. Useful for user-driven workflows.
|
|
120
|
+
|
|
121
|
+
### event vs atom\<Promise\<T\>\>
|
|
122
|
+
|
|
123
|
+
| Aspect | `atom<Promise<T>>` | `event<T>` |
|
|
124
|
+
|--------|-------------------|------------|
|
|
125
|
+
| Initial state | Promise you provide | Pending (no data) |
|
|
126
|
+
| Set value | `.set(promise)` | `.fire(data)` |
|
|
127
|
+
| First update | Replaces promise | Resolves pending |
|
|
128
|
+
| Get last value | Track yourself | `.last()` built-in |
|
|
129
|
+
| Use case | Async data fetching | User signals |
|
|
130
|
+
|
|
131
|
+
### Event API
|
|
132
|
+
|
|
133
|
+
| Method | Description |
|
|
134
|
+
|--------|-------------|
|
|
135
|
+
| `fire(payload)` | Fire event with payload |
|
|
136
|
+
| `get()` | Current promise (may be resolved) |
|
|
137
|
+
| `next()` | Pending promise for next meaningful fire |
|
|
138
|
+
| `on(listener)` | Subscribe to changes |
|
|
139
|
+
| `last()` | Last fired payload |
|
|
140
|
+
| `fireCount` | Count of meaningful fires |
|
|
141
|
+
| `sealed()` | True if `once` and already fired |
|
|
142
|
+
|
|
143
|
+
### get() vs next()
|
|
144
|
+
|
|
145
|
+
| | `get()` | `next()` |
|
|
146
|
+
|--|---------|----------|
|
|
147
|
+
| Returns | Current promise | Pending promise |
|
|
148
|
+
| After fire | Same resolved | New pending |
|
|
149
|
+
| Use case | Reactive | Imperative |
|
|
150
|
+
|
|
151
|
+
`next()` respects `equals` - duplicate fires won't resolve.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { event, derived, effect } from "atomirx";
|
|
155
|
+
|
|
156
|
+
// Create event
|
|
157
|
+
const submitEvent = event<FormData>({ meta: { key: "form.submit" } });
|
|
158
|
+
const cancelEvent = event({ meta: { key: "form.cancel" } }); // void payload
|
|
159
|
+
|
|
160
|
+
// In derived - suspends until fire()
|
|
161
|
+
const result$ = derived(({ read }) => {
|
|
162
|
+
const data = read(submitEvent); // Blocks until submitEvent.fire(data)
|
|
163
|
+
return processForm(data);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// In effect - suspends until fire()
|
|
167
|
+
effect(({ read }) => {
|
|
168
|
+
const data = read(submitEvent);
|
|
169
|
+
console.log("Form submitted:", data);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Race multiple events
|
|
173
|
+
const outcome$ = derived(({ race }) => {
|
|
174
|
+
const { key, value } = race({
|
|
175
|
+
submit: submitEvent,
|
|
176
|
+
cancel: cancelEvent,
|
|
177
|
+
});
|
|
178
|
+
return key === "cancel" ? null : processForm(value);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Fire the event (from user action)
|
|
182
|
+
function handleSubmit(data: FormData) {
|
|
183
|
+
submitEvent.fire(data);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Imperative awaiting with next()
|
|
187
|
+
async function processClicks() {
|
|
188
|
+
while (true) {
|
|
189
|
+
const data = await clickEvent.next();
|
|
190
|
+
handleClick(data);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### once Option (One-Time Events)
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
const initEvent = event<Config>({ once: true });
|
|
199
|
+
|
|
200
|
+
initEvent.fire(config); // Promise resolved
|
|
201
|
+
initEvent.fire(config2); // No-op (already fired)
|
|
202
|
+
initEvent.get(); // Same resolved promise
|
|
203
|
+
initEvent.next(); // Same resolved promise
|
|
204
|
+
|
|
205
|
+
// Late subscriber - triggers immediately
|
|
206
|
+
initEvent.on(() => console.log("init done")); // Logs immediately
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
| Behavior | `once: false` | `once: true` |
|
|
210
|
+
|----------|--------------|--------------|
|
|
211
|
+
| Multiple `fire()` | New promises | First only |
|
|
212
|
+
| `next()` after fire | New pending | Same resolved |
|
|
213
|
+
| `on()` after fire | Normal | Triggers immediately |
|
|
214
|
+
|
|
215
|
+
**Key Points:**
|
|
216
|
+
- `read(event)` suspends until `fire()` is called (like waiting for staleValue)
|
|
217
|
+
- Works with `race()`, `all()` for waiting on multiple user actions
|
|
218
|
+
- Each `fire()` after the first creates a new promise → triggers reactive updates
|
|
219
|
+
- Use `equals` option to dedupe identical payloads
|
|
220
|
+
- Use `once: true` for one-time events (init, login)
|
|
221
|
+
- **NOT for promise flow control** (timeouts, retries) — use `abortable()` for those
|
|
222
|
+
|
|
116
223
|
## SelectContext Methods
|
|
117
224
|
|
|
118
225
|
**Works identically in `derived()`, `effect()`, `useSelector()`, `rx()`.** Learn once, use everywhere.
|
|
119
226
|
|
|
120
|
-
| Method | Signature
|
|
121
|
-
| ----------- |
|
|
122
|
-
| `read()` | `read(atom$)`
|
|
123
|
-
| `ready()` | `ready(atom$)` or
|
|
124
|
-
| `from()` | `from(pool, params)`
|
|
125
|
-
| `track()` | `track(atom$)`
|
|
126
|
-
| `untrack()` | `untrack(atom$)` or fn
|
|
127
|
-
| `safe()` | `safe(() => expr)`
|
|
128
|
-
| `all()` | `all([a$, b$])`
|
|
129
|
-
| `any()` | `any({ a: a$, b: b$ })`
|
|
130
|
-
| `race()` | `race({ a: a$, b: b$ })`
|
|
131
|
-
| `settled()` | `settled([a$, b$])`
|
|
132
|
-
| `state()` | `state(atom$)`
|
|
133
|
-
| `and()` | `and([cond1, cond2])`
|
|
134
|
-
| `or()` | `or([cond1, cond2])`
|
|
227
|
+
| Method | Signature | Behavior |
|
|
228
|
+
| ----------- | -------------------------------- | ----------------------------------------- |
|
|
229
|
+
| `read()` | `read(atom$)` | Read + track dependency |
|
|
230
|
+
| `ready()` | `ready(atom$)` or `ready(array)` | Wait for non-null (suspends) |
|
|
231
|
+
| `from()` | `from(pool, params)` | Get ScopedAtom from pool |
|
|
232
|
+
| `track()` | `track(atom$)` | Track without reading |
|
|
233
|
+
| `untrack()` | `untrack(atom$)` or fn | Read/exec without tracking |
|
|
234
|
+
| `safe()` | `safe(() => expr)` | Catch errors, preserve Suspense |
|
|
235
|
+
| `all()` | `all([a$, b$])` | Wait for all (Promise.all) |
|
|
236
|
+
| `any()` | `any({ a: a$, b: b$ })` | First ready (discriminated union) |
|
|
237
|
+
| `race()` | `race({ a: a$, b: b$ })` | First settled (discriminated union) |
|
|
238
|
+
| `settled()` | `settled([a$, b$])` | All results (Promise.allSettled) |
|
|
239
|
+
| `state()` | `state(atom$)` | Get state without throwing |
|
|
240
|
+
| `and()` | `and([cond1, cond2])` | Logical AND, short-circuit |
|
|
241
|
+
| `or()` | `or([cond1, cond2])` | Logical OR, short-circuit |
|
|
135
242
|
|
|
136
243
|
```typescript
|
|
137
244
|
// Same pattern works everywhere
|
|
@@ -149,6 +256,38 @@ effect(pattern);
|
|
|
149
256
|
}
|
|
150
257
|
```
|
|
151
258
|
|
|
259
|
+
### race()/any() Discriminated Union
|
|
260
|
+
|
|
261
|
+
`race()` and `any()` return discriminated unions — checking `key` narrows `value` type:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
const result = race({ num: numAtom$, str: strAtom$ });
|
|
265
|
+
|
|
266
|
+
if (result.key === "num") {
|
|
267
|
+
result.value; // narrowed to number
|
|
268
|
+
} else {
|
|
269
|
+
result.value; // narrowed to string
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Tuple destructuring also works
|
|
273
|
+
const [winner, value] = result;
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### ready() with Async Utilities
|
|
277
|
+
|
|
278
|
+
Use `ready()` to ensure values from `all()`, `race()`, or `any()` are non-null:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
// ready() + all() — suspend if any value is null/undefined
|
|
282
|
+
const [user, posts] = ready(all([user$, posts$]));
|
|
283
|
+
|
|
284
|
+
// ready() + race() — suspend if winning value is null, preserves narrowing
|
|
285
|
+
const result = ready(race({ cache: cache$, api: api$ }));
|
|
286
|
+
if (result.key === "cache") {
|
|
287
|
+
result.value; // narrowed to cache type (non-null)
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
152
291
|
## read() vs ready() vs state()
|
|
153
292
|
|
|
154
293
|
| Method | On null/undefined | On loading | Use Case |
|