atom.io 0.45.1 → 0.45.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/react/index.d.ts +4 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +22 -3
- package/dist/react/index.js.map +1 -1
- package/dist/realtime-client/index.d.ts.map +1 -1
- package/dist/realtime-client/index.js +30 -31
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-react/index.d.ts +1 -4
- package/dist/realtime-react/index.d.ts.map +1 -1
- package/dist/realtime-react/index.js +4 -23
- package/dist/realtime-react/index.js.map +1 -1
- package/dist/realtime-testing/index.js +1 -1
- package/package.json +4 -4
- package/src/react/index.ts +1 -0
- package/src/react/use-o.ts +1 -1
- package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +2 -1
- package/src/realtime-client/sync-continuity.ts +4 -4
- package/src/realtime-react/index.ts +0 -1
- package/src/realtime-react/use-realtime-service.ts +1 -1
- /package/src/{realtime-react → react}/use-single-effect.ts +0 -0
package/dist/react/index.d.ts
CHANGED
|
@@ -46,6 +46,9 @@ declare function useLoadable<T, K extends Canonical, F extends T, E>(token: Read
|
|
|
46
46
|
declare function useO<T, E = never>(token: ReadableToken<T, any, E>): ViewOf<E | T>;
|
|
47
47
|
declare function useO<T, K extends Canonical, E = never>(token: ReadableFamilyToken<T, K, E>, key: NoInfer<K>): ViewOf<E | T>;
|
|
48
48
|
//#endregion
|
|
49
|
+
//#region src/react/use-single-effect.d.ts
|
|
50
|
+
declare function useSingleEffect(effect: () => (() => void) | undefined | void, deps: unknown[]): void;
|
|
51
|
+
//#endregion
|
|
49
52
|
//#region src/react/use-tl.d.ts
|
|
50
53
|
type TimelineMeta = {
|
|
51
54
|
at: number;
|
|
@@ -55,5 +58,5 @@ type TimelineMeta = {
|
|
|
55
58
|
};
|
|
56
59
|
declare function useTL(token: TimelineToken<any>): TimelineMeta;
|
|
57
60
|
//#endregion
|
|
58
|
-
export { StoreContext, StoreProvider, TimelineMeta, useAtomicRef, useI, useJSON, useLoadable, useO, useTL };
|
|
61
|
+
export { StoreContext, StoreProvider, TimelineMeta, useAtomicRef, useI, useJSON, useLoadable, useO, useSingleEffect, useTL };
|
|
59
62
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -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-atomic-ref.ts","../../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,KAAA,CAAM,QAAQ;cAI5BC,eAAe,KAAA,CAAM;YACvB,KAAA,CAAM;UACR;AANT,CAAA,CAAA;;;iBCAgB;WAAqC;ADArD,CAAA,CAIA,CAAA,KAAaA,ECHL,gBDGKA,CCHY,CDGZA,GAAAA,IAAAA,CAAAA,EAAAA,MAAAA,EAAAA,CAAAA,EAAAA,CAAAA,CAAAA,YAAAA,ECFe,EDEfA,GAAAA,IAAAA,EAAAA,GCF6B,CDE7BA,CAAAA,ECDV,CDCUA;;;iBEAG,eACR,cAAc,4BACN,SAAS,aAAa,MAAM;iBAE5B,QFRhB,UEQkC,SFRO,CAIzC,CAAA,KAAaA,EEKL,mBFLKA,CEKe,CFLfA,EEKkB,CFLlBA,EAAAA,GAAAA,CAAAA,EAAAA,GAAAA,EEMP,OFNOA,CEMC,CFNDA,CAAAA,CAAAA,EAAAA,CAAAA,YEOG,CFPHA,CAAAA,CAAAA,IAAAA,EEOY,GFPZA,GAAAA,CAAAA,CAAAA,GAAAA,EEOyB,CFPzBA,EAAAA,GEO+B,GFP/BA,CAAAA,EAAAA,GAAAA,IAAAA;;;iBGCG,kBAAkB,mCAC1B,iBAAiB,KACtB,OAAO;iBAEM,QHThB,UGUW,WHV8B,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,CAAA,EAIzC,UGOW,SHPEA,CACF,CAAA,KAAM,EGOR,sBHPQ,CGOe,CHPf,EGOkB,CHPlB,CAAA,EAAA,GAAA,EGO2B,CHP3B,CAAA,EGO+B,MHP/B,CGOsC,CHPtC,CAAA;;;iBIGD,eJRhB,CAAA,CAIA,CAAA,KAAaA,EIKL,aJLKA,CIKS,QJLTA,CIKkB,CJLlBA,CAAAA,EAAAA,GAAAA,EIK2B,CJL3BA,CAAAA,CAAAA,EAAAA,SAAAA,GAAAA;EACF,OAAM,EAAA,OAAA;EACR,KAAA,EIIiC,MJJjC,CIIwC,CJJxC,GII4C,CJJ5C,CAAA;CAFmB;AAAM,iBIQlB,WJRkB,cIQO,aHZzC,CAAA,KAAgB,EGaR,mBHbQ,CGaY,QHbZ,CGaqB,CHbrB,CAAA,EGayB,CHbzB,EGa4B,CHb5B,CAAA,EAAA,GAAA,EGcV,OHdU,CGcF,CHdE,CAAA,CAAA,EAAA,SAAA,GAAA;EAAqC,OAAA,EAAA,OAAA;EAC5B,KAAA,EGciB,MHdjB,CGcwB,CHdxB,GGc4B,CHd5B,CAAA;CAAjB;AACoB,iBGeZ,WHfY,CAAc,CAAA,EACvC,UGcsC,CHdtC,EAAA,CAAA,SGeK,cAAc,SAAS,SAAS,cAC7B;;SACmB,OAAO;EFhBrC,KAAgB,CAAA,EEgBiC,CFhBjC;CACM;AAAd,iBEiBQ,WFjBR,CACQ,CAAA,EAAS,UEgBgB,SFhBhB,EAAa,UEgBwB,CFhBxB,EAAM,CAAA,CAAA,CAAA,KAAA,EEiBpC,mBFjBoC,CEiBhB,QFjBgB,CEiBP,CFjBO,CAAA,EEiBH,CFjBG,EEiBA,CFjBA,CAAA,EAAA,GAAA,EEkBtC,OFlBsC,CEkB9B,CFlB8B,CAAA,EAAA,QAAA,EEmBjC,CFnBiC,CAAA,EAAA;EAE5C,OAAgB,EAAA,OAAA;EAAkB,KAAA,EEkBJ,MFlBI,CEkBG,CFlBH,CAAA;EACN,KAAA,CAAA,EEiBqB,CFjBrB;CAAG;;;iBGIf,QLbhB,IAAaD,KAAAA,CAIb,CAAA,KAAaC,EKUL,aLVKA,CKUS,CLVTA,EAAAA,GAAAA,EKUiB,CLVjBA,CAAAA,CAAAA,EKWV,MLXUA,CKWH,CLXGA,GKWC,CLXDA,CAAAA;AACI,iBKYD,ILZC,CACR,CAAA,EAFmB,UKaM,SLbA,EAAA,IAAA,KAAA,SKc1B,oBAAoB,GAAG,GAAG,SAC5B,QAAQ,KACX,OAAO,IAAI;;;
|
|
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-atomic-ref.ts","../../src/react/use-i.ts","../../src/react/use-json.ts","../../src/react/use-loadable.ts","../../src/react/use-o.ts","../../src/react/use-single-effect.ts","../../src/react/use-tl.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/react/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { IMPLICIT, findInStore, getFromStore, getJsonToken, setIntoStore, subscribeToState, subscribeToTimeline, withdraw } from "atom.io/internal";
|
|
1
|
+
import { IMPLICIT, findInStore, getFromStore, getJsonToken, isFn, setIntoStore, subscribeToState, subscribeToTimeline, withdraw } from "atom.io/internal";
|
|
2
2
|
import { redo, setState, undo } from "atom.io";
|
|
3
|
+
import * as React from "react";
|
|
3
4
|
import { createContext, useCallback, useContext, useEffect, useId, useRef, useState, useSyncExternalStore } from "react";
|
|
4
5
|
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
import { useSingleEffect } from "atom.io/realtime-react";
|
|
6
6
|
import { StoreContext as StoreContext$1, useO as useO$1 } from "atom.io/react";
|
|
7
7
|
|
|
8
8
|
//#region src/react/store-context.tsx
|
|
@@ -46,6 +46,25 @@ function useI(...params) {
|
|
|
46
46
|
return setter.current;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/react/use-single-effect.ts
|
|
51
|
+
/** biome-ignore-all lint/correctness/useHookAtTopLevel: intentional */
|
|
52
|
+
function useSingleEffect(effect, deps) {
|
|
53
|
+
if (globalThis[`env`]?.NODE_ENV === `development`) {
|
|
54
|
+
const cleanupRef = React.useRef(false);
|
|
55
|
+
React.useEffect(() => {
|
|
56
|
+
let cleanupFn = cleanupRef.current;
|
|
57
|
+
if (cleanupFn === false) {
|
|
58
|
+
cleanupFn = effect() ?? true;
|
|
59
|
+
cleanupRef.current = cleanupFn;
|
|
60
|
+
} else return () => {
|
|
61
|
+
if (isFn(cleanupFn)) cleanupFn();
|
|
62
|
+
cleanupRef.current = false;
|
|
63
|
+
};
|
|
64
|
+
}, deps);
|
|
65
|
+
} else React.useEffect(effect, deps);
|
|
66
|
+
}
|
|
67
|
+
|
|
49
68
|
//#endregion
|
|
50
69
|
//#region src/react/use-o.ts
|
|
51
70
|
function useO(...params) {
|
|
@@ -182,5 +201,5 @@ function useTL(token) {
|
|
|
182
201
|
}
|
|
183
202
|
|
|
184
203
|
//#endregion
|
|
185
|
-
export { StoreContext, StoreProvider, useAtomicRef, useI, useJSON, useLoadable, useO, useTL };
|
|
204
|
+
export { StoreContext, StoreProvider, useAtomicRef, useI, useJSON, useLoadable, useO, useSingleEffect, useTL };
|
|
186
205
|
//# sourceMappingURL=index.js.map
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["StoreContext: React.Context<RootStore>","StoreProvider: React.FC<{\n\tchildren: React.ReactNode\n\tstore?: RootStore\n}>","useRef","token: ReadableToken<any, any, any>","setter: React.RefObject<\n\t\t(<New extends T>(next: New | ((old: T) => New)) => void) | null\n\t>","StoreContext","value: unknown","state: ReadableState<any, any>","fallback: unknown","key: Canonical","useO"],"sources":["../../src/react/store-context.tsx","../../src/react/use-atomic-ref.ts","../../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 { createContext } from \"react\"\n\nexport const StoreContext: React.Context<RootStore> = 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 { RegularAtomToken } from \"atom.io\"\nimport { setState } from \"atom.io\"\nimport { useEffect } from \"react\"\n\nexport function useAtomicRef<T, R extends { current: T | null }>(\n\ttoken: RegularAtomToken<T | null>,\n\tuseRef: <TT>(initialValue: TT | null) => R,\n): R {\n\tconst ref = useRef(null)\n\tuseEffect(() => {\n\t\tsetState(token, ref.current)\n\t}, [token])\n\treturn ref\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, Key, 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, Key, 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, Key, 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 { useContext, useRef } 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>(\n\ttoken: WritableFamilyToken<T, K, any>,\n\tkey: NoInfer<K>,\n): <New extends T>(next: New | ((old: T) => New)) => void\n\nexport function useI<T, K extends Canonical>(\n\t...params:\n\t\t| [WritableFamilyToken<T, K, any>, NoInfer<K>]\n\t\t| [WritableToken<T, any, any>]\n): <New extends T>(next: New | ((old: T) => New)) => void {\n\tconst store = 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> = useRef(null)\n\tsetter.current ??= (next) => {\n\t\tsetIntoStore(store, token, next)\n\t}\n\treturn setter.current\n}\n","/** biome-ignore-all lint/correctness/useHookAtTopLevel: depends on the type of atom, which shouldn't change */\nimport type { ReadableFamilyToken, ReadableToken, ViewOf } from \"atom.io\"\nimport { getFromStore, subscribeToState } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport { useSingleEffect } from \"atom.io/realtime-react\"\nimport {\n\tuseCallback,\n\tuseContext,\n\tuseId,\n\tuseRef,\n\tuseState,\n\tuseSyncExternalStore,\n} from \"react\"\n\nimport { parseStateOverloads } from \"./parse-state-overloads\"\nimport { StoreContext } from \"./store-context\"\n\nexport function useO<T, E = never>(\n\ttoken: ReadableToken<T, any, E>,\n): ViewOf<E | T>\n\nexport function useO<T, K extends Canonical, E = never>(\n\ttoken: ReadableFamilyToken<T, K, E>,\n\tkey: NoInfer<K>,\n): ViewOf<E | T>\n\nexport function useO<T, K extends Canonical, E = never>(\n\t...params:\n\t\t| [ReadableFamilyToken<T, K, E>, NoInfer<K>]\n\t\t| [ReadableToken<T, any, E>]\n): ViewOf<E | T> {\n\tconst store = useContext(StoreContext)\n\tconst token = parseStateOverloads(store, ...params)\n\tconst id = useId()\n\n\tif (\n\t\ttoken.type === `mutable_atom` ||\n\t\ttoken.type === `readonly_held_selector` ||\n\t\ttoken.type === `writable_held_selector`\n\t) {\n\t\tconst [, dispatch] = useState<number>(0)\n\t\tconst valueRef = useRef<ViewOf<E | T>>(getFromStore(store, token))\n\t\tuseSingleEffect(() => {\n\t\t\tconst unsub = subscribeToState<T, E>(\n\t\t\t\tstore,\n\t\t\t\ttoken,\n\t\t\t\t`use-o:${id}`,\n\t\t\t\t({ newValue }) => {\n\t\t\t\t\tvalueRef.current = newValue\n\t\t\t\t\tdispatch((c) => c + 1)\n\t\t\t\t},\n\t\t\t)\n\t\t\treturn unsub\n\t\t}, [token.key])\n\t\treturn valueRef.current\n\t}\n\n\tconst sub = useCallback(\n\t\t(dispatch: () => void) =>\n\t\t\tsubscribeToState<T, E>(store, token, `use-o:${id}`, dispatch),\n\t\t[token.key],\n\t)\n\tconst get = useCallback(() => getFromStore(store, token), [token.key])\n\treturn useSyncExternalStore<ViewOf<E | T>>(sub, get, get)\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 { useContext } 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 = 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 {\n\tLoadable,\n\tReadableFamilyToken,\n\tReadableToken,\n\tViewOf,\n} 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 { useContext, useRef } from \"react\"\n\nexport function useLoadable<T, E>(\n\ttoken: ReadableToken<Loadable<T>, any, E>,\n): `LOADING` | { loading: boolean; value: ViewOf<E | T> }\n\nexport function useLoadable<T, K extends Canonical, E>(\n\ttoken: ReadableFamilyToken<Loadable<T>, K, E>,\n\tkey: NoInfer<K>,\n): `LOADING` | { loading: boolean; value: ViewOf<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: ViewOf<T>; error?: E }\n\nexport function useLoadable<T, K extends Canonical, F extends T, E>(\n\ttoken: ReadableFamilyToken<Loadable<T>, K, E>,\n\tkey: NoInfer<K>,\n\tfallback: F,\n): { loading: boolean; value: ViewOf<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 = 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 hasFallback = fallback !== undefined\n\tconst isErr = `catch` in state && state.catch.some((E) => value instanceof E)\n\n\tconst wrapperRef = useRef<{\n\t\tloading: boolean\n\t\tvalue: unknown\n\t\terror?: unknown\n\t}>({ loading: false, value: null as unknown })\n\tconst lastLoadedRef = 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 && hasFallback) {\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 && hasFallback) {\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 && hasFallback) {\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 { useContext, useId, useRef, useSyncExternalStore } 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 = useContext(StoreContext)\n\tconst id = useId()\n\tconst timeline = withdraw(store, token)\n\tconst tokenRef = 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 = 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 useSyncExternalStore<TimelineMeta>(\n\t\t(dispatch) => subscribeToTimeline(store, token, `use-tl:${id}`, dispatch),\n\t\tretrieve,\n\t\tretrieve,\n\t)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["StoreContext: React.Context<RootStore>","StoreProvider: React.FC<{\n\tchildren: React.ReactNode\n\tstore?: RootStore\n}>","useRef","token: ReadableToken<any, any, any>","setter: React.RefObject<\n\t\t(<New extends T>(next: New | ((old: T) => New)) => void) | null\n\t>","StoreContext","value: unknown","state: ReadableState<any, any>","fallback: unknown","key: Canonical","useO"],"sources":["../../src/react/store-context.tsx","../../src/react/use-atomic-ref.ts","../../src/react/parse-state-overloads.ts","../../src/react/use-i.ts","../../src/react/use-single-effect.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 { createContext } from \"react\"\n\nexport const StoreContext: React.Context<RootStore> = 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 { RegularAtomToken } from \"atom.io\"\nimport { setState } from \"atom.io\"\nimport { useEffect } from \"react\"\n\nexport function useAtomicRef<T, R extends { current: T | null }>(\n\ttoken: RegularAtomToken<T | null>,\n\tuseRef: <TT>(initialValue: TT | null) => R,\n): R {\n\tconst ref = useRef(null)\n\tuseEffect(() => {\n\t\tsetState(token, ref.current)\n\t}, [token])\n\treturn ref\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, Key, 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, Key, 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, Key, 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 { useContext, useRef } 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>(\n\ttoken: WritableFamilyToken<T, K, any>,\n\tkey: NoInfer<K>,\n): <New extends T>(next: New | ((old: T) => New)) => void\n\nexport function useI<T, K extends Canonical>(\n\t...params:\n\t\t| [WritableFamilyToken<T, K, any>, NoInfer<K>]\n\t\t| [WritableToken<T, any, any>]\n): <New extends T>(next: New | ((old: T) => New)) => void {\n\tconst store = 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> = useRef(null)\n\tsetter.current ??= (next) => {\n\t\tsetIntoStore(store, token, next)\n\t}\n\treturn setter.current\n}\n","/** biome-ignore-all lint/correctness/useHookAtTopLevel: intentional */\n\nimport { isFn } from \"atom.io/internal\"\nimport * as React from \"react\"\n\nexport function useSingleEffect(\n\teffect: () => (() => void) | undefined | void,\n\tdeps: unknown[],\n): void {\n\tconst globalEnv = (globalThis as unknown as { env: any })[`env`]\n\tconst isInDev = globalEnv?.NODE_ENV === `development`\n\tif (isInDev) {\n\t\tconst cleanupRef = React.useRef<boolean | (() => void)>(false)\n\t\tReact.useEffect(() => {\n\t\t\tlet cleanupFn = cleanupRef.current\n\t\t\tif (cleanupFn === false) {\n\t\t\t\tcleanupFn = effect() ?? true\n\t\t\t\tcleanupRef.current = cleanupFn\n\t\t\t} else {\n\t\t\t\treturn () => {\n\t\t\t\t\tif (isFn(cleanupFn)) cleanupFn()\n\t\t\t\t\tcleanupRef.current = false\n\t\t\t\t}\n\t\t\t}\n\t\t}, deps)\n\t} else {\n\t\tReact.useEffect(effect, deps)\n\t}\n}\n","/** biome-ignore-all lint/correctness/useHookAtTopLevel: depends on the type of atom, which shouldn't change */\nimport type { ReadableFamilyToken, ReadableToken, ViewOf } from \"atom.io\"\nimport { getFromStore, subscribeToState } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport {\n\tuseCallback,\n\tuseContext,\n\tuseId,\n\tuseRef,\n\tuseState,\n\tuseSyncExternalStore,\n} from \"react\"\n\nimport { parseStateOverloads } from \"./parse-state-overloads\"\nimport { StoreContext } from \"./store-context\"\nimport { useSingleEffect } from \"./use-single-effect\"\n\nexport function useO<T, E = never>(\n\ttoken: ReadableToken<T, any, E>,\n): ViewOf<E | T>\n\nexport function useO<T, K extends Canonical, E = never>(\n\ttoken: ReadableFamilyToken<T, K, E>,\n\tkey: NoInfer<K>,\n): ViewOf<E | T>\n\nexport function useO<T, K extends Canonical, E = never>(\n\t...params:\n\t\t| [ReadableFamilyToken<T, K, E>, NoInfer<K>]\n\t\t| [ReadableToken<T, any, E>]\n): ViewOf<E | T> {\n\tconst store = useContext(StoreContext)\n\tconst token = parseStateOverloads(store, ...params)\n\tconst id = useId()\n\n\tif (\n\t\ttoken.type === `mutable_atom` ||\n\t\ttoken.type === `readonly_held_selector` ||\n\t\ttoken.type === `writable_held_selector`\n\t) {\n\t\tconst [, dispatch] = useState<number>(0)\n\t\tconst valueRef = useRef<ViewOf<E | T>>(getFromStore(store, token))\n\t\tuseSingleEffect(() => {\n\t\t\tconst unsub = subscribeToState<T, E>(\n\t\t\t\tstore,\n\t\t\t\ttoken,\n\t\t\t\t`use-o:${id}`,\n\t\t\t\t({ newValue }) => {\n\t\t\t\t\tvalueRef.current = newValue\n\t\t\t\t\tdispatch((c) => c + 1)\n\t\t\t\t},\n\t\t\t)\n\t\t\treturn unsub\n\t\t}, [token.key])\n\t\treturn valueRef.current\n\t}\n\n\tconst sub = useCallback(\n\t\t(dispatch: () => void) =>\n\t\t\tsubscribeToState<T, E>(store, token, `use-o:${id}`, dispatch),\n\t\t[token.key],\n\t)\n\tconst get = useCallback(() => getFromStore(store, token), [token.key])\n\treturn useSyncExternalStore<ViewOf<E | T>>(sub, get, get)\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 { useContext } 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 = 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 {\n\tLoadable,\n\tReadableFamilyToken,\n\tReadableToken,\n\tViewOf,\n} 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 { useContext, useRef } from \"react\"\n\nexport function useLoadable<T, E>(\n\ttoken: ReadableToken<Loadable<T>, any, E>,\n): `LOADING` | { loading: boolean; value: ViewOf<E | T> }\n\nexport function useLoadable<T, K extends Canonical, E>(\n\ttoken: ReadableFamilyToken<Loadable<T>, K, E>,\n\tkey: NoInfer<K>,\n): `LOADING` | { loading: boolean; value: ViewOf<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: ViewOf<T>; error?: E }\n\nexport function useLoadable<T, K extends Canonical, F extends T, E>(\n\ttoken: ReadableFamilyToken<Loadable<T>, K, E>,\n\tkey: NoInfer<K>,\n\tfallback: F,\n): { loading: boolean; value: ViewOf<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 = 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 hasFallback = fallback !== undefined\n\tconst isErr = `catch` in state && state.catch.some((E) => value instanceof E)\n\n\tconst wrapperRef = useRef<{\n\t\tloading: boolean\n\t\tvalue: unknown\n\t\terror?: unknown\n\t}>({ loading: false, value: null as unknown })\n\tconst lastLoadedRef = 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 && hasFallback) {\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 && hasFallback) {\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 && hasFallback) {\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 { useContext, useId, useRef, useSyncExternalStore } 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 = useContext(StoreContext)\n\tconst id = useId()\n\tconst timeline = withdraw(store, token)\n\tconst tokenRef = 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 = 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 useSyncExternalStore<TimelineMeta>(\n\t\t(dispatch) => subscribeToTimeline(store, token, `use-tl:${id}`, dispatch),\n\t\tretrieve,\n\t\tretrieve,\n\t)\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":["mySocketKeyAtom: AtomIO.RegularAtomToken<SocketKey | undefined>","myUserKeyAtom: AtomIO.RegularAtomToken<UserKey | null>","optimisticUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n>","confirmedUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n>"],"sources":["../../src/realtime-client/continuity/register-and-attempt-confirmed-update.ts","../../src/realtime-client/continuity/use-conceal-state.ts","../../src/realtime-client/continuity/use-reveal-state.ts","../../src/realtime-client/pull-atom.ts","../../src/realtime-client/pull-atom-family-member.ts","../../src/realtime-client/pull-mutable-atom.ts","../../src/realtime-client/pull-mutable-atom-family-member.ts","../../src/realtime-client/pull-selector.ts","../../src/realtime-client/pull-selector-family-member.ts","../../src/realtime-client/push-state.ts","../../src/realtime-client/realtime-client-stores/client-main-store.ts","../../src/realtime-client/realtime-client-stores/client-sync-store.ts","../../src/realtime-client/sync-continuity.ts"],"sourcesContent":[],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["mySocketKeyAtom: AtomIO.RegularAtomToken<SocketKey | undefined>","myUserKeyAtom: AtomIO.RegularAtomToken<UserKey | null>","optimisticUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n>","confirmedUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n>"],"sources":["../../src/realtime-client/continuity/register-and-attempt-confirmed-update.ts","../../src/realtime-client/continuity/use-conceal-state.ts","../../src/realtime-client/continuity/use-reveal-state.ts","../../src/realtime-client/pull-atom.ts","../../src/realtime-client/pull-atom-family-member.ts","../../src/realtime-client/pull-mutable-atom.ts","../../src/realtime-client/pull-mutable-atom-family-member.ts","../../src/realtime-client/pull-selector.ts","../../src/realtime-client/pull-selector-family-member.ts","../../src/realtime-client/push-state.ts","../../src/realtime-client/realtime-client-stores/client-main-store.ts","../../src/realtime-client/realtime-client-stores/client-sync-store.ts","../../src/realtime-client/sync-continuity.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAgBa,8CAEJ,0CAEC,oCACoB,MAAA,CAAO,wBAClC,MAAA,CAAO,iBAAiB,mCAEE,MAAA,CAAO,wBACjC,MAAA,CAAO,iBAAiB,uBAId,MAAA,CAAO,wBAAwB,MAAA,CAAO,iBAAiB;;;iBCzBpD,eAAA,QAAuB,oBACnB;;;iBCFJ,cAAA,QAAsB,mBACnB,IAAA,CAAK;;;iBCCR,mBAAmB,IAAA,CAAK,qBAChC,eACC,iBACD,MAAA,CAAO,iBAAiB;;;iBCHhB,+BACL,IAAA,CAAK,wBACL,kBAEH,eACC,kBACA,MAAA,CAAO,gBAAgB,GAAG,cAC7B,QAAQ;;;iBCPE,0BAA0B,mCAClC,eACC,iBACD,MAAA,CAAO,iBAAiB;;;iBCGhB,sCACL,sCACA,kBAEH,eACC,kBACA,MAAA,CAAO,uBAAuB,GAAG,SACpC,QAAQ;;;iBCZE,uBACR,eACC,iBACD,MAAA,CAAO,cAAc;;;iBCDb,sCAAsC,kBAC9C,eACC,uBACK,MAAA,CAAO,oBAAoB,GAAG,SACtC,QAAQ;;;iBCLE,oBAAoB,IAAA,CAAK,qBACjC,eACC,iBACD,cAAc;;;cCNTA,iBAAiB,MAAA,CAAO,iBAAiB;cAMzCC,eAAe,MAAA,CAAO,iBAAiB;;;cCRvCC,2BAA2B,MAAA,CAAO,iBAC9C,MAAA,CAAO;cAMKC,0BAA0B,MAAA,CAAO,iBAC7C,MAAA,CAAO;;;iBCWQ,cAAA,QACR,mBACC,sBACI"}
|
|
@@ -2,14 +2,36 @@ import { actUponStore, assignTransactionToContinuity, disposeAtom, findInStore,
|
|
|
2
2
|
import * as AtomIO from "atom.io";
|
|
3
3
|
import { parseJson } from "atom.io/json";
|
|
4
4
|
import { storageSync } from "atom.io/web";
|
|
5
|
-
import { confirmedUpdateQueueAtom as confirmedUpdateQueueAtom$1, optimisticUpdateQueueAtom as optimisticUpdateQueueAtom$1 } from "atom.io/realtime-client";
|
|
6
5
|
import { employSocket, mutexAtoms } from "atom.io/realtime";
|
|
7
6
|
|
|
7
|
+
//#region src/realtime-client/realtime-client-stores/client-main-store.ts
|
|
8
|
+
const mySocketKeyAtom = AtomIO.atom({
|
|
9
|
+
key: `mySocketKey`,
|
|
10
|
+
default: void 0
|
|
11
|
+
});
|
|
12
|
+
const myUserKeyAtom = AtomIO.atom({
|
|
13
|
+
key: `myUserKey`,
|
|
14
|
+
default: null,
|
|
15
|
+
effects: [storageSync(globalThis.localStorage, JSON, `myUserKey`)]
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/realtime-client/realtime-client-stores/client-sync-store.ts
|
|
20
|
+
const optimisticUpdateQueueAtom = AtomIO.atom({
|
|
21
|
+
key: `optimisticUpdateQueue`,
|
|
22
|
+
default: () => []
|
|
23
|
+
});
|
|
24
|
+
const confirmedUpdateQueueAtom = AtomIO.atom({
|
|
25
|
+
key: `confirmedUpdateQueue`,
|
|
26
|
+
default: () => []
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
8
30
|
//#region src/realtime-client/continuity/register-and-attempt-confirmed-update.ts
|
|
9
31
|
const useRegisterAndAttemptConfirmedUpdate = (store, continuityKey, socket, optimisticUpdates, confirmedUpdates) => (confirmed) => {
|
|
10
32
|
function reconcileEpoch(optimisticUpdate, confirmedUpdate) {
|
|
11
33
|
store.logger.info(`🧑⚖️`, `continuity`, continuityKey, `reconciling updates`);
|
|
12
|
-
setIntoStore(store, optimisticUpdateQueueAtom
|
|
34
|
+
setIntoStore(store, optimisticUpdateQueueAtom, (queue) => {
|
|
13
35
|
queue.shift();
|
|
14
36
|
return queue;
|
|
15
37
|
});
|
|
@@ -59,7 +81,7 @@ const useRegisterAndAttemptConfirmedUpdate = (store, continuityKey, socket, opti
|
|
|
59
81
|
store.logger.info(`🧑⚖️`, `continuity`, continuityKey, `epoch of confirmed update #${confirmed.epoch} does not match zeroth optimistic update #${zerothOptimisticUpdate.epoch}`);
|
|
60
82
|
if (!confirmedUpdates.some((update) => update.epoch === confirmed.epoch)) {
|
|
61
83
|
store.logger.info(`👈`, `continuity`, continuityKey, `pushing confirmed update to queue`, confirmed);
|
|
62
|
-
setIntoStore(store, confirmedUpdateQueueAtom
|
|
84
|
+
setIntoStore(store, confirmedUpdateQueueAtom, (queue) => {
|
|
63
85
|
queue.push(confirmed);
|
|
64
86
|
queue.sort((a, b) => a.epoch - b.epoch);
|
|
65
87
|
return queue;
|
|
@@ -83,7 +105,7 @@ const useRegisterAndAttemptConfirmedUpdate = (store, continuityKey, socket, opti
|
|
|
83
105
|
if (confirmedUpdates.some((update) => update.epoch === confirmed.epoch)) store.logger.info(`👍`, `continuity`, continuityKey, `confirmed update #${confirmed.epoch} is already enqueued`);
|
|
84
106
|
else {
|
|
85
107
|
store.logger.info(`👈`, `continuity`, continuityKey, `pushing confirmed update #${confirmed.epoch} to queue`);
|
|
86
|
-
setIntoStore(store, confirmedUpdateQueueAtom
|
|
108
|
+
setIntoStore(store, confirmedUpdateQueueAtom, (queue) => {
|
|
87
109
|
queue.push(confirmed);
|
|
88
110
|
queue.sort((a, b) => a.epoch - b.epoch);
|
|
89
111
|
return queue;
|
|
@@ -274,35 +296,12 @@ function pushState(store, socket, token) {
|
|
|
274
296
|
};
|
|
275
297
|
}
|
|
276
298
|
|
|
277
|
-
//#endregion
|
|
278
|
-
//#region src/realtime-client/realtime-client-stores/client-main-store.ts
|
|
279
|
-
const mySocketKeyAtom = AtomIO.atom({
|
|
280
|
-
key: `mySocketKey`,
|
|
281
|
-
default: void 0
|
|
282
|
-
});
|
|
283
|
-
const myUserKeyAtom = AtomIO.atom({
|
|
284
|
-
key: `myUserKey`,
|
|
285
|
-
default: null,
|
|
286
|
-
effects: [storageSync(globalThis.localStorage, JSON, `myUserKey`)]
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
//#endregion
|
|
290
|
-
//#region src/realtime-client/realtime-client-stores/client-sync-store.ts
|
|
291
|
-
const optimisticUpdateQueueAtom = AtomIO.atom({
|
|
292
|
-
key: `optimisticUpdateQueue`,
|
|
293
|
-
default: () => []
|
|
294
|
-
});
|
|
295
|
-
const confirmedUpdateQueueAtom = AtomIO.atom({
|
|
296
|
-
key: `confirmedUpdateQueue`,
|
|
297
|
-
default: () => []
|
|
298
|
-
});
|
|
299
|
-
|
|
300
299
|
//#endregion
|
|
301
300
|
//#region src/realtime-client/sync-continuity.ts
|
|
302
301
|
function syncContinuity(store, socket, continuity) {
|
|
303
302
|
const continuityKey = continuity.key;
|
|
304
|
-
const optimisticUpdates = getFromStore(store, optimisticUpdateQueueAtom
|
|
305
|
-
const confirmedUpdates = getFromStore(store, confirmedUpdateQueueAtom
|
|
303
|
+
const optimisticUpdates = getFromStore(store, optimisticUpdateQueueAtom);
|
|
304
|
+
const confirmedUpdates = getFromStore(store, confirmedUpdateQueueAtom);
|
|
306
305
|
const initializeContinuity = (epoch, payload) => {
|
|
307
306
|
socket.off(`continuity-init:${continuityKey}`, initializeContinuity);
|
|
308
307
|
let i = 0;
|
|
@@ -331,14 +330,14 @@ function syncContinuity(store, socket, continuity) {
|
|
|
331
330
|
const optimisticUpdateIndex = optimisticUpdates.findIndex((update) => update.id === clientUpdate.id);
|
|
332
331
|
if (optimisticUpdateIndex === -1) {
|
|
333
332
|
store.logger.info(`🤞`, `continuity`, continuityKey, `enqueuing new optimistic update`);
|
|
334
|
-
setIntoStore(store, optimisticUpdateQueueAtom
|
|
333
|
+
setIntoStore(store, optimisticUpdateQueueAtom, (queue) => {
|
|
335
334
|
queue.push(clientUpdate);
|
|
336
335
|
queue.sort((a, b) => a.epoch - b.epoch);
|
|
337
336
|
return queue;
|
|
338
337
|
});
|
|
339
338
|
} else {
|
|
340
339
|
store.logger.info(`🤞`, `continuity`, continuityKey, `replacing existing optimistic update at index ${optimisticUpdateIndex}`);
|
|
341
|
-
setIntoStore(store, optimisticUpdateQueueAtom
|
|
340
|
+
setIntoStore(store, optimisticUpdateQueueAtom, (queue) => {
|
|
342
341
|
queue[optimisticUpdateIndex] = clientUpdate;
|
|
343
342
|
return queue;
|
|
344
343
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["optimisticUpdateQueueAtom","confirmedUpdateQueueAtom","continuityEpoch: number | undefined","k: any","v: any","mySocketKeyAtom: AtomIO.RegularAtomToken<SocketKey | undefined>","myUserKeyAtom: AtomIO.RegularAtomToken<UserKey | null>","optimisticUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n>","confirmedUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n>","optimisticUpdateQueueAtom","confirmedUpdateQueueAtom","k: any","v: any"],"sources":["../../src/realtime-client/continuity/register-and-attempt-confirmed-update.ts","../../src/realtime-client/continuity/use-conceal-state.ts","../../src/realtime-client/continuity/use-reveal-state.ts","../../src/realtime-client/pull-atom.ts","../../src/realtime-client/pull-atom-family-member.ts","../../src/realtime-client/pull-mutable-atom.ts","../../src/realtime-client/pull-mutable-atom-family-member.ts","../../src/realtime-client/pull-selector-roots.ts","../../src/realtime-client/pull-selector.ts","../../src/realtime-client/pull-selector-family-member.ts","../../src/realtime-client/push-state.ts","../../src/realtime-client/realtime-client-stores/client-main-store.ts","../../src/realtime-client/realtime-client-stores/client-sync-store.ts","../../src/realtime-client/sync-continuity.ts"],"sourcesContent":["import type * as AtomIO from \"atom.io\"\nimport type { Fn, RootStore } from \"atom.io/internal\"\nimport {\n\tactUponStore,\n\tgetEpochNumberOfContinuity,\n\tingestTransactionOutcomeEvent,\n\tsetEpochNumberOfContinuity,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport type { Socket } from \"atom.io/realtime\"\nimport {\n\tconfirmedUpdateQueueAtom,\n\toptimisticUpdateQueueAtom,\n} from \"atom.io/realtime-client\"\n\nexport const useRegisterAndAttemptConfirmedUpdate =\n\t(\n\t\tstore: RootStore,\n\t\tcontinuityKey: string,\n\t\tsocket: Socket,\n\t\toptimisticUpdates: readonly AtomIO.TransactionOutcomeEvent<\n\t\t\tAtomIO.TransactionToken<Fn>\n\t\t>[],\n\t\tconfirmedUpdates: readonly AtomIO.TransactionOutcomeEvent<\n\t\t\tAtomIO.TransactionToken<Fn>\n\t\t>[],\n\t) =>\n\t(\n\t\tconfirmed: AtomIO.TransactionOutcomeEvent<AtomIO.TransactionToken<Fn>>,\n\t): void => {\n\t\tfunction reconcileEpoch(\n\t\t\toptimisticUpdate: AtomIO.TransactionOutcomeEvent<\n\t\t\t\tAtomIO.TransactionToken<Fn>\n\t\t\t>,\n\t\t\tconfirmedUpdate: AtomIO.TransactionOutcomeEvent<\n\t\t\t\tAtomIO.TransactionToken<Fn>\n\t\t\t>,\n\t\t): void {\n\t\t\tstore.logger.info(\n\t\t\t\t`🧑⚖️`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`reconciling updates`,\n\t\t\t)\n\t\t\tsetIntoStore(store, optimisticUpdateQueueAtom, (queue) => {\n\t\t\t\tqueue.shift()\n\t\t\t\treturn queue\n\t\t\t})\n\t\t\tif (optimisticUpdate.id === confirmedUpdate.id) {\n\t\t\t\tconst clientResult = JSON.stringify(optimisticUpdate.subEvents)\n\t\t\t\tconst serverResult = JSON.stringify(confirmedUpdate.subEvents)\n\t\t\t\tif (clientResult === serverResult) {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`✅`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`results for ${optimisticUpdate.id} match between client and server`,\n\t\t\t\t\t)\n\t\t\t\t\tsocket.emit(`ack:${continuityKey}`, confirmedUpdate.epoch)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// id mismatch\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`❌`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`thought update #${confirmedUpdate.epoch} was ${optimisticUpdate.token.key}:${optimisticUpdate.id}, but it was actually ${confirmedUpdate.token.key}:${confirmedUpdate.id}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tstore.logger.info(\n\t\t\t\t`🧑⚖️`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`updates do not match`,\n\t\t\t\toptimisticUpdate,\n\t\t\t\tconfirmedUpdate,\n\t\t\t)\n\t\t\tconst reversedOptimisticUpdates = optimisticUpdates.toReversed()\n\t\t\tfor (const subsequentOptimistic of reversedOptimisticUpdates) {\n\t\t\t\tingestTransactionOutcomeEvent(store, subsequentOptimistic, `oldValue`)\n\t\t\t}\n\t\t\tstore.logger.info(\n\t\t\t\t`⏪`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`undid optimistic updates:`,\n\t\t\t\treversedOptimisticUpdates,\n\t\t\t)\n\t\t\tingestTransactionOutcomeEvent(store, optimisticUpdate, `oldValue`)\n\t\t\tstore.logger.info(\n\t\t\t\t`⏪`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`undid zeroth optimistic update`,\n\t\t\t\toptimisticUpdate,\n\t\t\t)\n\t\t\tingestTransactionOutcomeEvent(store, confirmedUpdate, `newValue`)\n\t\t\tstore.logger.info(\n\t\t\t\t`⏩`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`applied confirmed update`,\n\t\t\t\tconfirmedUpdate,\n\t\t\t)\n\t\t\tsocket.emit(`ack:${continuityKey}`, confirmedUpdate.epoch)\n\n\t\t\tfor (const subsequentOptimistic of optimisticUpdates) {\n\t\t\t\tconst token = {\n\t\t\t\t\ttype: `transaction`,\n\t\t\t\t\tkey: subsequentOptimistic.token.key,\n\t\t\t\t} as const\n\t\t\t\tconst { id, params } = subsequentOptimistic\n\t\t\t\tactUponStore(store, token, id)(...params)\n\t\t\t}\n\t\t\tstore.logger.info(\n\t\t\t\t`⏩`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`reapplied subsequent optimistic updates:`,\n\t\t\t\toptimisticUpdates,\n\t\t\t)\n\t\t}\n\n\t\tstore.logger.info(\n\t\t\t`🧑⚖️`,\n\t\t\t`continuity`,\n\t\t\tcontinuityKey,\n\t\t\t`integrating confirmed update`,\n\t\t\t{ confirmedUpdate: confirmed, confirmedUpdates, optimisticUpdates },\n\t\t)\n\t\tconst zerothOptimisticUpdate = optimisticUpdates[0]\n\t\tif (zerothOptimisticUpdate) {\n\t\t\tstore.logger.info(\n\t\t\t\t`🧑⚖️`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`has optimistic updates to reconcile`,\n\t\t\t)\n\t\t\tif (confirmed.epoch === zerothOptimisticUpdate.epoch) {\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`🧑⚖️`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`epoch of confirmed update #${confirmed.epoch} matches zeroth optimistic update`,\n\t\t\t\t)\n\t\t\t\treconcileEpoch(zerothOptimisticUpdate, confirmed)\n\t\t\t\tfor (const nextConfirmed of confirmedUpdates) {\n\t\t\t\t\tconst nextOptimistic = optimisticUpdates[0]\n\t\t\t\t\tif (nextConfirmed.epoch === nextOptimistic?.epoch) {\n\t\t\t\t\t\treconcileEpoch(nextOptimistic, nextConfirmed)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// epoch mismatch\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`🧑⚖️`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`epoch of confirmed update #${confirmed.epoch} does not match zeroth optimistic update #${zerothOptimisticUpdate.epoch}`,\n\t\t\t\t)\n\t\t\t\tconst confirmedUpdateIsAlreadyEnqueued = confirmedUpdates.some(\n\t\t\t\t\t(update) => update.epoch === confirmed.epoch,\n\t\t\t\t)\n\t\t\t\tif (!confirmedUpdateIsAlreadyEnqueued) {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`👈`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`pushing confirmed update to queue`,\n\t\t\t\t\t\tconfirmed,\n\t\t\t\t\t)\n\t\t\t\t\tsetIntoStore(store, confirmedUpdateQueueAtom, (queue) => {\n\t\t\t\t\t\tqueue.push(confirmed)\n\t\t\t\t\t\tqueue.sort((a, b) => a.epoch - b.epoch)\n\t\t\t\t\t\treturn queue\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tstore.logger.info(\n\t\t\t\t`🧑⚖️`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`has no optimistic updates to deal with`,\n\t\t\t)\n\t\t\tlet continuityEpoch: number | undefined\n\t\t\tcontinuityEpoch = getEpochNumberOfContinuity(store, continuityKey)\n\n\t\t\tif (continuityEpoch === confirmed.epoch - 1) {\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`✅`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`integrating update #${confirmed.epoch} (${confirmed.token.key} ${confirmed.id})`,\n\t\t\t\t)\n\t\t\t\tingestTransactionOutcomeEvent(store, confirmed, `newValue`)\n\t\t\t\tsocket.emit(`ack:${continuityKey}`, confirmed.epoch)\n\t\t\t\tsetEpochNumberOfContinuity(store, continuityKey, confirmed.epoch)\n\t\t\t} else if (continuityEpoch !== undefined) {\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`🧑⚖️`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`received update #${confirmed.epoch} but still waiting for update #${\n\t\t\t\t\t\tcontinuityEpoch + 1\n\t\t\t\t\t}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tclientEpoch: continuityEpoch,\n\t\t\t\t\t\tserverEpoch: confirmed.epoch,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\tconst confirmedUpdateIsAlreadyEnqueued = confirmedUpdates.some(\n\t\t\t\t\t(update) => update.epoch === confirmed.epoch,\n\t\t\t\t)\n\t\t\t\tif (confirmedUpdateIsAlreadyEnqueued) {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`👍`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`confirmed update #${confirmed.epoch} is already enqueued`,\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`👈`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`pushing confirmed update #${confirmed.epoch} to queue`,\n\t\t\t\t\t)\n\t\t\t\t\tsetIntoStore(store, confirmedUpdateQueueAtom, (queue) => {\n\t\t\t\t\t\tqueue.push(confirmed)\n\t\t\t\t\t\tqueue.sort((a, b) => a.epoch - b.epoch)\n\t\t\t\t\t\treturn queue\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n","import type { AtomToken } from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { disposeAtom } from \"atom.io/internal\"\n\nexport function useConcealState(store: Store) {\n\treturn (concealed: AtomToken<unknown>[]): void => {\n\t\tfor (const token of concealed) {\n\t\t\tdisposeAtom(store, token)\n\t\t}\n\t}\n}\n","import { setIntoStore, type Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\n\nexport function useRevealState(store: Store) {\n\treturn (revealed: Json.Array): void => {\n\t\tlet i = 0\n\t\tlet k: any\n\t\tlet v: any\n\t\tfor (const x of revealed) {\n\t\t\tif (i % 2 === 0) {\n\t\t\t\tk = x\n\t\t\t} else {\n\t\t\t\tv = x\n\t\t\t\tsetIntoStore(store, k, v)\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport { setIntoStore, type Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullAtom<J extends Json.Serializable>(\n\tstore: Store,\n\tsocket: Socket,\n\ttoken: AtomIO.RegularAtomToken<J, any, any>,\n): () => void {\n\tconst setServedValue = (data: J) => {\n\t\tsetIntoStore(store, token, data)\n\t}\n\tsocket.on(`serve:${token.key}`, setServedValue)\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`serve:${token.key}`, setServedValue)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport { findInStore, setIntoStore, type Store } from \"atom.io/internal\"\nimport type { Canonical, Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullAtomFamilyMember<\n\tJ extends Json.Serializable,\n\tK extends Canonical,\n>(\n\tstore: Store,\n\tsocket: Socket,\n\tfamily: AtomIO.AtomFamilyToken<J, K, any>,\n\tkey: NoInfer<K>,\n): () => void {\n\tconst token = findInStore(store, family, key)\n\tconst setServedValue = (data: J) => {\n\t\tsetIntoStore(store, token, data)\n\t}\n\tsocket?.on(`serve:${token.key}`, setServedValue)\n\tsocket?.emit(`sub:${family.key}`, key)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`, setServedValue)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { AsJSON, SignalFrom, Store, Transceiver } from \"atom.io/internal\"\nimport { getJsonToken, getUpdateToken, setIntoStore } from \"atom.io/internal\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableAtom<T extends Transceiver<any, any, any>>(\n\tstore: Store,\n\tsocket: Socket,\n\ttoken: AtomIO.MutableAtomToken<T>,\n): () => void {\n\tconst jsonToken = getJsonToken(store, token)\n\tconst updateToken = getUpdateToken(token)\n\tsocket.on(`init:${token.key}`, (data: AsJSON<T>) => {\n\t\tsetIntoStore(store, jsonToken, data)\n\t})\n\tsocket.on(`next:${token.key}`, (data: SignalFrom<T>) => {\n\t\tsetIntoStore(store, updateToken, data)\n\t})\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`init:${token.key}`)\n\t\tsocket.off(`next:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { AsJSON, SignalFrom, Store, Transceiver } from \"atom.io/internal\"\nimport {\n\tfindInStore,\n\tgetJsonToken,\n\tgetUpdateToken,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableAtomFamilyMember<\n\tT extends Transceiver<any, any, any>,\n\tK extends Canonical,\n>(\n\tstore: Store,\n\tsocket: Socket,\n\tfamily: AtomIO.MutableAtomFamilyToken<T, K>,\n\tkey: NoInfer<K>,\n): () => void {\n\tconst token = findInStore(store, family, key)\n\tsocket.on(`init:${token.key}`, (data: AsJSON<T>) => {\n\t\tconst jsonToken = getJsonToken(store, token)\n\t\tsetIntoStore(store, jsonToken, data)\n\t})\n\tsocket.on(`next:${token.key}`, (data: SignalFrom<T>) => {\n\t\tconst trackerToken = getUpdateToken(token)\n\t\tsetIntoStore(store, trackerToken, data)\n\t})\n\tsocket.emit(`sub:${family.key}`, key)\n\treturn () => {\n\t\tsocket.off(`serve:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import type { AtomToken, SelectorToken } from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { getFamilyOfToken, subscribeToState } from \"atom.io/internal\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { pullAtom } from \"./pull-atom\"\nimport { pullAtomFamilyMember } from \"./pull-atom-family-member\"\nimport { pullMutableAtom } from \"./pull-mutable-atom\"\nimport { pullMutableAtomFamilyMember } from \"./pull-mutable-atom-family-member\"\n\nexport function pullSelectorRoots(\n\tstore: Store,\n\tsocket: Socket,\n\tselectorToken: SelectorToken<any>,\n): () => void {\n\tconst atomSubscriptions = new Map<string, () => void>()\n\tconst clearAtomSubscriptions = () => {\n\t\tfor (const [, unsub] of atomSubscriptions) unsub()\n\t\tatomSubscriptions.clear()\n\t}\n\n\tconst start = () => {\n\t\tconst atomKeys = store.selectorAtoms.getRelatedKeys(selectorToken.key)\n\t\tif (atomKeys) {\n\t\t\tfor (const [atomKey, unsub] of atomSubscriptions) {\n\t\t\t\tif (!atomKeys.has(atomKey)) {\n\t\t\t\t\tunsub()\n\t\t\t\t\tatomSubscriptions.delete(atomKey)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const atomKey of atomKeys) {\n\t\t\t\tif (atomSubscriptions.has(atomKey)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst atom = store.atoms.get(atomKey) as AtomToken<any, any>\n\t\t\t\tswitch (atom.type) {\n\t\t\t\t\tcase `atom`: {\n\t\t\t\t\t\tif (atom.family) {\n\t\t\t\t\t\t\tconst { subKey: serializedSubKey } = atom.family\n\t\t\t\t\t\t\tconst subKey = parseJson(serializedSubKey)\n\t\t\t\t\t\t\tconst family = getFamilyOfToken(store, atom)\n\t\t\t\t\t\t\tatomSubscriptions.set(\n\t\t\t\t\t\t\t\tatomKey,\n\t\t\t\t\t\t\t\tpullAtomFamilyMember(store, socket, family, subKey),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tatomSubscriptions.set(atomKey, pullAtom(store, socket, atom))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase `mutable_atom`: {\n\t\t\t\t\t\tif (atom.family) {\n\t\t\t\t\t\t\tconst { subKey: serializedSubKey } = atom.family\n\t\t\t\t\t\t\tconst subKey = parseJson(serializedSubKey)\n\t\t\t\t\t\t\tconst family = getFamilyOfToken(store, atom)\n\t\t\t\t\t\t\tatomSubscriptions.set(\n\t\t\t\t\t\t\t\tatomKey,\n\t\t\t\t\t\t\t\tpullMutableAtomFamilyMember(store, socket, family, subKey),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tatomSubscriptions.set(\n\t\t\t\t\t\t\t\tatomKey,\n\t\t\t\t\t\t\t\tpullMutableAtom(store, socket, atom),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst unsubFromSelector = subscribeToState(\n\t\tstore,\n\t\tselectorToken,\n\t\t`pull-watches-dependencies`,\n\t\t() => {\n\t\t\tstart()\n\t\t},\n\t)\n\n\tstart()\n\n\treturn () => {\n\t\tclearAtomSubscriptions()\n\t\tunsubFromSelector()\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { pullSelectorRoots } from \"./pull-selector-roots\"\n\nexport function pullSelector<T>(\n\tstore: Store,\n\tsocket: Socket,\n\ttoken: AtomIO.SelectorToken<T>,\n): () => void {\n\treturn pullSelectorRoots(store, socket, token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { findInStore } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { pullSelectorRoots } from \"./pull-selector-roots\"\n\nexport function pullSelectorFamilyMember<T, K extends Canonical>(\n\tstore: Store,\n\tsocket: Socket,\n\tfamilyToken: AtomIO.SelectorFamilyToken<T, K>,\n\tkey: NoInfer<K>,\n): () => void {\n\tconst token = findInStore(store, familyToken, key)\n\treturn pullSelectorRoots(store, socket, token)\n}\n","import type { WritableToken } from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { setIntoStore, subscribeToState } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { employSocket, mutexAtoms } from \"atom.io/realtime\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pushState<J extends Json.Serializable>(\n\tstore: Store,\n\tsocket: Socket,\n\ttoken: WritableToken<J>,\n): () => void {\n\tconst publish = (newValue: J) => {\n\t\tsocket.emit(`pub:${token.key}`, newValue)\n\t}\n\n\tconst subscriptions = new Set<() => void>()\n\tconst clearSubscriptions = () => {\n\t\tfor (const unsub of subscriptions) unsub()\n\t\tsubscriptions.clear()\n\t}\n\n\tconst init = () => {\n\t\tsubscriptions.add(\n\t\t\temploySocket(socket, `claim-result:${token.key}`, (success: boolean) => {\n\t\t\t\tif (!success) return\n\n\t\t\t\tclearSubscriptions()\n\t\t\t\tsetIntoStore(store, mutexAtoms, token.key, true)\n\t\t\t\tsubscriptions.add(\n\t\t\t\t\tsubscribeToState(store, token, `push`, ({ newValue }) => {\n\t\t\t\t\t\tpublish(newValue)\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t}),\n\t\t)\n\n\t\tsocket.emit(`claim:${token.key}`)\n\t}\n\n\tinit()\n\n\treturn () => {\n\t\tclearSubscriptions()\n\t\tsocket.emit(`unclaim:${token.key}`)\n\t}\n}\n","import * as AtomIO from \"atom.io\"\nimport type { SocketKey, UserKey } from \"atom.io/realtime\"\nimport { storageSync } from \"atom.io/web\"\n\nexport const mySocketKeyAtom: AtomIO.RegularAtomToken<SocketKey | undefined> =\n\tAtomIO.atom<SocketKey | undefined>({\n\t\tkey: `mySocketKey`,\n\t\tdefault: undefined,\n\t})\n\nexport const myUserKeyAtom: AtomIO.RegularAtomToken<UserKey | null> =\n\tAtomIO.atom<UserKey | null>({\n\t\tkey: `myUserKey`,\n\t\tdefault: null,\n\t\teffects: [storageSync(globalThis.localStorage, JSON, `myUserKey`)],\n\t})\n","import * as AtomIO from \"atom.io\"\n\nexport const optimisticUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n> = AtomIO.atom<AtomIO.TransactionOutcomeEvent<any>[]>({\n\tkey: `optimisticUpdateQueue`,\n\tdefault: () => [],\n})\n\nexport const confirmedUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n> = AtomIO.atom<AtomIO.TransactionOutcomeEvent<any>[]>({\n\tkey: `confirmedUpdateQueue`,\n\tdefault: () => [],\n})\n","import type { RootStore } from \"atom.io/internal\"\nimport {\n\tassignTransactionToContinuity,\n\tgetFromStore,\n\tgetJsonToken,\n\tsetEpochNumberOfContinuity,\n\tsetIntoStore,\n\tsubscribeToTransaction,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { ContinuityToken } from \"atom.io/realtime\"\nimport {\n\tconfirmedUpdateQueueAtom,\n\toptimisticUpdateQueueAtom,\n} from \"atom.io/realtime-client\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { useRegisterAndAttemptConfirmedUpdate } from \"./continuity/register-and-attempt-confirmed-update\"\nimport { useConcealState } from \"./continuity/use-conceal-state\"\nimport { useRevealState } from \"./continuity/use-reveal-state\"\n\nexport function syncContinuity(\n\tstore: RootStore,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n): () => void {\n\tconst continuityKey = continuity.key\n\tconst optimisticUpdates = getFromStore(store, optimisticUpdateQueueAtom)\n\tconst confirmedUpdates = getFromStore(store, confirmedUpdateQueueAtom)\n\n\tconst initializeContinuity = (epoch: number, payload: Json.Array) => {\n\t\tsocket.off(`continuity-init:${continuityKey}`, initializeContinuity)\n\t\tlet i = 0\n\t\tlet k: any\n\t\tlet v: any\n\t\tfor (const x of payload) {\n\t\t\tif (i % 2 === 0) {\n\t\t\t\tk = x\n\t\t\t} else {\n\t\t\t\tv = x\n\t\t\t\tif (`type` in k && k.type === `mutable_atom`) {\n\t\t\t\t\tk = getJsonToken(store, k)\n\t\t\t\t}\n\t\t\t\tsetIntoStore(store, k, v)\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t\tsetEpochNumberOfContinuity(store, continuityKey, epoch)\n\t}\n\tsocket.off(`continuity-init:${continuityKey}`)\n\tsocket.on(`continuity-init:${continuityKey}`, initializeContinuity)\n\n\tconst registerAndAttemptConfirmedUpdate = useRegisterAndAttemptConfirmedUpdate(\n\t\tstore,\n\t\tcontinuityKey,\n\t\tsocket,\n\t\toptimisticUpdates,\n\t\tconfirmedUpdates,\n\t)\n\tsocket.off(`tx-new:${continuityKey}`)\n\tsocket.on(`tx-new:${continuityKey}`, registerAndAttemptConfirmedUpdate)\n\n\tconst unsubscribeFunctions = continuity.actions.map((transaction) => {\n\t\tassignTransactionToContinuity(store, continuityKey, transaction.key)\n\t\tconst unsubscribeFromTransactionUpdates = subscribeToTransaction(\n\t\t\tstore,\n\t\t\ttransaction,\n\t\t\t`tx-run:${continuityKey}`,\n\t\t\t(clientUpdate) => {\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`🤞`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`enqueuing optimistic update`,\n\t\t\t\t)\n\t\t\t\tconst optimisticUpdateIndex = optimisticUpdates.findIndex(\n\t\t\t\t\t(update) => update.id === clientUpdate.id,\n\t\t\t\t)\n\t\t\t\tif (optimisticUpdateIndex === -1) {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`🤞`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`enqueuing new optimistic update`,\n\t\t\t\t\t)\n\t\t\t\t\tsetIntoStore(store, optimisticUpdateQueueAtom, (queue) => {\n\t\t\t\t\t\tqueue.push(clientUpdate)\n\t\t\t\t\t\tqueue.sort((a, b) => a.epoch - b.epoch)\n\t\t\t\t\t\treturn queue\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`🤞`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`replacing existing optimistic update at index ${optimisticUpdateIndex}`,\n\t\t\t\t\t)\n\t\t\t\t\tsetIntoStore(store, optimisticUpdateQueueAtom, (queue) => {\n\t\t\t\t\t\tqueue[optimisticUpdateIndex] = clientUpdate\n\t\t\t\t\t\treturn queue\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tsocket.emit(`tx-run:${continuityKey}`, {\n\t\t\t\t\tid: clientUpdate.id,\n\t\t\t\t\ttoken: transaction,\n\t\t\t\t\tparams: clientUpdate.params,\n\t\t\t\t})\n\t\t\t},\n\t\t)\n\t\treturn unsubscribeFromTransactionUpdates\n\t})\n\n\tconst revealState = useRevealState(store)\n\tconst concealState = useConcealState(store)\n\tsocket.on(`reveal:${continuityKey}`, revealState)\n\tsocket.on(`conceal:${continuityKey}`, concealState)\n\n\tsocket.emit(`get:${continuityKey}`)\n\treturn () => {\n\t\tsocket.off(`continuity-init:${continuityKey}`)\n\t\tsocket.off(`tx-new:${continuityKey}`)\n\t\tfor (const unsubscribe of unsubscribeFunctions) unsubscribe()\n\t\t// socket.emit(`unsub:${continuityKey}`)\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["mySocketKeyAtom: AtomIO.RegularAtomToken<SocketKey | undefined>","myUserKeyAtom: AtomIO.RegularAtomToken<UserKey | null>","optimisticUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n>","confirmedUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n>","continuityEpoch: number | undefined","k: any","v: any","k: any","v: any"],"sources":["../../src/realtime-client/realtime-client-stores/client-main-store.ts","../../src/realtime-client/realtime-client-stores/client-sync-store.ts","../../src/realtime-client/continuity/register-and-attempt-confirmed-update.ts","../../src/realtime-client/continuity/use-conceal-state.ts","../../src/realtime-client/continuity/use-reveal-state.ts","../../src/realtime-client/pull-atom.ts","../../src/realtime-client/pull-atom-family-member.ts","../../src/realtime-client/pull-mutable-atom.ts","../../src/realtime-client/pull-mutable-atom-family-member.ts","../../src/realtime-client/pull-selector-roots.ts","../../src/realtime-client/pull-selector.ts","../../src/realtime-client/pull-selector-family-member.ts","../../src/realtime-client/push-state.ts","../../src/realtime-client/sync-continuity.ts"],"sourcesContent":["import * as AtomIO from \"atom.io\"\nimport type { SocketKey, UserKey } from \"atom.io/realtime\"\nimport { storageSync } from \"atom.io/web\"\n\nexport const mySocketKeyAtom: AtomIO.RegularAtomToken<SocketKey | undefined> =\n\tAtomIO.atom<SocketKey | undefined>({\n\t\tkey: `mySocketKey`,\n\t\tdefault: undefined,\n\t})\n\nexport const myUserKeyAtom: AtomIO.RegularAtomToken<UserKey | null> =\n\tAtomIO.atom<UserKey | null>({\n\t\tkey: `myUserKey`,\n\t\tdefault: null,\n\t\teffects: [storageSync(globalThis.localStorage, JSON, `myUserKey`)],\n\t})\n","import * as AtomIO from \"atom.io\"\n\nexport const optimisticUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n> = AtomIO.atom<AtomIO.TransactionOutcomeEvent<any>[]>({\n\tkey: `optimisticUpdateQueue`,\n\tdefault: () => [],\n})\n\nexport const confirmedUpdateQueueAtom: AtomIO.RegularAtomToken<\n\tAtomIO.TransactionOutcomeEvent<any>[]\n> = AtomIO.atom<AtomIO.TransactionOutcomeEvent<any>[]>({\n\tkey: `confirmedUpdateQueue`,\n\tdefault: () => [],\n})\n","import type * as AtomIO from \"atom.io\"\nimport type { Fn, RootStore } from \"atom.io/internal\"\nimport {\n\tactUponStore,\n\tgetEpochNumberOfContinuity,\n\tingestTransactionOutcomeEvent,\n\tsetEpochNumberOfContinuity,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport type { Socket } from \"atom.io/realtime\"\n\nimport {\n\tconfirmedUpdateQueueAtom,\n\toptimisticUpdateQueueAtom,\n} from \"../realtime-client-stores\"\n\nexport const useRegisterAndAttemptConfirmedUpdate =\n\t(\n\t\tstore: RootStore,\n\t\tcontinuityKey: string,\n\t\tsocket: Socket,\n\t\toptimisticUpdates: readonly AtomIO.TransactionOutcomeEvent<\n\t\t\tAtomIO.TransactionToken<Fn>\n\t\t>[],\n\t\tconfirmedUpdates: readonly AtomIO.TransactionOutcomeEvent<\n\t\t\tAtomIO.TransactionToken<Fn>\n\t\t>[],\n\t) =>\n\t(\n\t\tconfirmed: AtomIO.TransactionOutcomeEvent<AtomIO.TransactionToken<Fn>>,\n\t): void => {\n\t\tfunction reconcileEpoch(\n\t\t\toptimisticUpdate: AtomIO.TransactionOutcomeEvent<\n\t\t\t\tAtomIO.TransactionToken<Fn>\n\t\t\t>,\n\t\t\tconfirmedUpdate: AtomIO.TransactionOutcomeEvent<\n\t\t\t\tAtomIO.TransactionToken<Fn>\n\t\t\t>,\n\t\t): void {\n\t\t\tstore.logger.info(\n\t\t\t\t`🧑⚖️`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`reconciling updates`,\n\t\t\t)\n\t\t\tsetIntoStore(store, optimisticUpdateQueueAtom, (queue) => {\n\t\t\t\tqueue.shift()\n\t\t\t\treturn queue\n\t\t\t})\n\t\t\tif (optimisticUpdate.id === confirmedUpdate.id) {\n\t\t\t\tconst clientResult = JSON.stringify(optimisticUpdate.subEvents)\n\t\t\t\tconst serverResult = JSON.stringify(confirmedUpdate.subEvents)\n\t\t\t\tif (clientResult === serverResult) {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`✅`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`results for ${optimisticUpdate.id} match between client and server`,\n\t\t\t\t\t)\n\t\t\t\t\tsocket.emit(`ack:${continuityKey}`, confirmedUpdate.epoch)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// id mismatch\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`❌`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`thought update #${confirmedUpdate.epoch} was ${optimisticUpdate.token.key}:${optimisticUpdate.id}, but it was actually ${confirmedUpdate.token.key}:${confirmedUpdate.id}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tstore.logger.info(\n\t\t\t\t`🧑⚖️`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`updates do not match`,\n\t\t\t\toptimisticUpdate,\n\t\t\t\tconfirmedUpdate,\n\t\t\t)\n\t\t\tconst reversedOptimisticUpdates = optimisticUpdates.toReversed()\n\t\t\tfor (const subsequentOptimistic of reversedOptimisticUpdates) {\n\t\t\t\tingestTransactionOutcomeEvent(store, subsequentOptimistic, `oldValue`)\n\t\t\t}\n\t\t\tstore.logger.info(\n\t\t\t\t`⏪`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`undid optimistic updates:`,\n\t\t\t\treversedOptimisticUpdates,\n\t\t\t)\n\t\t\tingestTransactionOutcomeEvent(store, optimisticUpdate, `oldValue`)\n\t\t\tstore.logger.info(\n\t\t\t\t`⏪`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`undid zeroth optimistic update`,\n\t\t\t\toptimisticUpdate,\n\t\t\t)\n\t\t\tingestTransactionOutcomeEvent(store, confirmedUpdate, `newValue`)\n\t\t\tstore.logger.info(\n\t\t\t\t`⏩`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`applied confirmed update`,\n\t\t\t\tconfirmedUpdate,\n\t\t\t)\n\t\t\tsocket.emit(`ack:${continuityKey}`, confirmedUpdate.epoch)\n\n\t\t\tfor (const subsequentOptimistic of optimisticUpdates) {\n\t\t\t\tconst token = {\n\t\t\t\t\ttype: `transaction`,\n\t\t\t\t\tkey: subsequentOptimistic.token.key,\n\t\t\t\t} as const\n\t\t\t\tconst { id, params } = subsequentOptimistic\n\t\t\t\tactUponStore(store, token, id)(...params)\n\t\t\t}\n\t\t\tstore.logger.info(\n\t\t\t\t`⏩`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`reapplied subsequent optimistic updates:`,\n\t\t\t\toptimisticUpdates,\n\t\t\t)\n\t\t}\n\n\t\tstore.logger.info(\n\t\t\t`🧑⚖️`,\n\t\t\t`continuity`,\n\t\t\tcontinuityKey,\n\t\t\t`integrating confirmed update`,\n\t\t\t{ confirmedUpdate: confirmed, confirmedUpdates, optimisticUpdates },\n\t\t)\n\t\tconst zerothOptimisticUpdate = optimisticUpdates[0]\n\t\tif (zerothOptimisticUpdate) {\n\t\t\tstore.logger.info(\n\t\t\t\t`🧑⚖️`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`has optimistic updates to reconcile`,\n\t\t\t)\n\t\t\tif (confirmed.epoch === zerothOptimisticUpdate.epoch) {\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`🧑⚖️`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`epoch of confirmed update #${confirmed.epoch} matches zeroth optimistic update`,\n\t\t\t\t)\n\t\t\t\treconcileEpoch(zerothOptimisticUpdate, confirmed)\n\t\t\t\tfor (const nextConfirmed of confirmedUpdates) {\n\t\t\t\t\tconst nextOptimistic = optimisticUpdates[0]\n\t\t\t\t\tif (nextConfirmed.epoch === nextOptimistic?.epoch) {\n\t\t\t\t\t\treconcileEpoch(nextOptimistic, nextConfirmed)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// epoch mismatch\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`🧑⚖️`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`epoch of confirmed update #${confirmed.epoch} does not match zeroth optimistic update #${zerothOptimisticUpdate.epoch}`,\n\t\t\t\t)\n\t\t\t\tconst confirmedUpdateIsAlreadyEnqueued = confirmedUpdates.some(\n\t\t\t\t\t(update) => update.epoch === confirmed.epoch,\n\t\t\t\t)\n\t\t\t\tif (!confirmedUpdateIsAlreadyEnqueued) {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`👈`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`pushing confirmed update to queue`,\n\t\t\t\t\t\tconfirmed,\n\t\t\t\t\t)\n\t\t\t\t\tsetIntoStore(store, confirmedUpdateQueueAtom, (queue) => {\n\t\t\t\t\t\tqueue.push(confirmed)\n\t\t\t\t\t\tqueue.sort((a, b) => a.epoch - b.epoch)\n\t\t\t\t\t\treturn queue\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tstore.logger.info(\n\t\t\t\t`🧑⚖️`,\n\t\t\t\t`continuity`,\n\t\t\t\tcontinuityKey,\n\t\t\t\t`has no optimistic updates to deal with`,\n\t\t\t)\n\t\t\tlet continuityEpoch: number | undefined\n\t\t\tcontinuityEpoch = getEpochNumberOfContinuity(store, continuityKey)\n\n\t\t\tif (continuityEpoch === confirmed.epoch - 1) {\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`✅`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`integrating update #${confirmed.epoch} (${confirmed.token.key} ${confirmed.id})`,\n\t\t\t\t)\n\t\t\t\tingestTransactionOutcomeEvent(store, confirmed, `newValue`)\n\t\t\t\tsocket.emit(`ack:${continuityKey}`, confirmed.epoch)\n\t\t\t\tsetEpochNumberOfContinuity(store, continuityKey, confirmed.epoch)\n\t\t\t} else if (continuityEpoch !== undefined) {\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`🧑⚖️`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`received update #${confirmed.epoch} but still waiting for update #${\n\t\t\t\t\t\tcontinuityEpoch + 1\n\t\t\t\t\t}`,\n\t\t\t\t\t{\n\t\t\t\t\t\tclientEpoch: continuityEpoch,\n\t\t\t\t\t\tserverEpoch: confirmed.epoch,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\tconst confirmedUpdateIsAlreadyEnqueued = confirmedUpdates.some(\n\t\t\t\t\t(update) => update.epoch === confirmed.epoch,\n\t\t\t\t)\n\t\t\t\tif (confirmedUpdateIsAlreadyEnqueued) {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`👍`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`confirmed update #${confirmed.epoch} is already enqueued`,\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`👈`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`pushing confirmed update #${confirmed.epoch} to queue`,\n\t\t\t\t\t)\n\t\t\t\t\tsetIntoStore(store, confirmedUpdateQueueAtom, (queue) => {\n\t\t\t\t\t\tqueue.push(confirmed)\n\t\t\t\t\t\tqueue.sort((a, b) => a.epoch - b.epoch)\n\t\t\t\t\t\treturn queue\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n","import type { AtomToken } from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { disposeAtom } from \"atom.io/internal\"\n\nexport function useConcealState(store: Store) {\n\treturn (concealed: AtomToken<unknown>[]): void => {\n\t\tfor (const token of concealed) {\n\t\t\tdisposeAtom(store, token)\n\t\t}\n\t}\n}\n","import { setIntoStore, type Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\n\nexport function useRevealState(store: Store) {\n\treturn (revealed: Json.Array): void => {\n\t\tlet i = 0\n\t\tlet k: any\n\t\tlet v: any\n\t\tfor (const x of revealed) {\n\t\t\tif (i % 2 === 0) {\n\t\t\t\tk = x\n\t\t\t} else {\n\t\t\t\tv = x\n\t\t\t\tsetIntoStore(store, k, v)\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport { setIntoStore, type Store } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullAtom<J extends Json.Serializable>(\n\tstore: Store,\n\tsocket: Socket,\n\ttoken: AtomIO.RegularAtomToken<J, any, any>,\n): () => void {\n\tconst setServedValue = (data: J) => {\n\t\tsetIntoStore(store, token, data)\n\t}\n\tsocket.on(`serve:${token.key}`, setServedValue)\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`serve:${token.key}`, setServedValue)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport { findInStore, setIntoStore, type Store } from \"atom.io/internal\"\nimport type { Canonical, Json } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullAtomFamilyMember<\n\tJ extends Json.Serializable,\n\tK extends Canonical,\n>(\n\tstore: Store,\n\tsocket: Socket,\n\tfamily: AtomIO.AtomFamilyToken<J, K, any>,\n\tkey: NoInfer<K>,\n): () => void {\n\tconst token = findInStore(store, family, key)\n\tconst setServedValue = (data: J) => {\n\t\tsetIntoStore(store, token, data)\n\t}\n\tsocket?.on(`serve:${token.key}`, setServedValue)\n\tsocket?.emit(`sub:${family.key}`, key)\n\treturn () => {\n\t\tsocket?.off(`serve:${token.key}`, setServedValue)\n\t\tsocket?.emit(`unsub:${token.key}`)\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { AsJSON, SignalFrom, Store, Transceiver } from \"atom.io/internal\"\nimport { getJsonToken, getUpdateToken, setIntoStore } from \"atom.io/internal\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableAtom<T extends Transceiver<any, any, any>>(\n\tstore: Store,\n\tsocket: Socket,\n\ttoken: AtomIO.MutableAtomToken<T>,\n): () => void {\n\tconst jsonToken = getJsonToken(store, token)\n\tconst updateToken = getUpdateToken(token)\n\tsocket.on(`init:${token.key}`, (data: AsJSON<T>) => {\n\t\tsetIntoStore(store, jsonToken, data)\n\t})\n\tsocket.on(`next:${token.key}`, (data: SignalFrom<T>) => {\n\t\tsetIntoStore(store, updateToken, data)\n\t})\n\tsocket.emit(`sub:${token.key}`)\n\treturn () => {\n\t\tsocket.off(`init:${token.key}`)\n\t\tsocket.off(`next:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { AsJSON, SignalFrom, Store, Transceiver } from \"atom.io/internal\"\nimport {\n\tfindInStore,\n\tgetJsonToken,\n\tgetUpdateToken,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pullMutableAtomFamilyMember<\n\tT extends Transceiver<any, any, any>,\n\tK extends Canonical,\n>(\n\tstore: Store,\n\tsocket: Socket,\n\tfamily: AtomIO.MutableAtomFamilyToken<T, K>,\n\tkey: NoInfer<K>,\n): () => void {\n\tconst token = findInStore(store, family, key)\n\tsocket.on(`init:${token.key}`, (data: AsJSON<T>) => {\n\t\tconst jsonToken = getJsonToken(store, token)\n\t\tsetIntoStore(store, jsonToken, data)\n\t})\n\tsocket.on(`next:${token.key}`, (data: SignalFrom<T>) => {\n\t\tconst trackerToken = getUpdateToken(token)\n\t\tsetIntoStore(store, trackerToken, data)\n\t})\n\tsocket.emit(`sub:${family.key}`, key)\n\treturn () => {\n\t\tsocket.off(`serve:${token.key}`)\n\t\tsocket.emit(`unsub:${token.key}`)\n\t}\n}\n","import type { AtomToken, SelectorToken } from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { getFamilyOfToken, subscribeToState } from \"atom.io/internal\"\nimport { parseJson } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { pullAtom } from \"./pull-atom\"\nimport { pullAtomFamilyMember } from \"./pull-atom-family-member\"\nimport { pullMutableAtom } from \"./pull-mutable-atom\"\nimport { pullMutableAtomFamilyMember } from \"./pull-mutable-atom-family-member\"\n\nexport function pullSelectorRoots(\n\tstore: Store,\n\tsocket: Socket,\n\tselectorToken: SelectorToken<any>,\n): () => void {\n\tconst atomSubscriptions = new Map<string, () => void>()\n\tconst clearAtomSubscriptions = () => {\n\t\tfor (const [, unsub] of atomSubscriptions) unsub()\n\t\tatomSubscriptions.clear()\n\t}\n\n\tconst start = () => {\n\t\tconst atomKeys = store.selectorAtoms.getRelatedKeys(selectorToken.key)\n\t\tif (atomKeys) {\n\t\t\tfor (const [atomKey, unsub] of atomSubscriptions) {\n\t\t\t\tif (!atomKeys.has(atomKey)) {\n\t\t\t\t\tunsub()\n\t\t\t\t\tatomSubscriptions.delete(atomKey)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const atomKey of atomKeys) {\n\t\t\t\tif (atomSubscriptions.has(atomKey)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst atom = store.atoms.get(atomKey) as AtomToken<any, any>\n\t\t\t\tswitch (atom.type) {\n\t\t\t\t\tcase `atom`: {\n\t\t\t\t\t\tif (atom.family) {\n\t\t\t\t\t\t\tconst { subKey: serializedSubKey } = atom.family\n\t\t\t\t\t\t\tconst subKey = parseJson(serializedSubKey)\n\t\t\t\t\t\t\tconst family = getFamilyOfToken(store, atom)\n\t\t\t\t\t\t\tatomSubscriptions.set(\n\t\t\t\t\t\t\t\tatomKey,\n\t\t\t\t\t\t\t\tpullAtomFamilyMember(store, socket, family, subKey),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tatomSubscriptions.set(atomKey, pullAtom(store, socket, atom))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase `mutable_atom`: {\n\t\t\t\t\t\tif (atom.family) {\n\t\t\t\t\t\t\tconst { subKey: serializedSubKey } = atom.family\n\t\t\t\t\t\t\tconst subKey = parseJson(serializedSubKey)\n\t\t\t\t\t\t\tconst family = getFamilyOfToken(store, atom)\n\t\t\t\t\t\t\tatomSubscriptions.set(\n\t\t\t\t\t\t\t\tatomKey,\n\t\t\t\t\t\t\t\tpullMutableAtomFamilyMember(store, socket, family, subKey),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tatomSubscriptions.set(\n\t\t\t\t\t\t\t\tatomKey,\n\t\t\t\t\t\t\t\tpullMutableAtom(store, socket, atom),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst unsubFromSelector = subscribeToState(\n\t\tstore,\n\t\tselectorToken,\n\t\t`pull-watches-dependencies`,\n\t\t() => {\n\t\t\tstart()\n\t\t},\n\t)\n\n\tstart()\n\n\treturn () => {\n\t\tclearAtomSubscriptions()\n\t\tunsubFromSelector()\n\t}\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { pullSelectorRoots } from \"./pull-selector-roots\"\n\nexport function pullSelector<T>(\n\tstore: Store,\n\tsocket: Socket,\n\ttoken: AtomIO.SelectorToken<T>,\n): () => void {\n\treturn pullSelectorRoots(store, socket, token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { findInStore } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { pullSelectorRoots } from \"./pull-selector-roots\"\n\nexport function pullSelectorFamilyMember<T, K extends Canonical>(\n\tstore: Store,\n\tsocket: Socket,\n\tfamilyToken: AtomIO.SelectorFamilyToken<T, K>,\n\tkey: NoInfer<K>,\n): () => void {\n\tconst token = findInStore(store, familyToken, key)\n\treturn pullSelectorRoots(store, socket, token)\n}\n","import type { WritableToken } from \"atom.io\"\nimport type { Store } from \"atom.io/internal\"\nimport { setIntoStore, subscribeToState } from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport { employSocket, mutexAtoms } from \"atom.io/realtime\"\nimport type { Socket } from \"socket.io-client\"\n\nexport function pushState<J extends Json.Serializable>(\n\tstore: Store,\n\tsocket: Socket,\n\ttoken: WritableToken<J>,\n): () => void {\n\tconst publish = (newValue: J) => {\n\t\tsocket.emit(`pub:${token.key}`, newValue)\n\t}\n\n\tconst subscriptions = new Set<() => void>()\n\tconst clearSubscriptions = () => {\n\t\tfor (const unsub of subscriptions) unsub()\n\t\tsubscriptions.clear()\n\t}\n\n\tconst init = () => {\n\t\tsubscriptions.add(\n\t\t\temploySocket(socket, `claim-result:${token.key}`, (success: boolean) => {\n\t\t\t\tif (!success) return\n\n\t\t\t\tclearSubscriptions()\n\t\t\t\tsetIntoStore(store, mutexAtoms, token.key, true)\n\t\t\t\tsubscriptions.add(\n\t\t\t\t\tsubscribeToState(store, token, `push`, ({ newValue }) => {\n\t\t\t\t\t\tpublish(newValue)\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t}),\n\t\t)\n\n\t\tsocket.emit(`claim:${token.key}`)\n\t}\n\n\tinit()\n\n\treturn () => {\n\t\tclearSubscriptions()\n\t\tsocket.emit(`unclaim:${token.key}`)\n\t}\n}\n","import type { RootStore } from \"atom.io/internal\"\nimport {\n\tassignTransactionToContinuity,\n\tgetFromStore,\n\tgetJsonToken,\n\tsetEpochNumberOfContinuity,\n\tsetIntoStore,\n\tsubscribeToTransaction,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\nimport type { ContinuityToken } from \"atom.io/realtime\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { useRegisterAndAttemptConfirmedUpdate } from \"./continuity/register-and-attempt-confirmed-update\"\nimport { useConcealState } from \"./continuity/use-conceal-state\"\nimport { useRevealState } from \"./continuity/use-reveal-state\"\nimport {\n\tconfirmedUpdateQueueAtom,\n\toptimisticUpdateQueueAtom,\n} from \"./realtime-client-stores\"\n\nexport function syncContinuity(\n\tstore: RootStore,\n\tsocket: Socket,\n\tcontinuity: ContinuityToken,\n): () => void {\n\tconst continuityKey = continuity.key\n\tconst optimisticUpdates = getFromStore(store, optimisticUpdateQueueAtom)\n\tconst confirmedUpdates = getFromStore(store, confirmedUpdateQueueAtom)\n\n\tconst initializeContinuity = (epoch: number, payload: Json.Array) => {\n\t\tsocket.off(`continuity-init:${continuityKey}`, initializeContinuity)\n\t\tlet i = 0\n\t\tlet k: any\n\t\tlet v: any\n\t\tfor (const x of payload) {\n\t\t\tif (i % 2 === 0) {\n\t\t\t\tk = x\n\t\t\t} else {\n\t\t\t\tv = x\n\t\t\t\tif (`type` in k && k.type === `mutable_atom`) {\n\t\t\t\t\tk = getJsonToken(store, k)\n\t\t\t\t}\n\t\t\t\tsetIntoStore(store, k, v)\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t\tsetEpochNumberOfContinuity(store, continuityKey, epoch)\n\t}\n\tsocket.off(`continuity-init:${continuityKey}`)\n\tsocket.on(`continuity-init:${continuityKey}`, initializeContinuity)\n\n\tconst registerAndAttemptConfirmedUpdate = useRegisterAndAttemptConfirmedUpdate(\n\t\tstore,\n\t\tcontinuityKey,\n\t\tsocket,\n\t\toptimisticUpdates,\n\t\tconfirmedUpdates,\n\t)\n\tsocket.off(`tx-new:${continuityKey}`)\n\tsocket.on(`tx-new:${continuityKey}`, registerAndAttemptConfirmedUpdate)\n\n\tconst unsubscribeFunctions = continuity.actions.map((transaction) => {\n\t\tassignTransactionToContinuity(store, continuityKey, transaction.key)\n\t\tconst unsubscribeFromTransactionUpdates = subscribeToTransaction(\n\t\t\tstore,\n\t\t\ttransaction,\n\t\t\t`tx-run:${continuityKey}`,\n\t\t\t(clientUpdate) => {\n\t\t\t\tstore.logger.info(\n\t\t\t\t\t`🤞`,\n\t\t\t\t\t`continuity`,\n\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t`enqueuing optimistic update`,\n\t\t\t\t)\n\t\t\t\tconst optimisticUpdateIndex = optimisticUpdates.findIndex(\n\t\t\t\t\t(update) => update.id === clientUpdate.id,\n\t\t\t\t)\n\t\t\t\tif (optimisticUpdateIndex === -1) {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`🤞`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`enqueuing new optimistic update`,\n\t\t\t\t\t)\n\t\t\t\t\tsetIntoStore(store, optimisticUpdateQueueAtom, (queue) => {\n\t\t\t\t\t\tqueue.push(clientUpdate)\n\t\t\t\t\t\tqueue.sort((a, b) => a.epoch - b.epoch)\n\t\t\t\t\t\treturn queue\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tstore.logger.info(\n\t\t\t\t\t\t`🤞`,\n\t\t\t\t\t\t`continuity`,\n\t\t\t\t\t\tcontinuityKey,\n\t\t\t\t\t\t`replacing existing optimistic update at index ${optimisticUpdateIndex}`,\n\t\t\t\t\t)\n\t\t\t\t\tsetIntoStore(store, optimisticUpdateQueueAtom, (queue) => {\n\t\t\t\t\t\tqueue[optimisticUpdateIndex] = clientUpdate\n\t\t\t\t\t\treturn queue\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tsocket.emit(`tx-run:${continuityKey}`, {\n\t\t\t\t\tid: clientUpdate.id,\n\t\t\t\t\ttoken: transaction,\n\t\t\t\t\tparams: clientUpdate.params,\n\t\t\t\t})\n\t\t\t},\n\t\t)\n\t\treturn unsubscribeFromTransactionUpdates\n\t})\n\n\tconst revealState = useRevealState(store)\n\tconst concealState = useConcealState(store)\n\tsocket.on(`reveal:${continuityKey}`, revealState)\n\tsocket.on(`conceal:${continuityKey}`, concealState)\n\n\tsocket.emit(`get:${continuityKey}`)\n\treturn () => {\n\t\tsocket.off(`continuity-init:${continuityKey}`)\n\t\tsocket.off(`tx-new:${continuityKey}`)\n\t\tfor (const unsubscribe of unsubscribeFunctions) unsubscribe()\n\t\t// socket.emit(`unsub:${continuityKey}`)\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -47,11 +47,8 @@ declare function useRealtimeRooms<RoomNames extends string>(): Socket$1<{}, Room
|
|
|
47
47
|
//#region src/realtime-react/use-realtime-service.d.ts
|
|
48
48
|
declare function useRealtimeService(key: string, create: (socket: Socket$1) => () => void): void;
|
|
49
49
|
//#endregion
|
|
50
|
-
//#region src/realtime-react/use-single-effect.d.ts
|
|
51
|
-
declare function useSingleEffect(effect: () => (() => void) | undefined | void, deps: unknown[]): void;
|
|
52
|
-
//#endregion
|
|
53
50
|
//#region src/realtime-react/use-sync-continuity.d.ts
|
|
54
51
|
declare function useSyncContinuity(token: ContinuityToken): void;
|
|
55
52
|
//#endregion
|
|
56
|
-
export { RealtimeContext, RealtimeProvider, RealtimeReactStore, RealtimeServiceCounter, usePullAtom, usePullAtomFamilyMember, usePullMutable, usePullMutableAtomFamilyMember, usePullSelector, usePullSelectorFamilyMember, usePush, useRealtimeRooms, useRealtimeService,
|
|
53
|
+
export { RealtimeContext, RealtimeProvider, RealtimeReactStore, RealtimeServiceCounter, usePullAtom, usePullAtomFamilyMember, usePullMutable, usePullMutableAtomFamilyMember, usePullSelector, usePullSelectorFamilyMember, usePush, useRealtimeRooms, useRealtimeService, useSyncContinuity };
|
|
57
54
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":["RealtimeContext: React.Context<RealtimeReactStore>","RealtimeProvider: React.FC<{\n\tchildren: React.ReactNode\n\tsocket: Socket | null\n}>"],"sources":["../../src/realtime-react/realtime-context.tsx","../../src/realtime-react/use-pull-atom.ts","../../src/realtime-react/use-pull-atom-family-member.ts","../../src/realtime-react/use-pull-mutable-atom.ts","../../src/realtime-react/use-pull-mutable-family-member.ts","../../src/realtime-react/use-pull-selector.ts","../../src/realtime-react/use-pull-selector-family-member.ts","../../src/realtime-react/use-push.ts","../../src/realtime-react/use-realtime-rooms.ts","../../src/realtime-react/use-realtime-service.ts","../../src/realtime-react/use-
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["RealtimeContext: React.Context<RealtimeReactStore>","RealtimeProvider: React.FC<{\n\tchildren: React.ReactNode\n\tsocket: Socket | null\n}>"],"sources":["../../src/realtime-react/realtime-context.tsx","../../src/realtime-react/use-pull-atom.ts","../../src/realtime-react/use-pull-atom-family-member.ts","../../src/realtime-react/use-pull-mutable-atom.ts","../../src/realtime-react/use-pull-mutable-family-member.ts","../../src/realtime-react/use-pull-selector.ts","../../src/realtime-react/use-pull-selector-family-member.ts","../../src/realtime-react/use-push.ts","../../src/realtime-react/use-realtime-rooms.ts","../../src/realtime-react/use-realtime-service.ts","../../src/realtime-react/use-sync-continuity.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAKY,sBAAA;;;;KAKA,kBAAA;UACH;EANT,QAAY,EAOD,GAPC,CAAA,MAAA,EAOW,sBAPX,CAAA,GAAA,IAAA;AAKZ,CAAA;AACS,cAIIA,eAJJ,EAIqB,KAAA,CAAM,OAJ3B,CAImC,kBAJnC,CAAA;AACc,cASVC,gBATU,EASQ,KAAA,CAAM,EATd,CAAA;EAAZ,QAAA,EAUA,KAAA,CAAM,SAVN;EAAA,MAAA,EAWF,QAXE,GAAA,IAAA;AAGX,CAAA,CAAA;;;iBCPgB,sBAAsB,IAAA,CAAK,qBACnC,MAAA,CAAO,iBAAiB,KAC7B,MAAA,CAAO,OAAO;;;iBCDD,kCACL,IAAA,CAAK,wBACL,mBAEF,MAAA,CAAO,uBAAuB,GAAG,YACjC,QAAQ,KACd,MAAA,CAAO,OAAO;;;iBCPD,yBAAyB,mCACjC,MAAA,CAAO,iBAAiB,KAC7B;;;iBCAa,yCACL,sCACA,wBACI,MAAA,CAAO,uBAAuB,GAAG,SAAS,QAAQ,KAAK;;;iBCLtD,0BAA0B,IAAA,CAAK,qBACvC,MAAA,CAAO,cAAc,KAC1B,MAAA,CAAO,OAAO;;;iBCDD,yCAAyC,wBAC3C,MAAA,CAAO,oBAAoB,GAAG,SACtC,QAAQ,KACX,MAAA,CAAO,OAAO;;;iBCHD,kBAAkB,IAAA,CAAK,qBAC/B,MAAA,CAAO,cAAc,mBACZ,SAAS,aAAa,MAAM;;;iBCL7B,8CAA8C,aAE7D,oBAAoB;;;iBCFL,kBAAA,+BAEE;;;iBCDF,iBAAA,QAAyB"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { findInStore
|
|
1
|
+
import { findInStore } from "atom.io/internal";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
|
-
import { StoreContext, useI, useO } from "atom.io/react";
|
|
4
|
+
import { StoreContext, useI, useO, useSingleEffect } from "atom.io/react";
|
|
5
|
+
import * as RT from "atom.io/realtime";
|
|
5
6
|
import * as RTC from "atom.io/realtime-client";
|
|
6
7
|
import { syncContinuity } from "atom.io/realtime-client";
|
|
7
|
-
import * as RT from "atom.io/realtime";
|
|
8
8
|
|
|
9
9
|
//#region src/realtime-react/realtime-context.tsx
|
|
10
10
|
const RealtimeContext = React.createContext({
|
|
@@ -32,25 +32,6 @@ const RealtimeProvider = ({ children, socket }) => {
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
//#endregion
|
|
36
|
-
//#region src/realtime-react/use-single-effect.ts
|
|
37
|
-
/** biome-ignore-all lint/correctness/useHookAtTopLevel: intentional */
|
|
38
|
-
function useSingleEffect(effect, deps) {
|
|
39
|
-
if (globalThis[`env`]?.NODE_ENV === `development`) {
|
|
40
|
-
const cleanupRef = React.useRef(false);
|
|
41
|
-
React.useEffect(() => {
|
|
42
|
-
let cleanupFn = cleanupRef.current;
|
|
43
|
-
if (cleanupFn === false) {
|
|
44
|
-
cleanupFn = effect() ?? true;
|
|
45
|
-
cleanupRef.current = cleanupFn;
|
|
46
|
-
} else return () => {
|
|
47
|
-
if (isFn(cleanupFn)) cleanupFn();
|
|
48
|
-
cleanupRef.current = false;
|
|
49
|
-
};
|
|
50
|
-
}, deps);
|
|
51
|
-
} else React.useEffect(effect, deps);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
35
|
//#endregion
|
|
55
36
|
//#region src/realtime-react/use-realtime-service.ts
|
|
56
37
|
function useRealtimeService(key, create) {
|
|
@@ -155,5 +136,5 @@ function useSyncContinuity(token) {
|
|
|
155
136
|
}
|
|
156
137
|
|
|
157
138
|
//#endregion
|
|
158
|
-
export { RealtimeContext, RealtimeProvider, usePullAtom, usePullAtomFamilyMember, usePullMutable, usePullMutableAtomFamilyMember, usePullSelector, usePullSelectorFamilyMember, usePush, useRealtimeRooms, useRealtimeService,
|
|
139
|
+
export { RealtimeContext, RealtimeProvider, usePullAtom, usePullAtomFamilyMember, usePullMutable, usePullMutableAtomFamilyMember, usePullSelector, usePullSelectorFamilyMember, usePush, useRealtimeRooms, useRealtimeService, useSyncContinuity };
|
|
159
140
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["RealtimeContext: React.Context<RealtimeReactStore>","RealtimeProvider: React.FC<{\n\tchildren: React.ReactNode\n\tsocket: Socket | null\n}>"],"sources":["../../src/realtime-react/realtime-context.tsx","../../src/realtime-react/use-single-effect.ts","../../src/realtime-react/use-realtime-service.ts","../../src/realtime-react/use-pull-atom.ts","../../src/realtime-react/use-pull-atom-family-member.ts","../../src/realtime-react/use-pull-mutable-atom.ts","../../src/realtime-react/use-pull-mutable-family-member.ts","../../src/realtime-react/use-pull-selector.ts","../../src/realtime-react/use-pull-selector-family-member.ts","../../src/realtime-react/use-push.ts","../../src/realtime-react/use-realtime-rooms.ts","../../src/realtime-react/use-sync-continuity.ts"],"sourcesContent":["import { useI } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\nimport type { Socket } from \"socket.io-client\"\n\nexport type RealtimeServiceCounter = {\n\tconsumerCount: number\n\tdispose: () => void\n}\n\nexport type RealtimeReactStore = {\n\tsocket: Socket | null\n\tservices: Map<string, RealtimeServiceCounter> | null\n}\n\nexport const RealtimeContext: React.Context<RealtimeReactStore> =\n\tReact.createContext({\n\t\tsocket: null,\n\t\tservices: null,\n\t})\n\nexport const RealtimeProvider: React.FC<{\n\tchildren: React.ReactNode\n\tsocket: Socket | null\n}> = ({ children, socket }) => {\n\tconst services = React.useRef(\n\t\tnew Map<string, RealtimeServiceCounter>(),\n\t).current\n\tconst setMySocketKey = useI(RTC.mySocketKeyAtom)\n\tReact.useEffect(() => {\n\t\tsetMySocketKey(socket?.id ? `socket::${socket.id}` : undefined)\n\t\tsocket?.on(`connect`, () => {\n\t\t\tsetMySocketKey(socket?.id ? `socket::${socket.id}` : undefined)\n\t\t})\n\t\tsocket?.on(`disconnect`, () => {\n\t\t\tsetMySocketKey(undefined)\n\t\t})\n\t}, [socket, setMySocketKey])\n\treturn (\n\t\t<RealtimeContext.Provider value={{ socket, services }}>\n\t\t\t{children}\n\t\t</RealtimeContext.Provider>\n\t)\n}\n","/** biome-ignore-all lint/correctness/useHookAtTopLevel: intentional */\n\nimport { isFn } from \"atom.io/internal\"\nimport * as React from \"react\"\n\nexport function useSingleEffect(\n\teffect: () => (() => void) | undefined | void,\n\tdeps: unknown[],\n): void {\n\tconst globalEnv = (globalThis as unknown as { env: any })[`env`]\n\tconst isInDev = globalEnv?.NODE_ENV === `development`\n\tif (isInDev) {\n\t\tconst cleanupRef = React.useRef<boolean | (() => void)>(false)\n\t\tReact.useEffect(() => {\n\t\t\tlet cleanupFn = cleanupRef.current\n\t\t\tif (cleanupFn === false) {\n\t\t\t\tcleanupFn = effect() ?? true\n\t\t\t\tcleanupRef.current = cleanupFn\n\t\t\t} else {\n\t\t\t\treturn () => {\n\t\t\t\t\tif (isFn(cleanupFn)) cleanupFn()\n\t\t\t\t\tcleanupRef.current = false\n\t\t\t\t}\n\t\t\t}\n\t\t}, deps)\n\t} else {\n\t\tReact.useEffect(effect, deps)\n\t}\n}\n","import * as React from \"react\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { RealtimeContext } from \"./realtime-context\"\nimport { useSingleEffect } from \"./use-single-effect\"\n\nexport function useRealtimeService(\n\tkey: string,\n\tcreate: (socket: Socket) => () => void,\n): void {\n\tconst { socket, services } = React.useContext(RealtimeContext)\n\tuseSingleEffect(() => {\n\t\tlet service = services?.get(key)\n\t\tif (service) {\n\t\t\t++service.consumerCount\n\t\t} else if (socket) {\n\t\t\tconst dispose = create(socket)\n\t\t\tservice = { consumerCount: 1, dispose }\n\t\t\tservices?.set(key, service)\n\t\t}\n\t\treturn () => {\n\t\t\tif (service) {\n\t\t\t\t--service.consumerCount\n\t\t\t\tif (service.consumerCount === 0) {\n\t\t\t\t\tservice.dispose?.()\n\t\t\t\t\tservices?.delete(key)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [socket, key])\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullAtom<J extends Json.Serializable>(\n\ttoken: AtomIO.RegularAtomToken<J>,\n): AtomIO.ViewOf<J> {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullAtom(store, socket, token),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport { findInStore } from \"atom.io/internal\"\nimport type { Canonical, Json } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullAtomFamilyMember<\n\tJ extends Json.Serializable,\n\tK extends Canonical,\n>(\n\tfamily: AtomIO.RegularAtomFamilyToken<J, K>,\n\tsubKey: NoInfer<K>,\n): AtomIO.ViewOf<J> {\n\tconst store = React.useContext(StoreContext)\n\tconst token = findInStore(store, family, subKey)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullAtomFamilyMember(store, socket, family, subKey),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullMutable<T extends Transceiver<any, any, any>>(\n\ttoken: AtomIO.MutableAtomToken<T>,\n): T {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullMutableAtom(store, socket, token),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport { findInStore } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullMutableAtomFamilyMember<\n\tT extends Transceiver<any, any, any>,\n\tK extends Canonical,\n>(familyToken: AtomIO.MutableAtomFamilyToken<T, K>, key: NoInfer<K>): T {\n\tconst store = React.useContext(StoreContext)\n\tconst token = findInStore(store, familyToken, key)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullMutableAtomFamilyMember(store, socket, familyToken, key),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullSelector<J extends Json.Serializable>(\n\ttoken: AtomIO.SelectorToken<J>,\n): AtomIO.ViewOf<J> {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullSelector(store, socket, token),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport { findInStore } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullSelectorFamilyMember<T, K extends Canonical>(\n\tfamilyToken: AtomIO.SelectorFamilyToken<T, K>,\n\tkey: NoInfer<K>,\n): AtomIO.ViewOf<T> {\n\tconst store = React.useContext(StoreContext)\n\tconst token = findInStore(store, familyToken, key)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullSelectorFamilyMember(store, socket, familyToken, key),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext, useI, useO } from \"atom.io/react\"\nimport * as RT from \"atom.io/realtime\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePush<J extends Json.Serializable>(\n\ttoken: AtomIO.WritableToken<J>,\n): (<New extends J>(next: New | ((old: J) => New)) => void) | null {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`push:${token.key}`, (socket) =>\n\t\tRTC.pushState(store, socket, token),\n\t)\n\tconst mutex = useO(RT.mutexAtoms, token.key)\n\tconst setter = useI(token)\n\n\treturn mutex ? setter : null\n}\n","import type { RoomSocketInterface } from \"atom.io/realtime\"\nimport * as React from \"react\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { RealtimeContext } from \"./realtime-context\"\n\nexport function useRealtimeRooms<RoomNames extends string>(): Socket<\n\t{},\n\tRoomSocketInterface<RoomNames>\n> {\n\tconst { socket } = React.useContext(RealtimeContext)\n\treturn socket as Socket<{}, RoomSocketInterface<RoomNames>>\n}\n","import { StoreContext } from \"atom.io/react\"\nimport type { ContinuityToken } from \"atom.io/realtime\"\nimport { syncContinuity } from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function useSyncContinuity(token: ContinuityToken): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`tx-sync:${token.key}`, (socket) => {\n\t\treturn syncContinuity(store, socket, token)\n\t})\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["RealtimeContext: React.Context<RealtimeReactStore>","RealtimeProvider: React.FC<{\n\tchildren: React.ReactNode\n\tsocket: Socket | null\n}>"],"sources":["../../src/realtime-react/realtime-context.tsx","../../src/realtime-react/use-realtime-service.ts","../../src/realtime-react/use-pull-atom.ts","../../src/realtime-react/use-pull-atom-family-member.ts","../../src/realtime-react/use-pull-mutable-atom.ts","../../src/realtime-react/use-pull-mutable-family-member.ts","../../src/realtime-react/use-pull-selector.ts","../../src/realtime-react/use-pull-selector-family-member.ts","../../src/realtime-react/use-push.ts","../../src/realtime-react/use-realtime-rooms.ts","../../src/realtime-react/use-sync-continuity.ts"],"sourcesContent":["import { useI } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\nimport type { Socket } from \"socket.io-client\"\n\nexport type RealtimeServiceCounter = {\n\tconsumerCount: number\n\tdispose: () => void\n}\n\nexport type RealtimeReactStore = {\n\tsocket: Socket | null\n\tservices: Map<string, RealtimeServiceCounter> | null\n}\n\nexport const RealtimeContext: React.Context<RealtimeReactStore> =\n\tReact.createContext({\n\t\tsocket: null,\n\t\tservices: null,\n\t})\n\nexport const RealtimeProvider: React.FC<{\n\tchildren: React.ReactNode\n\tsocket: Socket | null\n}> = ({ children, socket }) => {\n\tconst services = React.useRef(\n\t\tnew Map<string, RealtimeServiceCounter>(),\n\t).current\n\tconst setMySocketKey = useI(RTC.mySocketKeyAtom)\n\tReact.useEffect(() => {\n\t\tsetMySocketKey(socket?.id ? `socket::${socket.id}` : undefined)\n\t\tsocket?.on(`connect`, () => {\n\t\t\tsetMySocketKey(socket?.id ? `socket::${socket.id}` : undefined)\n\t\t})\n\t\tsocket?.on(`disconnect`, () => {\n\t\t\tsetMySocketKey(undefined)\n\t\t})\n\t}, [socket, setMySocketKey])\n\treturn (\n\t\t<RealtimeContext.Provider value={{ socket, services }}>\n\t\t\t{children}\n\t\t</RealtimeContext.Provider>\n\t)\n}\n","import { useSingleEffect } from \"atom.io/react\"\nimport * as React from \"react\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { RealtimeContext } from \"./realtime-context\"\n\nexport function useRealtimeService(\n\tkey: string,\n\tcreate: (socket: Socket) => () => void,\n): void {\n\tconst { socket, services } = React.useContext(RealtimeContext)\n\tuseSingleEffect(() => {\n\t\tlet service = services?.get(key)\n\t\tif (service) {\n\t\t\t++service.consumerCount\n\t\t} else if (socket) {\n\t\t\tconst dispose = create(socket)\n\t\t\tservice = { consumerCount: 1, dispose }\n\t\t\tservices?.set(key, service)\n\t\t}\n\t\treturn () => {\n\t\t\tif (service) {\n\t\t\t\t--service.consumerCount\n\t\t\t\tif (service.consumerCount === 0) {\n\t\t\t\t\tservice.dispose?.()\n\t\t\t\t\tservices?.delete(key)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [socket, key])\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullAtom<J extends Json.Serializable>(\n\ttoken: AtomIO.RegularAtomToken<J>,\n): AtomIO.ViewOf<J> {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullAtom(store, socket, token),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport { findInStore } from \"atom.io/internal\"\nimport type { Canonical, Json } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullAtomFamilyMember<\n\tJ extends Json.Serializable,\n\tK extends Canonical,\n>(\n\tfamily: AtomIO.RegularAtomFamilyToken<J, K>,\n\tsubKey: NoInfer<K>,\n): AtomIO.ViewOf<J> {\n\tconst store = React.useContext(StoreContext)\n\tconst token = findInStore(store, family, subKey)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullAtomFamilyMember(store, socket, family, subKey),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullMutable<T extends Transceiver<any, any, any>>(\n\ttoken: AtomIO.MutableAtomToken<T>,\n): T {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullMutableAtom(store, socket, token),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Transceiver } from \"atom.io/internal\"\nimport { findInStore } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullMutableAtomFamilyMember<\n\tT extends Transceiver<any, any, any>,\n\tK extends Canonical,\n>(familyToken: AtomIO.MutableAtomFamilyToken<T, K>, key: NoInfer<K>): T {\n\tconst store = React.useContext(StoreContext)\n\tconst token = findInStore(store, familyToken, key)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullMutableAtomFamilyMember(store, socket, familyToken, key),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullSelector<J extends Json.Serializable>(\n\ttoken: AtomIO.SelectorToken<J>,\n): AtomIO.ViewOf<J> {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullSelector(store, socket, token),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport { findInStore } from \"atom.io/internal\"\nimport type { Canonical } from \"atom.io/json\"\nimport { StoreContext, useO } from \"atom.io/react\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePullSelectorFamilyMember<T, K extends Canonical>(\n\tfamilyToken: AtomIO.SelectorFamilyToken<T, K>,\n\tkey: NoInfer<K>,\n): AtomIO.ViewOf<T> {\n\tconst store = React.useContext(StoreContext)\n\tconst token = findInStore(store, familyToken, key)\n\tuseRealtimeService(`pull:${token.key}`, (socket) =>\n\t\tRTC.pullSelectorFamilyMember(store, socket, familyToken, key),\n\t)\n\treturn useO(token)\n}\n","import type * as AtomIO from \"atom.io\"\nimport type { Json } from \"atom.io/json\"\nimport { StoreContext, useI, useO } from \"atom.io/react\"\nimport * as RT from \"atom.io/realtime\"\nimport * as RTC from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function usePush<J extends Json.Serializable>(\n\ttoken: AtomIO.WritableToken<J>,\n): (<New extends J>(next: New | ((old: J) => New)) => void) | null {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`push:${token.key}`, (socket) =>\n\t\tRTC.pushState(store, socket, token),\n\t)\n\tconst mutex = useO(RT.mutexAtoms, token.key)\n\tconst setter = useI(token)\n\n\treturn mutex ? setter : null\n}\n","import type { RoomSocketInterface } from \"atom.io/realtime\"\nimport * as React from \"react\"\nimport type { Socket } from \"socket.io-client\"\n\nimport { RealtimeContext } from \"./realtime-context\"\n\nexport function useRealtimeRooms<RoomNames extends string>(): Socket<\n\t{},\n\tRoomSocketInterface<RoomNames>\n> {\n\tconst { socket } = React.useContext(RealtimeContext)\n\treturn socket as Socket<{}, RoomSocketInterface<RoomNames>>\n}\n","import { StoreContext } from \"atom.io/react\"\nimport type { ContinuityToken } from \"atom.io/realtime\"\nimport { syncContinuity } from \"atom.io/realtime-client\"\nimport * as React from \"react\"\n\nimport { useRealtimeService } from \"./use-realtime-service\"\n\nexport function useSyncContinuity(token: ContinuityToken): void {\n\tconst store = React.useContext(StoreContext)\n\tuseRealtimeService(`tx-sync:${token.key}`, (socket) => {\n\t\treturn syncContinuity(store, socket, token)\n\t})\n}\n"],"mappings":"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"}
|
|
@@ -4,12 +4,12 @@ import { toEntries } from "atom.io/json";
|
|
|
4
4
|
import { UList } from "atom.io/transceivers/u-list";
|
|
5
5
|
import "react";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
|
-
import * as RTR from "atom.io/realtime-react";
|
|
8
7
|
import * as AR from "atom.io/react";
|
|
9
8
|
import * as RTC from "atom.io/realtime-client";
|
|
10
9
|
import { ChildProcess } from "node:child_process";
|
|
11
10
|
import * as http from "node:http";
|
|
12
11
|
import { prettyDOM, render } from "@testing-library/react";
|
|
12
|
+
import * as RTR from "atom.io/realtime-react";
|
|
13
13
|
import * as RTS from "atom.io/realtime-server";
|
|
14
14
|
import * as Happy from "happy-dom";
|
|
15
15
|
import * as SocketIO from "socket.io";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atom.io",
|
|
3
|
-
"version": "0.45.
|
|
3
|
+
"version": "0.45.2",
|
|
4
4
|
"description": "Composable and testable reactive data library.",
|
|
5
5
|
"homepage": "https://atom.io.fyi",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@typescript-eslint/parser": "8.47.0",
|
|
73
73
|
"@typescript-eslint/rule-tester": "8.47.0",
|
|
74
74
|
"@typescript-eslint/utils": "8.47.0",
|
|
75
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
75
|
+
"@typescript/native-preview": "7.0.0-dev.20251201.1",
|
|
76
76
|
"@vitest/coverage-v8": "4.0.14",
|
|
77
77
|
"@vitest/ui": "4.0.14",
|
|
78
78
|
"arktype": "2.1.27",
|
|
@@ -97,8 +97,8 @@
|
|
|
97
97
|
"vite": "7.2.4",
|
|
98
98
|
"vite-tsconfig-paths": "5.1.4",
|
|
99
99
|
"vitest": "4.0.14",
|
|
100
|
-
"
|
|
101
|
-
"
|
|
100
|
+
"break-check": "0.6.24",
|
|
101
|
+
"takua": "0.1.1"
|
|
102
102
|
},
|
|
103
103
|
"main": "./dist/main/index.js",
|
|
104
104
|
"files": [
|
package/src/react/index.ts
CHANGED
package/src/react/use-o.ts
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import type { ReadableFamilyToken, ReadableToken, ViewOf } from "atom.io"
|
|
3
3
|
import { getFromStore, subscribeToState } from "atom.io/internal"
|
|
4
4
|
import type { Canonical } from "atom.io/json"
|
|
5
|
-
import { useSingleEffect } from "atom.io/realtime-react"
|
|
6
5
|
import {
|
|
7
6
|
useCallback,
|
|
8
7
|
useContext,
|
|
@@ -14,6 +13,7 @@ import {
|
|
|
14
13
|
|
|
15
14
|
import { parseStateOverloads } from "./parse-state-overloads"
|
|
16
15
|
import { StoreContext } from "./store-context"
|
|
16
|
+
import { useSingleEffect } from "./use-single-effect"
|
|
17
17
|
|
|
18
18
|
export function useO<T, E = never>(
|
|
19
19
|
token: ReadableToken<T, any, E>,
|
|
@@ -8,10 +8,11 @@ import {
|
|
|
8
8
|
setIntoStore,
|
|
9
9
|
} from "atom.io/internal"
|
|
10
10
|
import type { Socket } from "atom.io/realtime"
|
|
11
|
+
|
|
11
12
|
import {
|
|
12
13
|
confirmedUpdateQueueAtom,
|
|
13
14
|
optimisticUpdateQueueAtom,
|
|
14
|
-
} from "
|
|
15
|
+
} from "../realtime-client-stores"
|
|
15
16
|
|
|
16
17
|
export const useRegisterAndAttemptConfirmedUpdate =
|
|
17
18
|
(
|
|
@@ -9,15 +9,15 @@ import {
|
|
|
9
9
|
} from "atom.io/internal"
|
|
10
10
|
import type { Json } from "atom.io/json"
|
|
11
11
|
import type { ContinuityToken } from "atom.io/realtime"
|
|
12
|
-
import {
|
|
13
|
-
confirmedUpdateQueueAtom,
|
|
14
|
-
optimisticUpdateQueueAtom,
|
|
15
|
-
} from "atom.io/realtime-client"
|
|
16
12
|
import type { Socket } from "socket.io-client"
|
|
17
13
|
|
|
18
14
|
import { useRegisterAndAttemptConfirmedUpdate } from "./continuity/register-and-attempt-confirmed-update"
|
|
19
15
|
import { useConcealState } from "./continuity/use-conceal-state"
|
|
20
16
|
import { useRevealState } from "./continuity/use-reveal-state"
|
|
17
|
+
import {
|
|
18
|
+
confirmedUpdateQueueAtom,
|
|
19
|
+
optimisticUpdateQueueAtom,
|
|
20
|
+
} from "./realtime-client-stores"
|
|
21
21
|
|
|
22
22
|
export function syncContinuity(
|
|
23
23
|
store: RootStore,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { useSingleEffect } from "atom.io/react"
|
|
1
2
|
import * as React from "react"
|
|
2
3
|
import type { Socket } from "socket.io-client"
|
|
3
4
|
|
|
4
5
|
import { RealtimeContext } from "./realtime-context"
|
|
5
|
-
import { useSingleEffect } from "./use-single-effect"
|
|
6
6
|
|
|
7
7
|
export function useRealtimeService(
|
|
8
8
|
key: string,
|
|
File without changes
|