atom.io 0.40.4 → 0.40.5

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.
@@ -19,21 +19,39 @@ declare function useJSON<T extends Transceiver<any, any, any>>(token: MutableAto
19
19
  declare function useJSON<T extends Transceiver<any, any, any>, K extends Canonical>(token: MutableAtomFamilyToken<T, K>, key: K): AsJSON<T>;
20
20
  //#endregion
21
21
  //#region src/react/use-loadable.d.ts
22
+ declare function useLoadable<T>(token: ReadableToken<Loadable<T>, any, never>): `LOADING` | {
23
+ loading: boolean;
24
+ value: T;
25
+ };
26
+ declare function useLoadable<T, K extends Canonical, Key extends K>(token: ReadableFamilyToken<Loadable<T>, K, never>, key: Key): `LOADING` | {
27
+ loading: boolean;
28
+ value: T;
29
+ };
30
+ declare function useLoadable<T, F extends T>(token: ReadableToken<Loadable<T>, any, never>, fallback: F): {
31
+ loading: boolean;
32
+ value: T;
33
+ };
34
+ declare function useLoadable<T, K extends Canonical, F extends T, Key extends K>(token: ReadableFamilyToken<Loadable<T>, K, never>, key: Key, fallback: F): {
35
+ loading: boolean;
36
+ value: T;
37
+ };
22
38
  declare function useLoadable<T, E>(token: ReadableToken<Loadable<T>, any, E>): `LOADING` | {
23
39
  loading: boolean;
24
40
  value: E | T;
25
41
  };
26
- declare function useLoadable<T, K extends Canonical, E>(token: ReadableFamilyToken<Loadable<T>, K, E>, key: K): `LOADING` | {
42
+ declare function useLoadable<T, K extends Canonical, Key extends K, E>(token: ReadableFamilyToken<Loadable<T>, K, E>, key: Key): `LOADING` | {
27
43
  loading: boolean;
28
44
  value: E | T;
29
45
  };
30
46
  declare function useLoadable<T, F extends T, E>(token: ReadableToken<Loadable<T>, any, E>, fallback: F): {
31
47
  loading: boolean;
32
48
  value: T;
49
+ error?: E;
33
50
  };
34
- declare function useLoadable<T, K extends Canonical, F extends T, E>(token: ReadableFamilyToken<Loadable<T>, K, E>, key: K, fallback: F): {
51
+ declare function useLoadable<T, K extends Canonical, F extends T, Key extends K, E>(token: ReadableFamilyToken<Loadable<T>, K, E>, key: Key, fallback: F): {
35
52
  loading: boolean;
36
- value: E | T;
53
+ value: T;
54
+ error?: E;
37
55
  };
38
56
  //#endregion
39
57
  //#region src/react/use-o.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":["StoreContext: React.Context<RootStore>","StoreProvider: React.FC<{\n\tchildren: React.ReactNode\n\tstore?: RootStore\n}>"],"sources":["../../src/react/store-context.tsx","../../src/react/use-i.ts","../../src/react/use-json.ts","../../src/react/use-loadable.ts","../../src/react/use-o.ts","../../src/react/use-tl.ts"],"sourcesContent":[],"mappings":";;;;;;cAIaA,cAAc,OAAA,CAAM,QAAQ;cAI5BC,eAAe,OAAA,CAAM;YACvB,OAAA,CAAM;UACR;AANT,CAAA,CAAA;;;iBCIgB,eACR,cAAc,4BACN,SAAS,aAAa,MAAM;iBAE5B,kBAAkB,WDRlC,YCQyD,CDR5CD,CAA4B,CAAA,KAAA,ECSjC,mBDTiC,CCSb,CDTa,ECSV,CDTU,EAAA,GAAA,CAAA,EAAA,GAAA,ECUnC,GDVmC,CAAA,EAAA,CAAA,YCWzB,CDXyB,CAAA,CAAA,IAAA,ECWhB,GDXgB,GAAA,CAAA,CAAA,GAAA,ECWH,CDXG,EAAA,GCWG,GDXH,CAAA,EAAA,GAAA,IAAA;;;iBEKzB,kBAAkB,mCAC1B,iBAAiB,KACtB,OAAO;iBAEM,kBACL,4BFVX,UEWW,SFX8B,CAAA,CAAA,KAAA,EEYhC,sBFZgC,CEYT,CFZS,EEYN,CFZM,CAAA,EAAA,GAAA,EEYG,CFZH,CAAA,EEYO,MFZP,CEYc,CFZd,CAAA;;;iBGEzB,iBHFhB,CAAA,KAAaA,EGGL,aHHiC,CGGnB,QHHmB,CGGV,CHHU,CAAA,EAAA,GAAA,EGGD,CHHC,CAAA,CAAA,EAAA,SAAA,GAAA;EAAA,OAAA,EAAA,OAAA;SGIC,CHJD,GGIK,CHJL;;iBGMzB,YHFhB,CAAA,YGEyC,mBHAhC,EGCD,mBHDC,CGCmB,QHDnB,CGC4B,CHD5B,CAAA,EGCgC,CHDhC,EGCmC,CHDnC,CAAA,EAAA,GAAA,EGEH,CHFG,CAAA,EAAA,SAAA,GAAA;SAFmB,EAAA,OAAM;SGKQ,IAAI;;iBAE9B,eFPhB,UEOyC,CFPzB,EAAA,CAAA,OACM,EEOd,aFPc,CEOA,QFPA,CEOS,CFPT,CAAA,EAAA,GAAA,EEOkB,CFPlB,CAAA,EAAA,QAAA,EEQX,CFRW,CAAA,EAAA;SAAd,EAAA,OAAA;SESsB,CFRd;;AAAsB,iBEUtB,WFVsB,cEUG,WFRzC,UEQ8D,CFR9C,EAAA,CAAA,OAAkB,EES1B,mBFT0B,CESN,QFTM,CESG,CFTH,CAAA,EESO,CFTP,EESU,CFTV,CAAA,EAAA,GAAA,EEU5B,CFV4B,EAAA,QAAA,EEWvB,CFXuB,CAAA,EAAA;SAAuB,EAAA,OAAA;SEY3B,CFXF,GEWM,CFXN;;;;iBGLZ,kBAAkB,cAAc,QAAQ,KAAK,IAAI;AJJpDA,iBIMG,IJNyB,CAAA,CAAA,YIMP,SJNO,cIMgB,CJN9B,IAI3B,CAAA,KAAaC,EIGL,mBJHKA,CIGe,CJHfA,EIGkB,CJHlBA,EIGqB,CJHrBA,CAAAA,EAAAA,GAAAA,EIIP,GJJOA,CAAAA,EIKV,CJLUA,GIKN,CJLMA;;;KKDD,YAAA;;;;;ALHZ,CAAA;AAAyC,iBKUzB,KAAA,CLVyB,KAAA,EKUZ,aLVY,CAAA,GAAA,CAAA,CAAA,EKUS,YLVT"}
1
+ {"version":3,"file":"index.d.ts","names":["StoreContext: React.Context<RootStore>","StoreProvider: React.FC<{\n\tchildren: React.ReactNode\n\tstore?: RootStore\n}>"],"sources":["../../src/react/store-context.tsx","../../src/react/use-i.ts","../../src/react/use-json.ts","../../src/react/use-loadable.ts","../../src/react/use-o.ts","../../src/react/use-tl.ts"],"sourcesContent":[],"mappings":";;;;;;cAIaA,cAAc,OAAA,CAAM,QAAQ;cAI5BC,eAAe,OAAA,CAAM;YACvB,OAAA,CAAM;UACR;AANT,CAAA,CAAA;;;iBCIgB,eACR,cAAc,4BACN,SAAS,aAAa,MAAM;iBAE5B,kBAAkB,WDRlC,YCQyD,CDR5CD,CAA4B,CAAA,KAAA,ECSjC,mBDTiC,CCSb,CDTa,ECSV,CDTU,EAAA,GAAA,CAAA,EAAA,GAAA,ECUnC,GDVmC,CAAA,EAAA,CAAA,YCWzB,CDXyB,CAAA,CAAA,IAAA,ECWhB,GDXgB,GAAA,CAAA,CAAA,GAAA,ECWH,CDXG,EAAA,GCWG,GDXH,CAAA,EAAA,GAAA,IAAA;;;iBEKzB,kBAAkB,mCAC1B,iBAAiB,KACtB,OAAO;iBAEM,kBACL,4BFVX,UEWW,SFX8B,CAAA,CAAA,KAAA,EEYhC,sBFZgC,CEYT,CFZS,EEYN,CFZM,CAAA,EAAA,GAAA,EEYG,CFZH,CAAA,EEYO,MFZP,CEYc,CFZd,CAAA;;;iBGGzB,sBACR,cAAc,SAAS;;SACW;AHL1C,CAAA;AAAyC,iBGOzB,WHPyB,cGOA,SHPR,cGO+B,EHHhE,CAAA,KAAaC,EGIL,mBHJKA,CGIe,QHJfA,CGIwB,CHJxBA,CAAAA,EGI4B,CHJ5BA,EAAAA,KAAAA,CAAAA,EAAAA,GAAAA,EGKP,GHLOA,CAAAA,EAAAA,SAAAA,GAAAA;;SGM6B,CHL/B;;AADiB,iBGQZ,WHRkB,cGQO,UACjC,cAAc,SAAS,2BACpB;;EFVX,KAAgB,EEWc,CFXd;CAAA;AACM,iBEYN,WFZM,cEYmB,SFXzB,YEW8C,CFXrC,cEWoD,CFXvC,OAAM,EEYpC,mBFZoC,CEYhB,QFZgB,CEYP,CFZO,CAAA,EEYH,CFZG,EAAA,KAAA,CAAA,EAAA,GAAA,EEatC,GFbsC,EAAA,QAAA,EEcjC,CFdiC,CAAA,EAAA;;EAE5C,KAAgB,EEac,CFbd;CAAA;AAAkB,iBEelB,WFfkB,YACH,EEevB,aFfuB,CEeT,QFfS,CEeA,CFfA,CAAA,EAAA,GAAA,EEeS,CFfT,CAAA,CAAA,EAAA,SAAA,GAAA;SAAvB,EAAA,OAAA;SEgBkC,CFfpC,GEewC,CFfxC;;AACmB,iBEgBT,WFhBS,cEgBgB,SFhBG,cEgBoB,aACxD,oBAAoB,SAAS,IAAI,GAAG,SACtC;;EDxBN,KAAgB,ECyB0B,CDzB1B,GCyB8B,CDzB9B;CAAA;AAAkB,iBC2BlB,WD3BkB,cC2BO,CD1BjC,UACL,EC0BK,aD1BL,CC0BmB,QD1BnB,CC0B4B,CD1B5B,CAAA,EAAA,GAAA,EC0BqC,CD1BrC,CAAA,EAAA,QAAA,EC2BQ,CD3BR,CAAA,EAAA;;EAEH,KAAgB,EC0Bc,CD1Bd;EAAA,KAAA,CAAA,EC0ByB,CD1BzB;;AAEL,iBC0BK,WD1BL,cC4BA,SD3BwB,YC4BxB,CD5BF,cC6BI,CD7B+B,UAAI,ECgCxC,mBDhCwC,CCgCpB,QDhCoB,CCgCX,CDhCW,CAAA,ECgCP,CDhCO,ECgCJ,CDhCI,CAAA,EAAA,GAAA,ECiC1C,GDjC0C,EAAA,QAAA,ECkCrC,CDlCqC,CAAA,EAAA;;SCmClB;UAAW;;;;iBC3CzB,kBAAkB,cAAc,QAAQ,KAAK,IAAI;AJJpDD,iBIMG,IJNyB,CAAA,CAAA,YIMP,SJNO,cIMgB,CJN9B,IAI3B,CAAA,KAAaC,EIGL,mBJHKA,CIGe,CJHfA,EIGkB,CJHlBA,EIGqB,CJHrBA,CAAAA,EAAAA,GAAAA,EIIP,GJJOA,CAAAA,EIKV,CJLUA,GIKN,CJLMA;;;KKDD,YAAA;;;;;ALHZ,CAAA;AAAyC,iBKUzB,KAAA,CLVyB,KAAA,EKUZ,aLVY,CAAA,GAAA,CAAA,CAAA,EKUS,YLVT"}
@@ -3,7 +3,7 @@ import { redo, undo } from "atom.io";
3
3
  import * as React$1 from "react";
4
4
  import React from "react";
5
5
  import { jsx } from "react/jsx-runtime";
6
- import { useO as useO$1 } from "atom.io/react";
6
+ import { StoreContext as StoreContext$1, useO as useO$1 } from "atom.io/react";
7
7
 
8
8
  //#region src/react/store-context.tsx
9
9
  const StoreContext = React$1.createContext(IMPLICIT.STORE);
@@ -57,6 +57,8 @@ function useJSON(token, key) {
57
57
  //#endregion
58
58
  //#region src/react/use-loadable.ts
59
59
  function useLoadable(...params) {
60
+ const store = React.useContext(StoreContext$1);
61
+ let value;
60
62
  let state;
61
63
  let fallback;
62
64
  const [token] = params;
@@ -68,7 +70,8 @@ function useLoadable(...params) {
68
70
  case `readonly_pure_selector`:
69
71
  case `writable_held_selector`:
70
72
  case `writable_pure_selector`:
71
- state = useO$1(token);
73
+ value = useO$1(token);
74
+ state = withdraw(store, token);
72
75
  fallback = params[1];
73
76
  break;
74
77
  case `atom_family`:
@@ -78,31 +81,49 @@ function useLoadable(...params) {
78
81
  case `writable_held_selector_family`:
79
82
  case `writable_pure_selector_family`:
80
83
  key = params[1];
81
- state = useO$1(token, key);
84
+ value = useO$1(token, key);
85
+ state = withdraw(store, findInStore(store, token, key));
82
86
  fallback = params[2];
83
87
  }
88
+ const isErr = `catch` in state && state.catch.some((E) => value instanceof E);
84
89
  const wrapperRef = React.useRef({
85
90
  loading: false,
86
91
  value: null
87
92
  });
88
- const lastLoadedRef = React.useRef(fallback ?? (state instanceof Promise ? `LOADING` : state));
93
+ const lastLoadedRef = React.useRef(fallback ?? (value instanceof Promise ? `LOADING` : value));
89
94
  const { current: lastLoaded } = lastLoadedRef;
90
95
  let { current: wrapper } = wrapperRef;
91
- if (state instanceof Promise) {
96
+ const wasErr = `catch` in state && state.catch.some((E) => lastLoaded instanceof E);
97
+ if (value instanceof Promise) {
92
98
  if (lastLoaded === `LOADING`) return `LOADING`;
93
- wrapper = wrapperRef.current = {
99
+ if (wasErr && fallback) wrapper = wrapperRef.current = {
100
+ loading: true,
101
+ value: fallback,
102
+ error: lastLoaded
103
+ };
104
+ else wrapper = wrapperRef.current = {
94
105
  loading: true,
95
106
  value: lastLoaded
96
107
  };
97
108
  } else {
98
- lastLoadedRef.current = state;
99
- if (wrapper.loading === true) wrapper = wrapperRef.current = {
109
+ lastLoadedRef.current = value;
110
+ if (wrapper.loading === true) if (isErr && fallback) wrapper = wrapperRef.current = {
100
111
  loading: false,
101
- value: state
112
+ value: fallback,
113
+ error: value
102
114
  };
103
- else {
115
+ else wrapper = wrapperRef.current = {
116
+ loading: false,
117
+ value
118
+ };
119
+ else if (isErr && fallback) {
120
+ wrapper.loading = false;
121
+ wrapper.value = fallback;
122
+ wrapper.error = value;
123
+ } else {
104
124
  wrapper.loading = false;
105
- wrapper.value = state;
125
+ wrapper.value = value;
126
+ delete wrapper.error;
106
127
  }
107
128
  }
108
129
  return wrapper;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["StoreContext: React.Context<RootStore>","React","StoreProvider: React.FC<{\n\tchildren: React.ReactNode\n\tstore?: RootStore\n}>","token: ReadableToken<any, any, any>","React","setter: React.RefObject<\n\t\t(<New extends T>(next: New | ((old: T) => New)) => void) | null\n\t>","React","React","stateToken: MutableAtomToken<any>","state: unknown","fallback: unknown","key: Canonical","useO","React"],"sources":["../../src/react/store-context.tsx","../../src/react/parse-state-overloads.ts","../../src/react/use-i.ts","../../src/react/use-o.ts","../../src/react/use-json.ts","../../src/react/use-loadable.ts","../../src/react/use-tl.ts"],"sourcesContent":["import type { RootStore } from \"atom.io/internal\"\nimport { IMPLICIT } from \"atom.io/internal\"\nimport * as React from \"react\"\n\nexport const StoreContext: React.Context<RootStore> = React.createContext(\n\tIMPLICIT.STORE,\n)\n\nexport const StoreProvider: React.FC<{\n\tchildren: React.ReactNode\n\tstore?: RootStore\n}> = ({ children, store = IMPLICIT.STORE }) => (\n\t<StoreContext.Provider value={store}>{children}</StoreContext.Provider>\n)\n","import type {\n\tReadableFamilyToken,\n\tReadableToken,\n\tWritableFamilyToken,\n\tWritableToken,\n} from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { findInStore } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\n\nexport function parseStateOverloads<T, K extends Canonical, Key extends K, E>(\n\tstore: Store,\n\t...rest: [WritableFamilyToken<T, K, E>, Key] | [WritableToken<T, any, E>]\n): WritableToken<T, K, E>\n\nexport function parseStateOverloads<T, K extends Canonical, Key extends K, E>(\n\tstore: Store,\n\t...rest: [ReadableFamilyToken<T, K, E>, Key] | [ReadableToken<T, any, E>]\n): ReadableToken<T, K, E>\n\nexport function parseStateOverloads<T, K extends Canonical, Key extends K, E>(\n\tstore: Store,\n\t...rest: [ReadableFamilyToken<T, K, E>, Key] | [ReadableToken<T, any, E>]\n): ReadableToken<T, K, E> {\n\tlet token: ReadableToken<any, any, any>\n\tif (rest.length === 2) {\n\t\tconst family = rest[0]\n\t\tconst key = rest[1]\n\n\t\ttoken = findInStore(store, family, key)\n\t} else {\n\t\ttoken = rest[0]\n\t}\n\treturn token\n}\n","import type { WritableFamilyToken, WritableToken } from \"atom.io\"\nimport { setIntoStore } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport * as React from \"react\"\n\nimport { parseStateOverloads } from \"./parse-state-overloads\"\nimport { StoreContext } from \"./store-context\"\n\nexport function useI<T>(\n\ttoken: WritableToken<T, any, any>,\n): <New extends T>(next: New | ((old: T) => New)) => void\n\nexport function useI<T, K extends Canonical, Key extends K>(\n\ttoken: WritableFamilyToken<T, K, any>,\n\tkey: Key,\n): <New extends T>(next: New | ((old: T) => New)) => void\n\nexport function useI<T, K extends Canonical, Key extends K>(\n\t...params: [WritableFamilyToken<T, K, any>, Key] | [WritableToken<T, any, any>]\n): <New extends T>(next: New | ((old: T) => New)) => void {\n\tconst store = React.useContext(StoreContext)\n\tconst token = parseStateOverloads(store, ...params)\n\tconst setter: React.RefObject<\n\t\t(<New extends T>(next: New | ((old: T) => New)) => void) | null\n\t> = React.useRef(null)\n\tsetter.current ??= (next) => {\n\t\tsetIntoStore(store, token, next)\n\t}\n\treturn setter.current\n}\n","import type { ReadableFamilyToken, ReadableToken } from \"atom.io\"\nimport { getFromStore, subscribeToState } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport * as React from \"react\"\n\nimport { parseStateOverloads } from \"./parse-state-overloads\"\nimport { StoreContext } from \"./store-context\"\n\nexport function useO<T, E>(token: ReadableToken<T, any, E>): E | T\n\nexport function useO<T, K extends Canonical, Key extends K, E>(\n\ttoken: ReadableFamilyToken<T, K, E>,\n\tkey: Key,\n): E | T\n\nexport function useO<T, K extends Canonical, Key extends K, E>(\n\t...params: [ReadableFamilyToken<T, K, E>, Key] | [ReadableToken<T, any, E>]\n): E | T {\n\tconst store = React.useContext(StoreContext)\n\tconst token = parseStateOverloads(store, ...params)\n\tconst id = React.useId()\n\treturn React.useSyncExternalStore<E | T>(\n\t\t(dispatch) => subscribeToState(store, token, `use-o:${id}`, dispatch),\n\t\t() => getFromStore(store, token),\n\t\t() => getFromStore(store, token),\n\t)\n}\n","import type { MutableAtomFamilyToken, MutableAtomToken } from \"atom.io\"\nimport type { AsJSON, Transceiver } from \"atom.io/internal\"\nimport { findInStore, getJsonToken } from \"atom.io/internal\"\nimport type { Canonical, Json } from \"atom.io/json\"\nimport * as React from \"react\"\n\nimport { StoreContext } from \"./store-context\"\nimport { useO } from \"./use-o\"\n\nexport function useJSON<T extends Transceiver<any, any, any>>(\n\ttoken: MutableAtomToken<T>,\n): AsJSON<T>\n\nexport function useJSON<\n\tT extends Transceiver<any, any, any>,\n\tK extends Canonical,\n>(token: MutableAtomFamilyToken<T, K>, key: K): AsJSON<T>\n\nexport function useJSON(\n\ttoken: MutableAtomFamilyToken<any, any> | MutableAtomToken<any>,\n\tkey?: Canonical,\n): Json.Serializable {\n\tconst store = React.useContext(StoreContext)\n\tconst stateToken: MutableAtomToken<any> =\n\t\ttoken.type === `mutable_atom_family` ? findInStore(store, token, key) : token\n\tconst jsonToken = getJsonToken(store, stateToken)\n\treturn useO(jsonToken)\n}\n","/** biome-ignore-all lint/correctness/useHookAtTopLevel: params are used in an invariant way */\nimport type { Loadable, ReadableFamilyToken, ReadableToken } from \"atom.io\"\nimport type { Canonical } from \"atom.io/json\"\nimport { useO } from \"atom.io/react\"\nimport React from \"react\"\n\nexport function useLoadable<T, E>(\n\ttoken: ReadableToken<Loadable<T>, any, E>,\n): `LOADING` | { loading: boolean; value: E | T }\n\nexport function useLoadable<T, K extends Canonical, E>(\n\ttoken: ReadableFamilyToken<Loadable<T>, K, E>,\n\tkey: K,\n): `LOADING` | { loading: boolean; value: E | T }\n\nexport function useLoadable<T, F extends T, E>(\n\ttoken: ReadableToken<Loadable<T>, any, E>,\n\tfallback: F,\n): { loading: boolean; value: T }\n\nexport function useLoadable<T, K extends Canonical, F extends T, E>(\n\ttoken: ReadableFamilyToken<Loadable<T>, K, E>,\n\tkey: K,\n\tfallback: F,\n): { loading: boolean; value: E | T }\n\nexport function useLoadable(\n\t...params:\n\t\t| readonly [ReadableFamilyToken<any, Canonical, any>, Canonical, unknown]\n\t\t| readonly [ReadableFamilyToken<any, Canonical, any>, Canonical]\n\t\t| readonly [ReadableToken<any, any, any>, unknown]\n\t\t| readonly [ReadableToken<any, any, any>]\n): `LOADING` | { loading: boolean; value: unknown } {\n\tlet state: unknown\n\tlet fallback: unknown\n\n\tconst [token] = params\n\tlet key: Canonical\n\tswitch (token.type) {\n\t\tcase `atom`:\n\t\tcase `mutable_atom`:\n\t\tcase `readonly_held_selector`:\n\t\tcase `readonly_pure_selector`:\n\t\tcase `writable_held_selector`:\n\t\tcase `writable_pure_selector`:\n\t\t\tstate = useO(token)\n\t\t\tfallback = params[1]\n\t\t\tbreak\n\t\tcase `atom_family`:\n\t\tcase `mutable_atom_family`:\n\t\tcase `readonly_held_selector_family`:\n\t\tcase `readonly_pure_selector_family`:\n\t\tcase `writable_held_selector_family`:\n\t\tcase `writable_pure_selector_family`:\n\t\t\tkey = params[1] as Canonical\n\t\t\tstate = useO(token, key)\n\t\t\tfallback = params[2]\n\t}\n\n\tconst wrapperRef = React.useRef({ loading: false, value: null as unknown })\n\tconst lastLoadedRef = React.useRef(\n\t\tfallback ?? (state instanceof Promise ? `LOADING` : state),\n\t)\n\n\tconst { current: lastLoaded } = lastLoadedRef\n\tlet { current: wrapper } = wrapperRef\n\n\tif (state instanceof Promise) {\n\t\tif (lastLoaded === `LOADING`) {\n\t\t\treturn `LOADING`\n\t\t}\n\t\twrapper = wrapperRef.current = { loading: true, value: lastLoaded }\n\t} else {\n\t\tlastLoadedRef.current = state\n\t\tif (wrapper.loading === true) {\n\t\t\twrapper = wrapperRef.current = { loading: false, value: state }\n\t\t} else {\n\t\t\twrapper.loading = false\n\t\t\twrapper.value = state\n\t\t}\n\t}\n\n\treturn wrapper\n}\n","import type { TimelineToken } from \"atom.io\"\nimport { redo, undo } from \"atom.io\"\nimport { subscribeToTimeline, withdraw } from \"atom.io/internal\"\nimport * as React from \"react\"\n\nimport { StoreContext } from \"./store-context\"\n\nexport type TimelineMeta = {\n\tat: number\n\tlength: number\n\tundo: () => void\n\tredo: () => void\n}\n\nexport function useTL(token: TimelineToken<any>): TimelineMeta {\n\tconst store = React.useContext(StoreContext)\n\tconst id = React.useId()\n\tconst timeline = withdraw(store, token)\n\tconst tokenRef = React.useRef(token)\n\tconst rebuildMeta = () => {\n\t\treturn {\n\t\t\tat: timeline.at,\n\t\t\tlength: timeline.history.length,\n\t\t\tundo: () => {\n\t\t\t\tundo(token)\n\t\t\t},\n\t\t\tredo: () => {\n\t\t\t\tredo(token)\n\t\t\t},\n\t\t}\n\t}\n\tconst meta = React.useRef<TimelineMeta>(rebuildMeta())\n\tconst retrieve = () => {\n\t\tif (\n\t\t\tmeta.current.at !== timeline?.at ||\n\t\t\tmeta.current.length !== timeline?.history.length ||\n\t\t\ttokenRef.current !== token\n\t\t) {\n\t\t\ttokenRef.current = token\n\t\t\tmeta.current = rebuildMeta()\n\t\t}\n\t\treturn meta.current\n\t}\n\treturn React.useSyncExternalStore<TimelineMeta>(\n\t\t(dispatch) => subscribeToTimeline(store, token, `use-tl:${id}`, dispatch),\n\t\tretrieve,\n\t\tretrieve,\n\t)\n}\n"],"mappings":";;;;;;;;AAIA,MAAaA,eAAyCC,QAAM,cAC3D,SAAS;AAGV,MAAaC,iBAGP,EAAE,UAAU,QAAQ,SAAS,YAClC,oBAAC,aAAa;CAAS,OAAO;CAAQ;;;;;ACQvC,SAAgB,oBACf,OACA,GAAG,MACsB;CACzB,IAAIC;AACJ,KAAI,KAAK,WAAW,GAAG;EACtB,MAAM,SAAS,KAAK;EACpB,MAAM,MAAM,KAAK;AAEjB,UAAQ,YAAY,OAAO,QAAQ;OAEnC,SAAQ,KAAK;AAEd,QAAO;;;;;AChBR,SAAgB,KACf,GAAG,QACsD;CACzD,MAAM,QAAQC,QAAM,WAAW;CAC/B,MAAM,QAAQ,oBAAoB,OAAO,GAAG;CAC5C,MAAMC,SAEFD,QAAM,OAAO;AACjB,QAAO,aAAa,SAAS;AAC5B,eAAa,OAAO,OAAO;;AAE5B,QAAO,OAAO;;;;;ACbf,SAAgB,KACf,GAAG,QACK;CACR,MAAM,QAAQE,QAAM,WAAW;CAC/B,MAAM,QAAQ,oBAAoB,OAAO,GAAG;CAC5C,MAAM,KAAKA,QAAM;AACjB,QAAOA,QAAM,sBACX,aAAa,iBAAiB,OAAO,OAAO,SAAS,MAAM,iBACtD,aAAa,OAAO,cACpB,aAAa,OAAO;;;;;ACN5B,SAAgB,QACf,OACA,KACoB;CACpB,MAAM,QAAQC,QAAM,WAAW;CAC/B,MAAMC,aACL,MAAM,SAAS,wBAAwB,YAAY,OAAO,OAAO,OAAO;CACzE,MAAM,YAAY,aAAa,OAAO;AACtC,QAAO,KAAK;;;;;ACAb,SAAgB,YACf,GAAG,QAKgD;CACnD,IAAIC;CACJ,IAAIC;CAEJ,MAAM,CAAC,SAAS;CAChB,IAAIC;AACJ,SAAQ,MAAM,MAAd;EACC,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;AACJ,WAAQC,OAAK;AACb,cAAW,OAAO;AAClB;EACD,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;AACJ,SAAM,OAAO;AACb,WAAQA,OAAK,OAAO;AACpB,cAAW,OAAO;;CAGpB,MAAM,aAAa,MAAM,OAAO;EAAE,SAAS;EAAO,OAAO;;CACzD,MAAM,gBAAgB,MAAM,OAC3B,aAAa,iBAAiB,UAAU,YAAY;CAGrD,MAAM,EAAE,SAAS,eAAe;CAChC,IAAI,EAAE,SAAS,YAAY;AAE3B,KAAI,iBAAiB,SAAS;AAC7B,MAAI,eAAe,UAClB,QAAO;AAER,YAAU,WAAW,UAAU;GAAE,SAAS;GAAM,OAAO;;QACjD;AACN,gBAAc,UAAU;AACxB,MAAI,QAAQ,YAAY,KACvB,WAAU,WAAW,UAAU;GAAE,SAAS;GAAO,OAAO;;OAClD;AACN,WAAQ,UAAU;AAClB,WAAQ,QAAQ;;;AAIlB,QAAO;;;;;ACpER,SAAgB,MAAM,OAAyC;CAC9D,MAAM,QAAQC,QAAM,WAAW;CAC/B,MAAM,KAAKA,QAAM;CACjB,MAAM,WAAW,SAAS,OAAO;CACjC,MAAM,WAAWA,QAAM,OAAO;CAC9B,MAAM,oBAAoB;AACzB,SAAO;GACN,IAAI,SAAS;GACb,QAAQ,SAAS,QAAQ;GACzB,YAAY;AACX,SAAK;;GAEN,YAAY;AACX,SAAK;;;;CAIR,MAAM,OAAOA,QAAM,OAAqB;CACxC,MAAM,iBAAiB;AACtB,MACC,KAAK,QAAQ,OAAO,UAAU,MAC9B,KAAK,QAAQ,WAAW,UAAU,QAAQ,UAC1C,SAAS,YAAY,OACpB;AACD,YAAS,UAAU;AACnB,QAAK,UAAU;;AAEhB,SAAO,KAAK;;AAEb,QAAOA,QAAM,sBACX,aAAa,oBAAoB,OAAO,OAAO,UAAU,MAAM,WAChE,UACA"}
1
+ {"version":3,"file":"index.js","names":["StoreContext: React.Context<RootStore>","React","StoreProvider: React.FC<{\n\tchildren: React.ReactNode\n\tstore?: RootStore\n}>","token: ReadableToken<any, any, any>","React","setter: React.RefObject<\n\t\t(<New extends T>(next: New | ((old: T) => New)) => void) | null\n\t>","React","React","stateToken: MutableAtomToken<any>","StoreContext","value: unknown","state: ReadableState<any, any>","fallback: unknown","key: Canonical","useO","React"],"sources":["../../src/react/store-context.tsx","../../src/react/parse-state-overloads.ts","../../src/react/use-i.ts","../../src/react/use-o.ts","../../src/react/use-json.ts","../../src/react/use-loadable.ts","../../src/react/use-tl.ts"],"sourcesContent":["import type { RootStore } from \"atom.io/internal\"\nimport { IMPLICIT } from \"atom.io/internal\"\nimport * as React from \"react\"\n\nexport const StoreContext: React.Context<RootStore> = React.createContext(\n\tIMPLICIT.STORE,\n)\n\nexport const StoreProvider: React.FC<{\n\tchildren: React.ReactNode\n\tstore?: RootStore\n}> = ({ children, store = IMPLICIT.STORE }) => (\n\t<StoreContext.Provider value={store}>{children}</StoreContext.Provider>\n)\n","import type {\n\tReadableFamilyToken,\n\tReadableToken,\n\tWritableFamilyToken,\n\tWritableToken,\n} from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { findInStore } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\n\nexport function parseStateOverloads<T, K extends Canonical, Key extends K, E>(\n\tstore: Store,\n\t...rest: [WritableFamilyToken<T, K, E>, Key] | [WritableToken<T, any, E>]\n): WritableToken<T, K, E>\n\nexport function parseStateOverloads<T, K extends Canonical, Key extends K, E>(\n\tstore: Store,\n\t...rest: [ReadableFamilyToken<T, K, E>, Key] | [ReadableToken<T, any, E>]\n): ReadableToken<T, K, E>\n\nexport function parseStateOverloads<T, K extends Canonical, Key extends K, E>(\n\tstore: Store,\n\t...rest: [ReadableFamilyToken<T, K, E>, Key] | [ReadableToken<T, any, E>]\n): ReadableToken<T, K, E> {\n\tlet token: ReadableToken<any, any, any>\n\tif (rest.length === 2) {\n\t\tconst family = rest[0]\n\t\tconst key = rest[1]\n\n\t\ttoken = findInStore(store, family, key)\n\t} else {\n\t\ttoken = rest[0]\n\t}\n\treturn token\n}\n","import type { WritableFamilyToken, WritableToken } from \"atom.io\"\nimport { setIntoStore } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport * as React from \"react\"\n\nimport { parseStateOverloads } from \"./parse-state-overloads\"\nimport { StoreContext } from \"./store-context\"\n\nexport function useI<T>(\n\ttoken: WritableToken<T, any, any>,\n): <New extends T>(next: New | ((old: T) => New)) => void\n\nexport function useI<T, K extends Canonical, Key extends K>(\n\ttoken: WritableFamilyToken<T, K, any>,\n\tkey: Key,\n): <New extends T>(next: New | ((old: T) => New)) => void\n\nexport function useI<T, K extends Canonical, Key extends K>(\n\t...params: [WritableFamilyToken<T, K, any>, Key] | [WritableToken<T, any, any>]\n): <New extends T>(next: New | ((old: T) => New)) => void {\n\tconst store = React.useContext(StoreContext)\n\tconst token = parseStateOverloads(store, ...params)\n\tconst setter: React.RefObject<\n\t\t(<New extends T>(next: New | ((old: T) => New)) => void) | null\n\t> = React.useRef(null)\n\tsetter.current ??= (next) => {\n\t\tsetIntoStore(store, token, next)\n\t}\n\treturn setter.current\n}\n","import type { ReadableFamilyToken, ReadableToken } from \"atom.io\"\nimport { getFromStore, subscribeToState } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport * as React from \"react\"\n\nimport { parseStateOverloads } from \"./parse-state-overloads\"\nimport { StoreContext } from \"./store-context\"\n\nexport function useO<T, E>(token: ReadableToken<T, any, E>): E | T\n\nexport function useO<T, K extends Canonical, Key extends K, E>(\n\ttoken: ReadableFamilyToken<T, K, E>,\n\tkey: Key,\n): E | T\n\nexport function useO<T, K extends Canonical, Key extends K, E>(\n\t...params: [ReadableFamilyToken<T, K, E>, Key] | [ReadableToken<T, any, E>]\n): E | T {\n\tconst store = React.useContext(StoreContext)\n\tconst token = parseStateOverloads(store, ...params)\n\tconst id = React.useId()\n\treturn React.useSyncExternalStore<E | T>(\n\t\t(dispatch) => subscribeToState(store, token, `use-o:${id}`, dispatch),\n\t\t() => getFromStore(store, token),\n\t\t() => getFromStore(store, token),\n\t)\n}\n","import type { MutableAtomFamilyToken, MutableAtomToken } from \"atom.io\"\nimport type { AsJSON, Transceiver } from \"atom.io/internal\"\nimport { findInStore, getJsonToken } from \"atom.io/internal\"\nimport type { Canonical, Json } from \"atom.io/json\"\nimport * as React from \"react\"\n\nimport { StoreContext } from \"./store-context\"\nimport { useO } from \"./use-o\"\n\nexport function useJSON<T extends Transceiver<any, any, any>>(\n\ttoken: MutableAtomToken<T>,\n): AsJSON<T>\n\nexport function useJSON<\n\tT extends Transceiver<any, any, any>,\n\tK extends Canonical,\n>(token: MutableAtomFamilyToken<T, K>, key: K): AsJSON<T>\n\nexport function useJSON(\n\ttoken: MutableAtomFamilyToken<any, any> | MutableAtomToken<any>,\n\tkey?: Canonical,\n): Json.Serializable {\n\tconst store = React.useContext(StoreContext)\n\tconst stateToken: MutableAtomToken<any> =\n\t\ttoken.type === `mutable_atom_family` ? findInStore(store, token, key) : token\n\tconst jsonToken = getJsonToken(store, stateToken)\n\treturn useO(jsonToken)\n}\n","/** biome-ignore-all lint/correctness/useHookAtTopLevel: params are used in an invariant way */\nimport type { Loadable, ReadableFamilyToken, ReadableToken } from \"atom.io\"\nimport { findInStore, type ReadableState, withdraw } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport React from \"react\"\n\nexport function useLoadable<T>(\n\ttoken: ReadableToken<Loadable<T>, any, never>,\n): `LOADING` | { loading: boolean; value: T }\n\nexport function useLoadable<T, K extends Canonical, Key extends K>(\n\ttoken: ReadableFamilyToken<Loadable<T>, K, never>,\n\tkey: Key,\n): `LOADING` | { loading: boolean; value: T }\n\nexport function useLoadable<T, F extends T>(\n\ttoken: ReadableToken<Loadable<T>, any, never>,\n\tfallback: F,\n): { loading: boolean; value: T }\n\nexport function useLoadable<T, K extends Canonical, F extends T, Key extends K>(\n\ttoken: ReadableFamilyToken<Loadable<T>, K, never>,\n\tkey: Key,\n\tfallback: F,\n): { loading: boolean; value: T }\n\nexport function useLoadable<T, E>(\n\ttoken: ReadableToken<Loadable<T>, any, E>,\n): `LOADING` | { loading: boolean; value: E | T }\n\nexport function useLoadable<T, K extends Canonical, Key extends K, E>(\n\ttoken: ReadableFamilyToken<Loadable<T>, K, E>,\n\tkey: Key,\n): `LOADING` | { loading: boolean; value: E | T }\n\nexport function useLoadable<T, F extends T, E>(\n\ttoken: ReadableToken<Loadable<T>, any, E>,\n\tfallback: F,\n): { loading: boolean; value: T; error?: E }\n\nexport function useLoadable<\n\tT,\n\tK extends Canonical,\n\tF extends T,\n\tKey extends K,\n\tE,\n>(\n\ttoken: ReadableFamilyToken<Loadable<T>, K, E>,\n\tkey: Key,\n\tfallback: F,\n): { loading: boolean; value: T; error?: E }\n\nexport function useLoadable(\n\t...params:\n\t\t| readonly [ReadableFamilyToken<any, Canonical, any>, Canonical, unknown]\n\t\t| readonly [ReadableFamilyToken<any, Canonical, any>, Canonical]\n\t\t| readonly [ReadableToken<any, any, any>, unknown]\n\t\t| readonly [ReadableToken<any, any, any>]\n): `LOADING` | { loading: boolean; value: unknown; error?: unknown } {\n\tconst store = React.useContext(StoreContext)\n\n\tlet value: unknown\n\tlet state: ReadableState<any, any>\n\tlet fallback: unknown\n\n\tconst [token] = params\n\tlet key: Canonical\n\tswitch (token.type) {\n\t\tcase `atom`:\n\t\tcase `mutable_atom`:\n\t\tcase `readonly_held_selector`:\n\t\tcase `readonly_pure_selector`:\n\t\tcase `writable_held_selector`:\n\t\tcase `writable_pure_selector`:\n\t\t\tvalue = useO(token)\n\t\t\tstate = withdraw(store, token)\n\t\t\tfallback = params[1]\n\t\t\tbreak\n\t\tcase `atom_family`:\n\t\tcase `mutable_atom_family`:\n\t\tcase `readonly_held_selector_family`:\n\t\tcase `readonly_pure_selector_family`:\n\t\tcase `writable_held_selector_family`:\n\t\tcase `writable_pure_selector_family`:\n\t\t\tkey = params[1] as Canonical\n\t\t\tvalue = useO(token, key)\n\t\t\tstate = withdraw(store, findInStore(store, token, key))\n\t\t\tfallback = params[2]\n\t}\n\n\tconst isErr = `catch` in state && state.catch.some((E) => value instanceof E)\n\n\tconst wrapperRef = React.useRef<{\n\t\tloading: boolean\n\t\tvalue: unknown\n\t\terror?: unknown\n\t}>({ loading: false, value: null as unknown })\n\tconst lastLoadedRef = React.useRef(\n\t\tfallback ?? (value instanceof Promise ? `LOADING` : value),\n\t)\n\n\tconst { current: lastLoaded } = lastLoadedRef\n\tlet { current: wrapper } = wrapperRef\n\n\tconst wasErr =\n\t\t`catch` in state && state.catch.some((E) => lastLoaded instanceof E)\n\n\tif (value instanceof Promise) {\n\t\tif (lastLoaded === `LOADING`) {\n\t\t\treturn `LOADING`\n\t\t}\n\t\tif (wasErr && fallback) {\n\t\t\twrapper = wrapperRef.current = {\n\t\t\t\tloading: true,\n\t\t\t\tvalue: fallback,\n\t\t\t\terror: lastLoaded,\n\t\t\t}\n\t\t} else {\n\t\t\twrapper = wrapperRef.current = { loading: true, value: lastLoaded }\n\t\t}\n\t} else {\n\t\tlastLoadedRef.current = value\n\t\tif (wrapper.loading === true) {\n\t\t\tif (isErr && fallback) {\n\t\t\t\twrapper = wrapperRef.current = {\n\t\t\t\t\tloading: false,\n\t\t\t\t\tvalue: fallback,\n\t\t\t\t\terror: value,\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twrapper = wrapperRef.current = { loading: false, value: value }\n\t\t\t}\n\t\t} else {\n\t\t\tif (isErr && fallback) {\n\t\t\t\twrapper.loading = false\n\t\t\t\twrapper.value = fallback\n\t\t\t\twrapper.error = value\n\t\t\t} else {\n\t\t\t\twrapper.loading = false\n\t\t\t\twrapper.value = value\n\t\t\t\tdelete wrapper.error\n\t\t\t}\n\t\t}\n\t}\n\n\treturn wrapper\n}\n","import type { TimelineToken } from \"atom.io\"\nimport { redo, undo } from \"atom.io\"\nimport { subscribeToTimeline, withdraw } from \"atom.io/internal\"\nimport * as React from \"react\"\n\nimport { StoreContext } from \"./store-context\"\n\nexport type TimelineMeta = {\n\tat: number\n\tlength: number\n\tundo: () => void\n\tredo: () => void\n}\n\nexport function useTL(token: TimelineToken<any>): TimelineMeta {\n\tconst store = React.useContext(StoreContext)\n\tconst id = React.useId()\n\tconst timeline = withdraw(store, token)\n\tconst tokenRef = React.useRef(token)\n\tconst rebuildMeta = () => {\n\t\treturn {\n\t\t\tat: timeline.at,\n\t\t\tlength: timeline.history.length,\n\t\t\tundo: () => {\n\t\t\t\tundo(token)\n\t\t\t},\n\t\t\tredo: () => {\n\t\t\t\tredo(token)\n\t\t\t},\n\t\t}\n\t}\n\tconst meta = React.useRef<TimelineMeta>(rebuildMeta())\n\tconst retrieve = () => {\n\t\tif (\n\t\t\tmeta.current.at !== timeline?.at ||\n\t\t\tmeta.current.length !== timeline?.history.length ||\n\t\t\ttokenRef.current !== token\n\t\t) {\n\t\t\ttokenRef.current = token\n\t\t\tmeta.current = rebuildMeta()\n\t\t}\n\t\treturn meta.current\n\t}\n\treturn React.useSyncExternalStore<TimelineMeta>(\n\t\t(dispatch) => subscribeToTimeline(store, token, `use-tl:${id}`, dispatch),\n\t\tretrieve,\n\t\tretrieve,\n\t)\n}\n"],"mappings":";;;;;;;;AAIA,MAAaA,eAAyCC,QAAM,cAC3D,SAAS;AAGV,MAAaC,iBAGP,EAAE,UAAU,QAAQ,SAAS,YAClC,oBAAC,aAAa;CAAS,OAAO;CAAQ;;;;;ACQvC,SAAgB,oBACf,OACA,GAAG,MACsB;CACzB,IAAIC;AACJ,KAAI,KAAK,WAAW,GAAG;EACtB,MAAM,SAAS,KAAK;EACpB,MAAM,MAAM,KAAK;AAEjB,UAAQ,YAAY,OAAO,QAAQ;OAEnC,SAAQ,KAAK;AAEd,QAAO;;;;;AChBR,SAAgB,KACf,GAAG,QACsD;CACzD,MAAM,QAAQC,QAAM,WAAW;CAC/B,MAAM,QAAQ,oBAAoB,OAAO,GAAG;CAC5C,MAAMC,SAEFD,QAAM,OAAO;AACjB,QAAO,aAAa,SAAS;AAC5B,eAAa,OAAO,OAAO;;AAE5B,QAAO,OAAO;;;;;ACbf,SAAgB,KACf,GAAG,QACK;CACR,MAAM,QAAQE,QAAM,WAAW;CAC/B,MAAM,QAAQ,oBAAoB,OAAO,GAAG;CAC5C,MAAM,KAAKA,QAAM;AACjB,QAAOA,QAAM,sBACX,aAAa,iBAAiB,OAAO,OAAO,SAAS,MAAM,iBACtD,aAAa,OAAO,cACpB,aAAa,OAAO;;;;;ACN5B,SAAgB,QACf,OACA,KACoB;CACpB,MAAM,QAAQC,QAAM,WAAW;CAC/B,MAAMC,aACL,MAAM,SAAS,wBAAwB,YAAY,OAAO,OAAO,OAAO;CACzE,MAAM,YAAY,aAAa,OAAO;AACtC,QAAO,KAAK;;;;;AC2Bb,SAAgB,YACf,GAAG,QAKiE;CACpE,MAAM,QAAQ,MAAM,WAAWC;CAE/B,IAAIC;CACJ,IAAIC;CACJ,IAAIC;CAEJ,MAAM,CAAC,SAAS;CAChB,IAAIC;AACJ,SAAQ,MAAM,MAAd;EACC,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;AACJ,WAAQC,OAAK;AACb,WAAQ,SAAS,OAAO;AACxB,cAAW,OAAO;AAClB;EACD,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;AACJ,SAAM,OAAO;AACb,WAAQA,OAAK,OAAO;AACpB,WAAQ,SAAS,OAAO,YAAY,OAAO,OAAO;AAClD,cAAW,OAAO;;CAGpB,MAAM,QAAQ,WAAW,SAAS,MAAM,MAAM,MAAM,MAAM,iBAAiB;CAE3E,MAAM,aAAa,MAAM,OAItB;EAAE,SAAS;EAAO,OAAO;;CAC5B,MAAM,gBAAgB,MAAM,OAC3B,aAAa,iBAAiB,UAAU,YAAY;CAGrD,MAAM,EAAE,SAAS,eAAe;CAChC,IAAI,EAAE,SAAS,YAAY;CAE3B,MAAM,SACL,WAAW,SAAS,MAAM,MAAM,MAAM,MAAM,sBAAsB;AAEnE,KAAI,iBAAiB,SAAS;AAC7B,MAAI,eAAe,UAClB,QAAO;AAER,MAAI,UAAU,SACb,WAAU,WAAW,UAAU;GAC9B,SAAS;GACT,OAAO;GACP,OAAO;;MAGR,WAAU,WAAW,UAAU;GAAE,SAAS;GAAM,OAAO;;QAElD;AACN,gBAAc,UAAU;AACxB,MAAI,QAAQ,YAAY,KACvB,KAAI,SAAS,SACZ,WAAU,WAAW,UAAU;GAC9B,SAAS;GACT,OAAO;GACP,OAAO;;MAGR,WAAU,WAAW,UAAU;GAAE,SAAS;GAAc;;WAGrD,SAAS,UAAU;AACtB,WAAQ,UAAU;AAClB,WAAQ,QAAQ;AAChB,WAAQ,QAAQ;SACV;AACN,WAAQ,UAAU;AAClB,WAAQ,QAAQ;AAChB,UAAO,QAAQ;;;AAKlB,QAAO;;;;;ACpIR,SAAgB,MAAM,OAAyC;CAC9D,MAAM,QAAQC,QAAM,WAAW;CAC/B,MAAM,KAAKA,QAAM;CACjB,MAAM,WAAW,SAAS,OAAO;CACjC,MAAM,WAAWA,QAAM,OAAO;CAC9B,MAAM,oBAAoB;AACzB,SAAO;GACN,IAAI,SAAS;GACb,QAAQ,SAAS,QAAQ;GACzB,YAAY;AACX,SAAK;;GAEN,YAAY;AACX,SAAK;;;;CAIR,MAAM,OAAOA,QAAM,OAAqB;CACxC,MAAM,iBAAiB;AACtB,MACC,KAAK,QAAQ,OAAO,UAAU,MAC9B,KAAK,QAAQ,WAAW,UAAU,QAAQ,UAC1C,SAAS,YAAY,OACpB;AACD,YAAS,UAAU;AACnB,QAAK,UAAU;;AAEhB,SAAO,KAAK;;AAEb,QAAOA,QAAM,sBACX,aAAa,oBAAoB,OAAO,OAAO,UAAU,MAAM,WAChE,UACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atom.io",
3
- "version": "0.40.4",
3
+ "version": "0.40.5",
4
4
  "description": "Composable and testable reactive data library.",
5
5
  "homepage": "https://atom.io.fyi",
6
6
  "sideEffects": false,
@@ -2,7 +2,7 @@ import type { ViewOf } from "atom.io"
2
2
 
3
3
  import type { ReadableState } from ".."
4
4
  import { readFromCache, writeToCache } from "../caching"
5
- import { isFn } from "../is-fn"
5
+ import { safeCompute } from "../safe-compute"
6
6
  import type { Store } from "../store"
7
7
 
8
8
  export function readOrComputeValue<T, E>(
@@ -30,83 +30,10 @@ export function readOrComputeValue<T, E>(
30
30
  case `writable_held_selector`:
31
31
  target.logger.info(`🧮`, state.type, key, `computing value`)
32
32
  return state.getFrom(target)
33
+ case `writable_pure_selector`:
33
34
  case `readonly_pure_selector`:
34
- case `writable_pure_selector`: {
35
- let val: E | T
36
- target.logger.info(`🧮`, state.type, key, `computing value`)
37
- try {
38
- val = state.getFrom(target)
39
- if (val instanceof Promise) {
40
- return (val as Promise<E & T>).catch((thrown) => {
41
- target.logger.error(`💥`, state.type, key, `rejected:`, thrown)
42
- if (state.catch) {
43
- for (const Class of state.catch) {
44
- if (thrown instanceof Class) {
45
- return thrown
46
- }
47
- }
48
- }
49
- throw thrown
50
- }) as E | T
51
- }
52
- } catch (e) {
53
- target.logger.error(`💥`, state.type, key, `rejected:`, e)
54
- if (state.catch) {
55
- for (const Class of state.catch) {
56
- if (e instanceof Class) {
57
- return writeToCache(target, state, e)
58
- }
59
- }
60
- }
61
- throw e
62
- }
63
- const cachedValue = writeToCache(target, state, val)
64
- return cachedValue
65
- }
66
- case `atom`: {
67
- let def: E | T
68
- if (isFn(state.default)) {
69
- try {
70
- def = state.default()
71
- if (def instanceof Promise) {
72
- def = (def as Promise<T> & T).catch<E | T>((thrown) => {
73
- target.logger.error(`💥`, state.type, key, `rejected:`, thrown)
74
- if (state.catch) {
75
- for (const Class of state.catch) {
76
- if (thrown instanceof Class) {
77
- return thrown
78
- }
79
- }
80
- }
81
- throw thrown
82
- }) as E | T
83
- }
84
- } catch (e) {
85
- target.logger.error(`💥`, state.type, key, `rejected:`, e)
86
- if (state.catch) {
87
- for (const Class of state.catch) {
88
- if (e instanceof Class) {
89
- def = writeToCache(target, state, e)
90
- target.logger.info(
91
- `✨`,
92
- state.type,
93
- key,
94
- `computed default`,
95
- def,
96
- )
97
- return def
98
- }
99
- }
100
- }
101
- throw e
102
- }
103
- } else {
104
- def = state.default
105
- target.logger.info(`✨`, state.type, key, `using static default`, def)
106
- }
107
- const cachedValue = writeToCache(target, state, def)
108
- return cachedValue
109
- }
35
+ case `atom`:
36
+ return safeCompute(target, state)
110
37
  case `mutable_atom`: {
111
38
  const instance = new state.class()
112
39
  target.logger.info(`✨`, state.type, key, `created new instance`, instance)
@@ -0,0 +1,90 @@
1
+ import type { PureSelector, RegularAtom } from "."
2
+ import { writeToCache } from "./caching"
3
+ import { isFn } from "./is-fn"
4
+ import type { Store } from "./store"
5
+
6
+ export function safeCompute<T, E>(
7
+ target: Store,
8
+ state: PureSelector<T, E> | RegularAtom<T, E>,
9
+ ): E | T {
10
+ const { type, key, catch: canCatch } = state
11
+ switch (type) {
12
+ case `readonly_pure_selector`:
13
+ case `writable_pure_selector`: {
14
+ let val: E | T
15
+ target.logger.info(`🧮`, type, key, `computing value`)
16
+ try {
17
+ val = state.getFrom(target)
18
+ if (val instanceof Promise) {
19
+ return (val as Promise<E & T>).catch((thrown) => {
20
+ target.logger.error(`💥`, type, key, `rejected:`, thrown)
21
+ if (canCatch) {
22
+ for (const Class of canCatch) {
23
+ if (thrown instanceof Class) {
24
+ return thrown
25
+ }
26
+ }
27
+ }
28
+ throw thrown
29
+ }) as E | T
30
+ }
31
+ } catch (e) {
32
+ target.logger.error(`💥`, type, key, `rejected:`, e)
33
+ if (canCatch) {
34
+ for (const Class of canCatch) {
35
+ if (e instanceof Class) {
36
+ return writeToCache(target, state, e)
37
+ }
38
+ }
39
+ }
40
+ throw e
41
+ }
42
+ const cachedValue = writeToCache(target, state, val)
43
+ return cachedValue
44
+ }
45
+ case `atom`: {
46
+ let def: E | T
47
+ if (isFn(state.default)) {
48
+ try {
49
+ def = state.default()
50
+ if (def instanceof Promise) {
51
+ def = (def as Promise<T> & T).catch<E | T>((thrown) => {
52
+ target.logger.error(`💥`, type, key, `rejected:`, thrown)
53
+ if (canCatch) {
54
+ for (const Class of canCatch) {
55
+ if (thrown instanceof Class) {
56
+ return thrown
57
+ }
58
+ }
59
+ }
60
+ throw thrown
61
+ }) as E | T
62
+ }
63
+ } catch (e) {
64
+ target.logger.error(`💥`, type, key, `rejected:`, e)
65
+ if (canCatch) {
66
+ for (const Class of canCatch) {
67
+ if (e instanceof Class) {
68
+ def = writeToCache(target, state, e)
69
+ target.logger.info(
70
+ `✨`,
71
+ state.type,
72
+ key,
73
+ `computed default`,
74
+ def,
75
+ )
76
+ return def
77
+ }
78
+ }
79
+ }
80
+ throw e
81
+ }
82
+ } else {
83
+ def = state.default
84
+ target.logger.info(`✨`, state.type, key, `using static default`, def)
85
+ }
86
+ const cachedValue = writeToCache(target, state, def)
87
+ return cachedValue
88
+ }
89
+ }
90
+ }
@@ -1,6 +1,7 @@
1
1
  import type { Atom, OpenOperation, Store, WritableState } from ".."
2
2
  import { traceRootSelectorAtoms } from ".."
3
3
  import { isFn } from "../is-fn"
4
+ import { safeCompute } from "../safe-compute"
4
5
  import { dispatchOrDeferStateUpdate } from "./dispatch-state-update"
5
6
  import type { ProtoUpdate } from "./operate-on-store"
6
7
  import { setAtom } from "./set-atom"
@@ -13,8 +14,9 @@ function resetAtom<T, E>(
13
14
  case `mutable_atom`:
14
15
  return setAtom(target, atom, new atom.class())
15
16
  case `atom`: {
16
- let def = atom.default
17
- if (isFn(def)) def = def()
17
+ let def: E | T
18
+ if (isFn(atom.default)) def = safeCompute(target, atom)
19
+ else def = atom.default
18
20
  return setAtom(target, atom, def)
19
21
  }
20
22
  }
@@ -30,16 +32,26 @@ export function resetAtomOrSelector<T, E>(
30
32
  case `mutable_atom`:
31
33
  protoUpdate = resetAtom(target, state)
32
34
  break
33
- case `writable_pure_selector`:
34
35
  case `writable_held_selector`:
35
36
  {
36
- const oldValue = state.getFrom(target)
37
37
  const atoms = traceRootSelectorAtoms(target, state.key)
38
38
  for (const atom of atoms.values()) {
39
39
  const rootProtoUpdate = resetAtom(target, atom)
40
40
  dispatchOrDeferStateUpdate(target, state, rootProtoUpdate, false)
41
41
  }
42
- const newValue = state.getFrom(target)
42
+ const value = state.getFrom(target)
43
+ protoUpdate = { oldValue: value, newValue: value }
44
+ }
45
+ break
46
+ case `writable_pure_selector`:
47
+ {
48
+ const oldValue = safeCompute(target, state)
49
+ const atoms = traceRootSelectorAtoms(target, state.key)
50
+ for (const atom of atoms.values()) {
51
+ const rootProtoUpdate = resetAtom(target, atom)
52
+ dispatchOrDeferStateUpdate(target, state, rootProtoUpdate, false)
53
+ }
54
+ const newValue = safeCompute(target, state)
43
55
  protoUpdate = { oldValue, newValue }
44
56
  }
45
57
  break
@@ -1,28 +1,55 @@
1
1
  /** biome-ignore-all lint/correctness/useHookAtTopLevel: params are used in an invariant way */
2
2
  import type { Loadable, ReadableFamilyToken, ReadableToken } from "atom.io"
3
+ import { findInStore, type ReadableState, withdraw } from "atom.io/internal"
3
4
  import type { Canonical } from "atom.io/json"
4
- import { useO } from "atom.io/react"
5
+ import { StoreContext, useO } from "atom.io/react"
5
6
  import React from "react"
6
7
 
8
+ export function useLoadable<T>(
9
+ token: ReadableToken<Loadable<T>, any, never>,
10
+ ): `LOADING` | { loading: boolean; value: T }
11
+
12
+ export function useLoadable<T, K extends Canonical, Key extends K>(
13
+ token: ReadableFamilyToken<Loadable<T>, K, never>,
14
+ key: Key,
15
+ ): `LOADING` | { loading: boolean; value: T }
16
+
17
+ export function useLoadable<T, F extends T>(
18
+ token: ReadableToken<Loadable<T>, any, never>,
19
+ fallback: F,
20
+ ): { loading: boolean; value: T }
21
+
22
+ export function useLoadable<T, K extends Canonical, F extends T, Key extends K>(
23
+ token: ReadableFamilyToken<Loadable<T>, K, never>,
24
+ key: Key,
25
+ fallback: F,
26
+ ): { loading: boolean; value: T }
27
+
7
28
  export function useLoadable<T, E>(
8
29
  token: ReadableToken<Loadable<T>, any, E>,
9
30
  ): `LOADING` | { loading: boolean; value: E | T }
10
31
 
11
- export function useLoadable<T, K extends Canonical, E>(
32
+ export function useLoadable<T, K extends Canonical, Key extends K, E>(
12
33
  token: ReadableFamilyToken<Loadable<T>, K, E>,
13
- key: K,
34
+ key: Key,
14
35
  ): `LOADING` | { loading: boolean; value: E | T }
15
36
 
16
37
  export function useLoadable<T, F extends T, E>(
17
38
  token: ReadableToken<Loadable<T>, any, E>,
18
39
  fallback: F,
19
- ): { loading: boolean; value: T }
40
+ ): { loading: boolean; value: T; error?: E }
20
41
 
21
- export function useLoadable<T, K extends Canonical, F extends T, E>(
42
+ export function useLoadable<
43
+ T,
44
+ K extends Canonical,
45
+ F extends T,
46
+ Key extends K,
47
+ E,
48
+ >(
22
49
  token: ReadableFamilyToken<Loadable<T>, K, E>,
23
- key: K,
50
+ key: Key,
24
51
  fallback: F,
25
- ): { loading: boolean; value: E | T }
52
+ ): { loading: boolean; value: T; error?: E }
26
53
 
27
54
  export function useLoadable(
28
55
  ...params:
@@ -30,8 +57,11 @@ export function useLoadable(
30
57
  | readonly [ReadableFamilyToken<any, Canonical, any>, Canonical]
31
58
  | readonly [ReadableToken<any, any, any>, unknown]
32
59
  | readonly [ReadableToken<any, any, any>]
33
- ): `LOADING` | { loading: boolean; value: unknown } {
34
- let state: unknown
60
+ ): `LOADING` | { loading: boolean; value: unknown; error?: unknown } {
61
+ const store = React.useContext(StoreContext)
62
+
63
+ let value: unknown
64
+ let state: ReadableState<any, any>
35
65
  let fallback: unknown
36
66
 
37
67
  const [token] = params
@@ -43,7 +73,8 @@ export function useLoadable(
43
73
  case `readonly_pure_selector`:
44
74
  case `writable_held_selector`:
45
75
  case `writable_pure_selector`:
46
- state = useO(token)
76
+ value = useO(token)
77
+ state = withdraw(store, token)
47
78
  fallback = params[1]
48
79
  break
49
80
  case `atom_family`:
@@ -53,30 +84,63 @@ export function useLoadable(
53
84
  case `writable_held_selector_family`:
54
85
  case `writable_pure_selector_family`:
55
86
  key = params[1] as Canonical
56
- state = useO(token, key)
87
+ value = useO(token, key)
88
+ state = withdraw(store, findInStore(store, token, key))
57
89
  fallback = params[2]
58
90
  }
59
91
 
60
- const wrapperRef = React.useRef({ loading: false, value: null as unknown })
92
+ const isErr = `catch` in state && state.catch.some((E) => value instanceof E)
93
+
94
+ const wrapperRef = React.useRef<{
95
+ loading: boolean
96
+ value: unknown
97
+ error?: unknown
98
+ }>({ loading: false, value: null as unknown })
61
99
  const lastLoadedRef = React.useRef(
62
- fallback ?? (state instanceof Promise ? `LOADING` : state),
100
+ fallback ?? (value instanceof Promise ? `LOADING` : value),
63
101
  )
64
102
 
65
103
  const { current: lastLoaded } = lastLoadedRef
66
104
  let { current: wrapper } = wrapperRef
67
105
 
68
- if (state instanceof Promise) {
106
+ const wasErr =
107
+ `catch` in state && state.catch.some((E) => lastLoaded instanceof E)
108
+
109
+ if (value instanceof Promise) {
69
110
  if (lastLoaded === `LOADING`) {
70
111
  return `LOADING`
71
112
  }
72
- wrapper = wrapperRef.current = { loading: true, value: lastLoaded }
113
+ if (wasErr && fallback) {
114
+ wrapper = wrapperRef.current = {
115
+ loading: true,
116
+ value: fallback,
117
+ error: lastLoaded,
118
+ }
119
+ } else {
120
+ wrapper = wrapperRef.current = { loading: true, value: lastLoaded }
121
+ }
73
122
  } else {
74
- lastLoadedRef.current = state
123
+ lastLoadedRef.current = value
75
124
  if (wrapper.loading === true) {
76
- wrapper = wrapperRef.current = { loading: false, value: state }
125
+ if (isErr && fallback) {
126
+ wrapper = wrapperRef.current = {
127
+ loading: false,
128
+ value: fallback,
129
+ error: value,
130
+ }
131
+ } else {
132
+ wrapper = wrapperRef.current = { loading: false, value: value }
133
+ }
77
134
  } else {
78
- wrapper.loading = false
79
- wrapper.value = state
135
+ if (isErr && fallback) {
136
+ wrapper.loading = false
137
+ wrapper.value = fallback
138
+ wrapper.error = value
139
+ } else {
140
+ wrapper.loading = false
141
+ wrapper.value = value
142
+ delete wrapper.error
143
+ }
80
144
  }
81
145
  }
82
146