doxum 0.1.12 → 0.1.13
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/README.md +44 -39
- package/dist/advanced.cjs +116 -0
- package/dist/advanced.cjs.map +1 -0
- package/dist/advanced.d.cts +42 -0
- package/dist/advanced.d.ts +42 -0
- package/dist/advanced.js +115 -0
- package/dist/advanced.js.map +1 -0
- package/dist/{contract-CeAnEPBA.d.ts → contract-BT53Gg94.d.ts} +5 -4
- package/dist/{contract-DtGVSXSK.d.cts → contract-XmKnroJq.d.cts} +5 -4
- package/dist/definition-177L4Amk.cjs +898 -0
- package/dist/definition-177L4Amk.cjs.map +1 -0
- package/dist/definition-BlMeHwdz.d.ts +98 -0
- package/dist/definition-DXrKMVs7.js +785 -0
- package/dist/definition-DXrKMVs7.js.map +1 -0
- package/dist/definition-kxnWUvX9.d.cts +98 -0
- package/dist/{driver-xOIkwrB8.cjs → driver-BCyfqxsl.cjs} +1 -1
- package/dist/{driver-xOIkwrB8.cjs.map → driver-BCyfqxsl.cjs.map} +1 -1
- package/dist/{driver-BlR81Dqg.js → driver-CSnhMjbP.js} +1 -1
- package/dist/{driver-BlR81Dqg.js.map → driver-CSnhMjbP.js.map} +1 -1
- package/dist/index.cjs +31 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/{integration-CWjttg7H.js → integration-Bco8ZB16.js} +7 -3
- package/dist/integration-Bco8ZB16.js.map +1 -0
- package/dist/integration-CEUn96tx.cjs +52 -0
- package/dist/integration-CEUn96tx.cjs.map +1 -0
- package/dist/integration.cjs +7 -3
- package/dist/integration.d.cts +7 -3
- package/dist/integration.d.ts +7 -3
- package/dist/integration.js +3 -3
- package/dist/local-sync.cjs +1 -1
- package/dist/local-sync.d.cts +1 -1
- package/dist/local-sync.d.ts +1 -1
- package/dist/local-sync.js +1 -1
- package/dist/react.cjs +63 -36
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +8 -7
- package/dist/react.d.ts +8 -7
- package/dist/react.js +63 -35
- package/dist/react.js.map +1 -1
- package/dist/store-CDeqZEE3.d.cts +28 -0
- package/dist/{store-7XBEcR8s.js → store-CtgvCVFg.js} +585 -922
- package/dist/store-CtgvCVFg.js.map +1 -0
- package/dist/{store-DBv58dns.cjs → store-DcDpDgjk.cjs} +595 -992
- package/dist/store-DcDpDgjk.cjs.map +1 -0
- package/dist/store-P5dJ7TVe.d.ts +28 -0
- package/package.json +6 -1
- package/skills/doxum-runtime/SKILL.md +5 -7
- package/skills/doxum-runtime/references/guide.en.md +12 -16
- package/skills/doxum-runtime/references/guide.zh-CN.md +9 -14
- package/skills/doxum-runtime/references/patterns.en.md +12 -20
- package/skills/doxum-runtime/references/patterns.zh-CN.md +12 -18
- package/skills/doxum-runtime/references/projections.en.md +56 -199
- package/skills/doxum-runtime/references/projections.zh-CN.md +50 -180
- package/dist/integration-BShL68Nc.cjs +0 -30
- package/dist/integration-BShL68Nc.cjs.map +0 -1
- package/dist/integration-CWjttg7H.js.map +0 -1
- package/dist/store-2i8pYXqa.d.ts +0 -263
- package/dist/store-7XBEcR8s.js.map +0 -1
- package/dist/store-DBv58dns.cjs.map +0 -1
- package/dist/store-Ks80xWS_.d.cts +0 -263
package/dist/react.cjs
CHANGED
|
@@ -1,48 +1,76 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_store = require("./store-
|
|
3
|
-
const require_integration = require("./integration-
|
|
2
|
+
const require_store = require("./store-DcDpDgjk.cjs");
|
|
3
|
+
const require_integration = require("./integration-CEUn96tx.cjs");
|
|
4
4
|
let react = require("react");
|
|
5
5
|
//#region react/src/hooks.ts
|
|
6
6
|
const ProjectionContext = (0, react.createContext)(void 0);
|
|
7
7
|
const ProjectionProvider = ProjectionContext.Provider;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
function useProjectionItem(projection, key, store) {
|
|
8
|
+
const sameProjectionSelection = (left, right) => {
|
|
9
|
+
if (left.all !== right.all || left.structure !== right.structure || left.keys.size !== right.keys.size) return false;
|
|
10
|
+
for (const key of left.keys) if (!right.keys.has(key)) return false;
|
|
11
|
+
return true;
|
|
12
|
+
};
|
|
13
|
+
function useProjection(projection, selectorOrRuntime, equalityOrRuntime, suppliedRuntime) {
|
|
16
14
|
const context = (0, react.useContext)(ProjectionContext);
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
15
|
+
const selector = typeof selectorOrRuntime === "function" ? selectorOrRuntime : void 0;
|
|
16
|
+
const equality = typeof equalityOrRuntime === "function" ? equalityOrRuntime : Object.is;
|
|
17
|
+
const owner = (selector ? suppliedRuntime : void 0) ?? (selector ? equalityOrRuntime && typeof equalityOrRuntime !== "function" ? equalityOrRuntime : void 0 : void 0) ?? (selector ? context : typeof selectorOrRuntime === "object" ? selectorOrRuntime : context);
|
|
18
|
+
if (!owner) throw new Error("ProjectionRuntime is required.");
|
|
19
|
+
if (!selector) {
|
|
20
|
+
const read = (0, react.useCallback)(() => owner.get(projection), [owner, projection]);
|
|
21
|
+
return (0, react.useSyncExternalStore)((0, react.useCallback)((listener) => owner.subscribe(projection, listener), [owner, projection]), read, read);
|
|
22
|
+
}
|
|
23
|
+
const cache = (0, react.useRef)(void 0);
|
|
24
|
+
const read = (0, react.useCallback)(() => {
|
|
25
|
+
const selected = require_store.trackProjection(owner, projection, selector);
|
|
26
|
+
const previous = cache.current;
|
|
27
|
+
const value = previous && equality(previous.value, selected.value) ? previous.value : selected.value;
|
|
28
|
+
cache.current = {
|
|
29
|
+
value,
|
|
30
|
+
selection: selected.selection
|
|
31
|
+
};
|
|
32
|
+
return value;
|
|
33
|
+
}, [
|
|
34
|
+
equality,
|
|
21
35
|
owner,
|
|
22
|
-
projection
|
|
36
|
+
projection,
|
|
37
|
+
selector
|
|
23
38
|
]);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (snapshot && revision === previousRevision) return snapshot;
|
|
31
|
-
previousRevision = revision;
|
|
32
|
-
snapshot = {
|
|
33
|
-
value,
|
|
34
|
-
revision
|
|
35
|
-
};
|
|
36
|
-
return snapshot;
|
|
39
|
+
return (0, react.useSyncExternalStore)((0, react.useCallback)((listener) => {
|
|
40
|
+
read();
|
|
41
|
+
let selection = cache.current?.selection ?? {
|
|
42
|
+
keys: /* @__PURE__ */ new Set(),
|
|
43
|
+
all: true,
|
|
44
|
+
structure: false
|
|
37
45
|
};
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
let unsubscribe = require_store.subscribeProjection(owner, projection, selection, onInvalidate);
|
|
47
|
+
const reinstall = (next) => {
|
|
48
|
+
if (sameProjectionSelection(selection, next)) return;
|
|
49
|
+
unsubscribe();
|
|
50
|
+
selection = next;
|
|
51
|
+
unsubscribe = require_store.subscribeProjection(owner, projection, selection, onInvalidate);
|
|
52
|
+
};
|
|
53
|
+
function onInvalidate() {
|
|
54
|
+
const previous = cache.current?.value;
|
|
55
|
+
const next = read();
|
|
56
|
+
const nextSelection = cache.current?.selection;
|
|
57
|
+
if (nextSelection) reinstall(nextSelection);
|
|
58
|
+
if (!Object.is(previous, next)) listener();
|
|
59
|
+
}
|
|
60
|
+
return () => unsubscribe();
|
|
61
|
+
}, [
|
|
62
|
+
owner,
|
|
63
|
+
projection,
|
|
64
|
+
read
|
|
65
|
+
]), read, read);
|
|
40
66
|
}
|
|
41
|
-
function
|
|
67
|
+
function useInput(input, runtime) {
|
|
42
68
|
const context = (0, react.useContext)(ProjectionContext);
|
|
43
|
-
const owner =
|
|
44
|
-
if (!owner) throw new Error("
|
|
45
|
-
|
|
69
|
+
const owner = runtime ?? context;
|
|
70
|
+
if (!owner) throw new Error("ProjectionRuntime is required.");
|
|
71
|
+
const value = useProjection(input, owner);
|
|
72
|
+
const set = (0, react.useCallback)((next) => owner.set(input, next), [input, owner]);
|
|
73
|
+
return (0, react.useMemo)(() => [value, set], [set, value]);
|
|
46
74
|
}
|
|
47
75
|
const objectIs = (previous, next) => Object.is(previous, next);
|
|
48
76
|
const sameTargets = (left, right) => {
|
|
@@ -145,9 +173,8 @@ exports.ProjectionContext = ProjectionContext;
|
|
|
145
173
|
exports.ProjectionProvider = ProjectionProvider;
|
|
146
174
|
exports.useDocumentSelector = useDocumentSelector;
|
|
147
175
|
exports.useHistory = useHistory;
|
|
176
|
+
exports.useInput = useInput;
|
|
148
177
|
exports.useProjection = useProjection;
|
|
149
|
-
exports.useProjectionItem = useProjectionItem;
|
|
150
178
|
exports.useReadable = useReadable;
|
|
151
|
-
exports.useSetProjection = useSetProjection;
|
|
152
179
|
|
|
153
180
|
//# sourceMappingURL=react.cjs.map
|
package/dist/react.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.cjs","names":["sameTarget","track","subscribeDependencies"],"sources":["../react/src/hooks.ts"],"sourcesContent":["import type {\n DocumentReadable,\n ObjectNode,\n DocumentSelector,\n HistoryState,\n LocalHistory,\n OperationResult,\n Readable,\n ProjectionStore,\n CollectionProjection,\n ValueProjection,\n InputProjection,\n} from 'doxum';\nimport { track, subscribeDependencies, sameTarget, type ImpactTarget } from 'doxum/integration';\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from 'react';\n\nexport const ProjectionContext = createContext<ProjectionStore | undefined>(undefined);\nexport const ProjectionProvider = ProjectionContext.Provider;\n\nexport function useProjection<T>(projection: ValueProjection<T>, store?: ProjectionStore): T {\n const context = useContext(ProjectionContext);\n const owner = store ?? context;\n if (!owner) throw new Error('ProjectionStore is required.');\n const read = useCallback(() => owner.get(projection), [owner, projection]);\n const subscribe = useCallback(\n (listener: () => void) => owner.subscribe(projection, listener),\n [owner, projection]\n );\n return useSyncExternalStore(subscribe, read, read);\n}\n\ntype ProjectionItemSnapshot<T> = {\n readonly value: T | undefined;\n readonly revision: number;\n};\n\nexport function useProjectionItem<K extends string, V>(\n projection: CollectionProjection<K, V>,\n key: K,\n store?: ProjectionStore\n): V | undefined {\n const context = useContext(ProjectionContext);\n const owner = store ?? context;\n if (!owner) throw new Error('ProjectionStore is required.');\n const item = useMemo(() => owner.item(projection, key), [key, owner, projection]);\n const read = useMemo(() => {\n let previousRevision = -1;\n let snapshot: ProjectionItemSnapshot<V> | undefined;\n return (): ProjectionItemSnapshot<V> => {\n const value = item.current();\n const revision = item.revision();\n if (snapshot && revision === previousRevision) return snapshot;\n previousRevision = revision;\n snapshot = { value, revision };\n return snapshot;\n };\n }, [item]);\n const subscribe = useCallback((listener: () => void) => item.subscribe(listener), [item]);\n return useSyncExternalStore(subscribe, read, read).value;\n}\n\nexport function useSetProjection<T>(\n projection: InputProjection<T>,\n store?: ProjectionStore\n): (value: T) => void {\n const context = useContext(ProjectionContext);\n const owner = store ?? context;\n if (!owner) throw new Error('ProjectionStore is required.');\n return useCallback((value: T) => owner.set(projection, value), [owner, projection]);\n}\n\nexport type DocumentSelectorOptions<TResult> = {\n readonly isEqual?: (previous: TResult, next: TResult) => boolean;\n readonly server?: () => TResult;\n};\n\ntype SelectorCache<TSchema extends ObjectNode, TResult> = {\n readonly runtime: DocumentReadable<TSchema>;\n readonly value: TResult;\n readonly targets: readonly ImpactTarget<unknown>[];\n};\n\nconst objectIs = <T>(previous: T, next: T): boolean => Object.is(previous, next);\nconst sameTargets = (\n left: readonly ImpactTarget<unknown>[],\n right: readonly ImpactTarget<unknown>[]\n): boolean => {\n if (left.length !== right.length) return false;\n for (let index = 0; index < left.length; index += 1)\n if (!sameTarget(left[index], right[index])) return false;\n return true;\n};\n\nexport function useDocumentSelector<TSchema extends ObjectNode, TResult>(\n runtime: DocumentReadable<TSchema>,\n selector: DocumentSelector<TSchema, TResult>,\n options?: DocumentSelectorOptions<TResult>\n): TResult {\n const equality = options?.isEqual ?? objectIs;\n const cache = useRef<SelectorCache<TSchema, TResult> | undefined>(undefined);\n const serverCache = useRef<\n | {\n readonly runtime: DocumentReadable<TSchema>;\n readonly selector: DocumentSelector<TSchema, TResult>;\n readonly source: (() => TResult) | undefined;\n readonly value: TResult;\n }\n | undefined\n >(undefined);\n\n const read = useMemo(() => {\n // Each selector closure owns its revision cache, including inline selectors\n // that allocate arrays or objects. Equality only compares distinct snapshots.\n let snapshot: { readonly revision: number; readonly value: TResult } | undefined;\n return (): TResult => {\n const revision = runtime.revision();\n if (snapshot?.revision === revision) return snapshot.value;\n const selection = track(runtime, selector);\n const previous = cache.current;\n const value =\n previous && previous.runtime === runtime && equality(previous.value, selection.value)\n ? previous.value\n : selection.value;\n cache.current = { runtime, value, targets: selection.targets };\n snapshot = { revision, value };\n return value;\n };\n }, [equality, runtime, selector]);\n\n const subscribe = useCallback(\n (listener: () => void) => {\n read();\n let targets = cache.current?.targets ?? [];\n let unsubscribe: () => void = () => undefined;\n const install = () => {\n if (targets.length === 0) return () => undefined;\n return subscribeDependencies(runtime, targets, onCommit);\n };\n const onCommit = () => {\n const previous = cache.current;\n const next = read();\n const nextTargets = cache.current?.targets ?? [];\n if (!sameTargets(targets, nextTargets)) {\n unsubscribe();\n targets = nextTargets;\n unsubscribe = install();\n }\n if (previous && !Object.is(previous.value, next)) listener();\n };\n unsubscribe = install();\n return () => unsubscribe();\n },\n [read, runtime]\n );\n\n const server = options?.server;\n const readServer = useCallback((): TResult => {\n const previous = serverCache.current;\n if (\n previous &&\n previous.source === server &&\n previous.runtime === runtime &&\n previous.selector === selector\n )\n return previous.value;\n const value = server ? server() : read();\n serverCache.current = { runtime, selector, source: server, value };\n return value;\n }, [read, server, runtime, selector]);\n\n return useSyncExternalStore(subscribe, read, readServer);\n}\n\nexport function useReadable<T>(readable: Readable<T>): T {\n const subscribe = useCallback((listener: () => void) => readable.subscribe(listener), [readable]);\n const read = useCallback(() => readable.current(), [readable]);\n return useSyncExternalStore(subscribe, read, read);\n}\n\nexport function useHistory<TCommit>(history: LocalHistory<TCommit>): HistoryState & {\n undo(): OperationResult<TCommit>;\n redo(): OperationResult<TCommit>;\n} {\n const subscribe = useCallback((listener: () => void) => history.subscribe(listener), [history]);\n const read = useCallback(() => history.current(), [history]);\n const state = useSyncExternalStore(subscribe, read, read);\n const undo = useCallback(() => history.undo(), [history]);\n const redo = useCallback(() => history.redo(), [history]);\n\n return useMemo(() => ({ ...state, undo, redo }), [redo, state, undo]);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react.cjs","names":["trackProjection","subscribeProjection","sameTarget","track","subscribeDependencies"],"sources":["../react/src/hooks.ts"],"sourcesContent":["import type {\n DocumentReadable,\n ObjectNode,\n DocumentSelector,\n HistoryState,\n LocalHistory,\n OperationResult,\n Readable,\n ProjectionRuntime,\n Projection,\n Input,\n} from 'doxum';\nimport {\n track,\n subscribeDependencies,\n sameTarget,\n type ImpactTarget,\n trackProjection,\n subscribeProjection,\n type ProjectionSelection,\n} from 'doxum/integration';\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from 'react';\n\nexport const ProjectionContext = createContext<ProjectionRuntime | undefined>(undefined);\nexport const ProjectionProvider = ProjectionContext.Provider;\n\nconst sameProjectionSelection = (\n left: ProjectionSelection,\n right: ProjectionSelection\n): boolean => {\n if (\n left.all !== right.all ||\n left.structure !== right.structure ||\n left.keys.size !== right.keys.size\n )\n return false;\n for (const key of left.keys) if (!right.keys.has(key)) return false;\n return true;\n};\n\nexport function useProjection<T>(projection: Projection<T>, runtime?: ProjectionRuntime): T;\nexport function useProjection<T, R>(\n projection: Projection<T>,\n selector: (value: T) => R,\n runtime?: ProjectionRuntime\n): R;\nexport function useProjection<T, R>(\n projection: Projection<T>,\n selector: (value: T) => R,\n equality?: (previous: R, next: R) => boolean,\n runtime?: ProjectionRuntime\n): R;\nexport function useProjection<T, R>(\n projection: Projection<T>,\n selectorOrRuntime?: ((value: T) => R) | ProjectionRuntime,\n equalityOrRuntime?: ((previous: R, next: R) => boolean) | ProjectionRuntime,\n suppliedRuntime?: ProjectionRuntime\n): T | R {\n const context = useContext(ProjectionContext);\n const selector = typeof selectorOrRuntime === 'function' ? selectorOrRuntime : undefined;\n const equality = typeof equalityOrRuntime === 'function' ? equalityOrRuntime : Object.is;\n const owner =\n (selector ? suppliedRuntime : undefined) ??\n (selector\n ? equalityOrRuntime && typeof equalityOrRuntime !== 'function'\n ? equalityOrRuntime\n : undefined\n : undefined) ??\n (selector ? context : typeof selectorOrRuntime === 'object' ? selectorOrRuntime : context);\n if (!owner) throw new Error('ProjectionRuntime is required.');\n if (!selector) {\n const read = useCallback(() => owner.get(projection), [owner, projection]);\n const subscribe = useCallback(\n (listener: () => void) => owner.subscribe(projection, listener),\n [owner, projection]\n );\n return useSyncExternalStore(subscribe, read, read) as T;\n }\n const cache = useRef<{ value: R; selection: ProjectionSelection } | undefined>(undefined);\n const read = useCallback(() => {\n const selected = trackProjection(owner, projection, selector);\n const previous = cache.current;\n const value =\n previous && equality(previous.value, selected.value) ? previous.value : selected.value;\n cache.current = { value, selection: selected.selection };\n return value;\n }, [equality, owner, projection, selector]);\n const subscribe = useCallback(\n (listener: () => void) => {\n read();\n let selection = cache.current?.selection ?? {\n keys: new Set<string>(),\n all: true,\n structure: false,\n };\n let unsubscribe = subscribeProjection(owner, projection, selection, onInvalidate);\n const reinstall = (next: ProjectionSelection) => {\n if (sameProjectionSelection(selection, next)) return;\n unsubscribe();\n selection = next;\n unsubscribe = subscribeProjection(owner, projection, selection, onInvalidate);\n };\n function onInvalidate() {\n const previous = cache.current?.value;\n const next = read();\n const nextSelection = cache.current?.selection;\n if (nextSelection) reinstall(nextSelection);\n if (!Object.is(previous, next)) listener();\n }\n return () => unsubscribe();\n },\n [owner, projection, read]\n );\n return useSyncExternalStore(subscribe, read, read);\n}\n\nexport function useInput<T>(\n input: Input<T>,\n runtime?: ProjectionRuntime\n): readonly [T, (value: T) => void] {\n const context = useContext(ProjectionContext);\n const owner = runtime ?? context;\n if (!owner) throw new Error('ProjectionRuntime is required.');\n const value = useProjection(input, owner);\n const set = useCallback((next: T) => owner.set(input, next), [input, owner]);\n return useMemo(() => [value, set] as const, [set, value]);\n}\n\nexport type DocumentSelectorOptions<TResult> = {\n readonly isEqual?: (previous: TResult, next: TResult) => boolean;\n readonly server?: () => TResult;\n};\n\ntype SelectorCache<TSchema extends ObjectNode, TResult> = {\n readonly runtime: DocumentReadable<TSchema>;\n readonly value: TResult;\n readonly targets: readonly ImpactTarget<unknown>[];\n};\n\nconst objectIs = <T>(previous: T, next: T): boolean => Object.is(previous, next);\nconst sameTargets = (\n left: readonly ImpactTarget<unknown>[],\n right: readonly ImpactTarget<unknown>[]\n): boolean => {\n if (left.length !== right.length) return false;\n for (let index = 0; index < left.length; index += 1)\n if (!sameTarget(left[index], right[index])) return false;\n return true;\n};\n\nexport function useDocumentSelector<TSchema extends ObjectNode, TResult>(\n runtime: DocumentReadable<TSchema>,\n selector: DocumentSelector<TSchema, TResult>,\n options?: DocumentSelectorOptions<TResult>\n): TResult {\n const equality = options?.isEqual ?? objectIs;\n const cache = useRef<SelectorCache<TSchema, TResult> | undefined>(undefined);\n const serverCache = useRef<\n | {\n readonly runtime: DocumentReadable<TSchema>;\n readonly selector: DocumentSelector<TSchema, TResult>;\n readonly source: (() => TResult) | undefined;\n readonly value: TResult;\n }\n | undefined\n >(undefined);\n\n const read = useMemo(() => {\n // Each selector closure owns its revision cache, including inline selectors\n // that allocate arrays or objects. Equality only compares distinct snapshots.\n let snapshot: { readonly revision: number; readonly value: TResult } | undefined;\n return (): TResult => {\n const revision = runtime.revision();\n if (snapshot?.revision === revision) return snapshot.value;\n const selection = track(runtime, selector);\n const previous = cache.current;\n const value =\n previous && previous.runtime === runtime && equality(previous.value, selection.value)\n ? previous.value\n : selection.value;\n cache.current = { runtime, value, targets: selection.targets };\n snapshot = { revision, value };\n return value;\n };\n }, [equality, runtime, selector]);\n\n const subscribe = useCallback(\n (listener: () => void) => {\n read();\n let targets = cache.current?.targets ?? [];\n let unsubscribe: () => void = () => undefined;\n const install = () => {\n if (targets.length === 0) return () => undefined;\n return subscribeDependencies(runtime, targets, onCommit);\n };\n const onCommit = () => {\n const previous = cache.current;\n const next = read();\n const nextTargets = cache.current?.targets ?? [];\n if (!sameTargets(targets, nextTargets)) {\n unsubscribe();\n targets = nextTargets;\n unsubscribe = install();\n }\n if (previous && !Object.is(previous.value, next)) listener();\n };\n unsubscribe = install();\n return () => unsubscribe();\n },\n [read, runtime]\n );\n\n const server = options?.server;\n const readServer = useCallback((): TResult => {\n const previous = serverCache.current;\n if (\n previous &&\n previous.source === server &&\n previous.runtime === runtime &&\n previous.selector === selector\n )\n return previous.value;\n const value = server ? server() : read();\n serverCache.current = { runtime, selector, source: server, value };\n return value;\n }, [read, server, runtime, selector]);\n\n return useSyncExternalStore(subscribe, read, readServer);\n}\n\nexport function useReadable<T>(readable: Readable<T>): T {\n const subscribe = useCallback((listener: () => void) => readable.subscribe(listener), [readable]);\n const read = useCallback(() => readable.current(), [readable]);\n return useSyncExternalStore(subscribe, read, read);\n}\n\nexport function useHistory<TCommit>(history: LocalHistory<TCommit>): HistoryState & {\n undo(): OperationResult<TCommit>;\n redo(): OperationResult<TCommit>;\n} {\n const subscribe = useCallback((listener: () => void) => history.subscribe(listener), [history]);\n const read = useCallback(() => history.current(), [history]);\n const state = useSyncExternalStore(subscribe, read, read);\n const undo = useCallback(() => history.undo(), [history]);\n const redo = useCallback(() => history.redo(), [history]);\n\n return useMemo(() => ({ ...state, undo, redo }), [redo, state, undo]);\n}\n"],"mappings":"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"}
|
package/dist/react.d.cts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import * as _$react from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { DocumentReadable, DocumentSelector, HistoryState, Input, LocalHistory, ObjectNode, OperationResult, Projection, ProjectionRuntime, Readable } from "doxum";
|
|
3
3
|
|
|
4
4
|
//#region react/src/hooks.d.ts
|
|
5
|
-
declare const ProjectionContext: _$react.Context<
|
|
6
|
-
declare const ProjectionProvider: _$react.Provider<
|
|
7
|
-
declare function useProjection<T>(projection:
|
|
8
|
-
declare function
|
|
9
|
-
declare function
|
|
5
|
+
declare const ProjectionContext: _$react.Context<ProjectionRuntime | undefined>;
|
|
6
|
+
declare const ProjectionProvider: _$react.Provider<ProjectionRuntime | undefined>;
|
|
7
|
+
declare function useProjection<T>(projection: Projection<T>, runtime?: ProjectionRuntime): T;
|
|
8
|
+
declare function useProjection<T, R>(projection: Projection<T>, selector: (value: T) => R, runtime?: ProjectionRuntime): R;
|
|
9
|
+
declare function useProjection<T, R>(projection: Projection<T>, selector: (value: T) => R, equality?: (previous: R, next: R) => boolean, runtime?: ProjectionRuntime): R;
|
|
10
|
+
declare function useInput<T>(input: Input<T>, runtime?: ProjectionRuntime): readonly [T, (value: T) => void];
|
|
10
11
|
type DocumentSelectorOptions<TResult> = {
|
|
11
12
|
readonly isEqual?: (previous: TResult, next: TResult) => boolean;
|
|
12
13
|
readonly server?: () => TResult;
|
|
@@ -18,5 +19,5 @@ declare function useHistory<TCommit>(history: LocalHistory<TCommit>): HistorySta
|
|
|
18
19
|
redo(): OperationResult<TCommit>;
|
|
19
20
|
};
|
|
20
21
|
//#endregion
|
|
21
|
-
export { type DocumentSelectorOptions, ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory,
|
|
22
|
+
export { type DocumentSelectorOptions, ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
|
|
22
23
|
//# sourceMappingURL=react.d.cts.map
|
package/dist/react.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import * as _$react from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { DocumentReadable, DocumentSelector, HistoryState, Input, LocalHistory, ObjectNode, OperationResult, Projection, ProjectionRuntime, Readable } from "doxum";
|
|
3
3
|
|
|
4
4
|
//#region react/src/hooks.d.ts
|
|
5
|
-
declare const ProjectionContext: _$react.Context<
|
|
6
|
-
declare const ProjectionProvider: _$react.Provider<
|
|
7
|
-
declare function useProjection<T>(projection:
|
|
8
|
-
declare function
|
|
9
|
-
declare function
|
|
5
|
+
declare const ProjectionContext: _$react.Context<ProjectionRuntime | undefined>;
|
|
6
|
+
declare const ProjectionProvider: _$react.Provider<ProjectionRuntime | undefined>;
|
|
7
|
+
declare function useProjection<T>(projection: Projection<T>, runtime?: ProjectionRuntime): T;
|
|
8
|
+
declare function useProjection<T, R>(projection: Projection<T>, selector: (value: T) => R, runtime?: ProjectionRuntime): R;
|
|
9
|
+
declare function useProjection<T, R>(projection: Projection<T>, selector: (value: T) => R, equality?: (previous: R, next: R) => boolean, runtime?: ProjectionRuntime): R;
|
|
10
|
+
declare function useInput<T>(input: Input<T>, runtime?: ProjectionRuntime): readonly [T, (value: T) => void];
|
|
10
11
|
type DocumentSelectorOptions<TResult> = {
|
|
11
12
|
readonly isEqual?: (previous: TResult, next: TResult) => boolean;
|
|
12
13
|
readonly server?: () => TResult;
|
|
@@ -18,5 +19,5 @@ declare function useHistory<TCommit>(history: LocalHistory<TCommit>): HistorySta
|
|
|
18
19
|
redo(): OperationResult<TCommit>;
|
|
19
20
|
};
|
|
20
21
|
//#endregion
|
|
21
|
-
export { type DocumentSelectorOptions, ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory,
|
|
22
|
+
export { type DocumentSelectorOptions, ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
|
|
22
23
|
//# sourceMappingURL=react.d.ts.map
|
package/dist/react.js
CHANGED
|
@@ -1,47 +1,75 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { d as subscribeDependencies, n as subscribeProjection, r as trackProjection, x as same } from "./store-CtgvCVFg.js";
|
|
2
|
+
import { i as track } from "./integration-Bco8ZB16.js";
|
|
3
3
|
import { createContext, useCallback, useContext, useMemo, useRef, useSyncExternalStore } from "react";
|
|
4
4
|
//#region react/src/hooks.ts
|
|
5
5
|
const ProjectionContext = createContext(void 0);
|
|
6
6
|
const ProjectionProvider = ProjectionContext.Provider;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
function useProjectionItem(projection, key, store) {
|
|
7
|
+
const sameProjectionSelection = (left, right) => {
|
|
8
|
+
if (left.all !== right.all || left.structure !== right.structure || left.keys.size !== right.keys.size) return false;
|
|
9
|
+
for (const key of left.keys) if (!right.keys.has(key)) return false;
|
|
10
|
+
return true;
|
|
11
|
+
};
|
|
12
|
+
function useProjection(projection, selectorOrRuntime, equalityOrRuntime, suppliedRuntime) {
|
|
15
13
|
const context = useContext(ProjectionContext);
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
14
|
+
const selector = typeof selectorOrRuntime === "function" ? selectorOrRuntime : void 0;
|
|
15
|
+
const equality = typeof equalityOrRuntime === "function" ? equalityOrRuntime : Object.is;
|
|
16
|
+
const owner = (selector ? suppliedRuntime : void 0) ?? (selector ? equalityOrRuntime && typeof equalityOrRuntime !== "function" ? equalityOrRuntime : void 0 : void 0) ?? (selector ? context : typeof selectorOrRuntime === "object" ? selectorOrRuntime : context);
|
|
17
|
+
if (!owner) throw new Error("ProjectionRuntime is required.");
|
|
18
|
+
if (!selector) {
|
|
19
|
+
const read = useCallback(() => owner.get(projection), [owner, projection]);
|
|
20
|
+
return useSyncExternalStore(useCallback((listener) => owner.subscribe(projection, listener), [owner, projection]), read, read);
|
|
21
|
+
}
|
|
22
|
+
const cache = useRef(void 0);
|
|
23
|
+
const read = useCallback(() => {
|
|
24
|
+
const selected = trackProjection(owner, projection, selector);
|
|
25
|
+
const previous = cache.current;
|
|
26
|
+
const value = previous && equality(previous.value, selected.value) ? previous.value : selected.value;
|
|
27
|
+
cache.current = {
|
|
28
|
+
value,
|
|
29
|
+
selection: selected.selection
|
|
30
|
+
};
|
|
31
|
+
return value;
|
|
32
|
+
}, [
|
|
33
|
+
equality,
|
|
20
34
|
owner,
|
|
21
|
-
projection
|
|
35
|
+
projection,
|
|
36
|
+
selector
|
|
22
37
|
]);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
let
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (snapshot && revision === previousRevision) return snapshot;
|
|
30
|
-
previousRevision = revision;
|
|
31
|
-
snapshot = {
|
|
32
|
-
value,
|
|
33
|
-
revision
|
|
34
|
-
};
|
|
35
|
-
return snapshot;
|
|
38
|
+
return useSyncExternalStore(useCallback((listener) => {
|
|
39
|
+
read();
|
|
40
|
+
let selection = cache.current?.selection ?? {
|
|
41
|
+
keys: /* @__PURE__ */ new Set(),
|
|
42
|
+
all: true,
|
|
43
|
+
structure: false
|
|
36
44
|
};
|
|
37
|
-
|
|
38
|
-
|
|
45
|
+
let unsubscribe = subscribeProjection(owner, projection, selection, onInvalidate);
|
|
46
|
+
const reinstall = (next) => {
|
|
47
|
+
if (sameProjectionSelection(selection, next)) return;
|
|
48
|
+
unsubscribe();
|
|
49
|
+
selection = next;
|
|
50
|
+
unsubscribe = subscribeProjection(owner, projection, selection, onInvalidate);
|
|
51
|
+
};
|
|
52
|
+
function onInvalidate() {
|
|
53
|
+
const previous = cache.current?.value;
|
|
54
|
+
const next = read();
|
|
55
|
+
const nextSelection = cache.current?.selection;
|
|
56
|
+
if (nextSelection) reinstall(nextSelection);
|
|
57
|
+
if (!Object.is(previous, next)) listener();
|
|
58
|
+
}
|
|
59
|
+
return () => unsubscribe();
|
|
60
|
+
}, [
|
|
61
|
+
owner,
|
|
62
|
+
projection,
|
|
63
|
+
read
|
|
64
|
+
]), read, read);
|
|
39
65
|
}
|
|
40
|
-
function
|
|
66
|
+
function useInput(input, runtime) {
|
|
41
67
|
const context = useContext(ProjectionContext);
|
|
42
|
-
const owner =
|
|
43
|
-
if (!owner) throw new Error("
|
|
44
|
-
|
|
68
|
+
const owner = runtime ?? context;
|
|
69
|
+
if (!owner) throw new Error("ProjectionRuntime is required.");
|
|
70
|
+
const value = useProjection(input, owner);
|
|
71
|
+
const set = useCallback((next) => owner.set(input, next), [input, owner]);
|
|
72
|
+
return useMemo(() => [value, set], [set, value]);
|
|
45
73
|
}
|
|
46
74
|
const objectIs = (previous, next) => Object.is(previous, next);
|
|
47
75
|
const sameTargets = (left, right) => {
|
|
@@ -140,6 +168,6 @@ function useHistory(history) {
|
|
|
140
168
|
]);
|
|
141
169
|
}
|
|
142
170
|
//#endregion
|
|
143
|
-
export { ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory,
|
|
171
|
+
export { ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
|
|
144
172
|
|
|
145
173
|
//# sourceMappingURL=react.js.map
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","names":["sameTarget"],"sources":["../react/src/hooks.ts"],"sourcesContent":["import type {\n DocumentReadable,\n ObjectNode,\n DocumentSelector,\n HistoryState,\n LocalHistory,\n OperationResult,\n Readable,\n ProjectionStore,\n CollectionProjection,\n ValueProjection,\n InputProjection,\n} from 'doxum';\nimport { track, subscribeDependencies, sameTarget, type ImpactTarget } from 'doxum/integration';\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from 'react';\n\nexport const ProjectionContext = createContext<ProjectionStore | undefined>(undefined);\nexport const ProjectionProvider = ProjectionContext.Provider;\n\nexport function useProjection<T>(projection: ValueProjection<T>, store?: ProjectionStore): T {\n const context = useContext(ProjectionContext);\n const owner = store ?? context;\n if (!owner) throw new Error('ProjectionStore is required.');\n const read = useCallback(() => owner.get(projection), [owner, projection]);\n const subscribe = useCallback(\n (listener: () => void) => owner.subscribe(projection, listener),\n [owner, projection]\n );\n return useSyncExternalStore(subscribe, read, read);\n}\n\ntype ProjectionItemSnapshot<T> = {\n readonly value: T | undefined;\n readonly revision: number;\n};\n\nexport function useProjectionItem<K extends string, V>(\n projection: CollectionProjection<K, V>,\n key: K,\n store?: ProjectionStore\n): V | undefined {\n const context = useContext(ProjectionContext);\n const owner = store ?? context;\n if (!owner) throw new Error('ProjectionStore is required.');\n const item = useMemo(() => owner.item(projection, key), [key, owner, projection]);\n const read = useMemo(() => {\n let previousRevision = -1;\n let snapshot: ProjectionItemSnapshot<V> | undefined;\n return (): ProjectionItemSnapshot<V> => {\n const value = item.current();\n const revision = item.revision();\n if (snapshot && revision === previousRevision) return snapshot;\n previousRevision = revision;\n snapshot = { value, revision };\n return snapshot;\n };\n }, [item]);\n const subscribe = useCallback((listener: () => void) => item.subscribe(listener), [item]);\n return useSyncExternalStore(subscribe, read, read).value;\n}\n\nexport function useSetProjection<T>(\n projection: InputProjection<T>,\n store?: ProjectionStore\n): (value: T) => void {\n const context = useContext(ProjectionContext);\n const owner = store ?? context;\n if (!owner) throw new Error('ProjectionStore is required.');\n return useCallback((value: T) => owner.set(projection, value), [owner, projection]);\n}\n\nexport type DocumentSelectorOptions<TResult> = {\n readonly isEqual?: (previous: TResult, next: TResult) => boolean;\n readonly server?: () => TResult;\n};\n\ntype SelectorCache<TSchema extends ObjectNode, TResult> = {\n readonly runtime: DocumentReadable<TSchema>;\n readonly value: TResult;\n readonly targets: readonly ImpactTarget<unknown>[];\n};\n\nconst objectIs = <T>(previous: T, next: T): boolean => Object.is(previous, next);\nconst sameTargets = (\n left: readonly ImpactTarget<unknown>[],\n right: readonly ImpactTarget<unknown>[]\n): boolean => {\n if (left.length !== right.length) return false;\n for (let index = 0; index < left.length; index += 1)\n if (!sameTarget(left[index], right[index])) return false;\n return true;\n};\n\nexport function useDocumentSelector<TSchema extends ObjectNode, TResult>(\n runtime: DocumentReadable<TSchema>,\n selector: DocumentSelector<TSchema, TResult>,\n options?: DocumentSelectorOptions<TResult>\n): TResult {\n const equality = options?.isEqual ?? objectIs;\n const cache = useRef<SelectorCache<TSchema, TResult> | undefined>(undefined);\n const serverCache = useRef<\n | {\n readonly runtime: DocumentReadable<TSchema>;\n readonly selector: DocumentSelector<TSchema, TResult>;\n readonly source: (() => TResult) | undefined;\n readonly value: TResult;\n }\n | undefined\n >(undefined);\n\n const read = useMemo(() => {\n // Each selector closure owns its revision cache, including inline selectors\n // that allocate arrays or objects. Equality only compares distinct snapshots.\n let snapshot: { readonly revision: number; readonly value: TResult } | undefined;\n return (): TResult => {\n const revision = runtime.revision();\n if (snapshot?.revision === revision) return snapshot.value;\n const selection = track(runtime, selector);\n const previous = cache.current;\n const value =\n previous && previous.runtime === runtime && equality(previous.value, selection.value)\n ? previous.value\n : selection.value;\n cache.current = { runtime, value, targets: selection.targets };\n snapshot = { revision, value };\n return value;\n };\n }, [equality, runtime, selector]);\n\n const subscribe = useCallback(\n (listener: () => void) => {\n read();\n let targets = cache.current?.targets ?? [];\n let unsubscribe: () => void = () => undefined;\n const install = () => {\n if (targets.length === 0) return () => undefined;\n return subscribeDependencies(runtime, targets, onCommit);\n };\n const onCommit = () => {\n const previous = cache.current;\n const next = read();\n const nextTargets = cache.current?.targets ?? [];\n if (!sameTargets(targets, nextTargets)) {\n unsubscribe();\n targets = nextTargets;\n unsubscribe = install();\n }\n if (previous && !Object.is(previous.value, next)) listener();\n };\n unsubscribe = install();\n return () => unsubscribe();\n },\n [read, runtime]\n );\n\n const server = options?.server;\n const readServer = useCallback((): TResult => {\n const previous = serverCache.current;\n if (\n previous &&\n previous.source === server &&\n previous.runtime === runtime &&\n previous.selector === selector\n )\n return previous.value;\n const value = server ? server() : read();\n serverCache.current = { runtime, selector, source: server, value };\n return value;\n }, [read, server, runtime, selector]);\n\n return useSyncExternalStore(subscribe, read, readServer);\n}\n\nexport function useReadable<T>(readable: Readable<T>): T {\n const subscribe = useCallback((listener: () => void) => readable.subscribe(listener), [readable]);\n const read = useCallback(() => readable.current(), [readable]);\n return useSyncExternalStore(subscribe, read, read);\n}\n\nexport function useHistory<TCommit>(history: LocalHistory<TCommit>): HistoryState & {\n undo(): OperationResult<TCommit>;\n redo(): OperationResult<TCommit>;\n} {\n const subscribe = useCallback((listener: () => void) => history.subscribe(listener), [history]);\n const read = useCallback(() => history.current(), [history]);\n const state = useSyncExternalStore(subscribe, read, read);\n const undo = useCallback(() => history.undo(), [history]);\n const redo = useCallback(() => history.redo(), [history]);\n\n return useMemo(() => ({ ...state, undo, redo }), [redo, state, undo]);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"react.js","names":["sameTarget"],"sources":["../react/src/hooks.ts"],"sourcesContent":["import type {\n DocumentReadable,\n ObjectNode,\n DocumentSelector,\n HistoryState,\n LocalHistory,\n OperationResult,\n Readable,\n ProjectionRuntime,\n Projection,\n Input,\n} from 'doxum';\nimport {\n track,\n subscribeDependencies,\n sameTarget,\n type ImpactTarget,\n trackProjection,\n subscribeProjection,\n type ProjectionSelection,\n} from 'doxum/integration';\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from 'react';\n\nexport const ProjectionContext = createContext<ProjectionRuntime | undefined>(undefined);\nexport const ProjectionProvider = ProjectionContext.Provider;\n\nconst sameProjectionSelection = (\n left: ProjectionSelection,\n right: ProjectionSelection\n): boolean => {\n if (\n left.all !== right.all ||\n left.structure !== right.structure ||\n left.keys.size !== right.keys.size\n )\n return false;\n for (const key of left.keys) if (!right.keys.has(key)) return false;\n return true;\n};\n\nexport function useProjection<T>(projection: Projection<T>, runtime?: ProjectionRuntime): T;\nexport function useProjection<T, R>(\n projection: Projection<T>,\n selector: (value: T) => R,\n runtime?: ProjectionRuntime\n): R;\nexport function useProjection<T, R>(\n projection: Projection<T>,\n selector: (value: T) => R,\n equality?: (previous: R, next: R) => boolean,\n runtime?: ProjectionRuntime\n): R;\nexport function useProjection<T, R>(\n projection: Projection<T>,\n selectorOrRuntime?: ((value: T) => R) | ProjectionRuntime,\n equalityOrRuntime?: ((previous: R, next: R) => boolean) | ProjectionRuntime,\n suppliedRuntime?: ProjectionRuntime\n): T | R {\n const context = useContext(ProjectionContext);\n const selector = typeof selectorOrRuntime === 'function' ? selectorOrRuntime : undefined;\n const equality = typeof equalityOrRuntime === 'function' ? equalityOrRuntime : Object.is;\n const owner =\n (selector ? suppliedRuntime : undefined) ??\n (selector\n ? equalityOrRuntime && typeof equalityOrRuntime !== 'function'\n ? equalityOrRuntime\n : undefined\n : undefined) ??\n (selector ? context : typeof selectorOrRuntime === 'object' ? selectorOrRuntime : context);\n if (!owner) throw new Error('ProjectionRuntime is required.');\n if (!selector) {\n const read = useCallback(() => owner.get(projection), [owner, projection]);\n const subscribe = useCallback(\n (listener: () => void) => owner.subscribe(projection, listener),\n [owner, projection]\n );\n return useSyncExternalStore(subscribe, read, read) as T;\n }\n const cache = useRef<{ value: R; selection: ProjectionSelection } | undefined>(undefined);\n const read = useCallback(() => {\n const selected = trackProjection(owner, projection, selector);\n const previous = cache.current;\n const value =\n previous && equality(previous.value, selected.value) ? previous.value : selected.value;\n cache.current = { value, selection: selected.selection };\n return value;\n }, [equality, owner, projection, selector]);\n const subscribe = useCallback(\n (listener: () => void) => {\n read();\n let selection = cache.current?.selection ?? {\n keys: new Set<string>(),\n all: true,\n structure: false,\n };\n let unsubscribe = subscribeProjection(owner, projection, selection, onInvalidate);\n const reinstall = (next: ProjectionSelection) => {\n if (sameProjectionSelection(selection, next)) return;\n unsubscribe();\n selection = next;\n unsubscribe = subscribeProjection(owner, projection, selection, onInvalidate);\n };\n function onInvalidate() {\n const previous = cache.current?.value;\n const next = read();\n const nextSelection = cache.current?.selection;\n if (nextSelection) reinstall(nextSelection);\n if (!Object.is(previous, next)) listener();\n }\n return () => unsubscribe();\n },\n [owner, projection, read]\n );\n return useSyncExternalStore(subscribe, read, read);\n}\n\nexport function useInput<T>(\n input: Input<T>,\n runtime?: ProjectionRuntime\n): readonly [T, (value: T) => void] {\n const context = useContext(ProjectionContext);\n const owner = runtime ?? context;\n if (!owner) throw new Error('ProjectionRuntime is required.');\n const value = useProjection(input, owner);\n const set = useCallback((next: T) => owner.set(input, next), [input, owner]);\n return useMemo(() => [value, set] as const, [set, value]);\n}\n\nexport type DocumentSelectorOptions<TResult> = {\n readonly isEqual?: (previous: TResult, next: TResult) => boolean;\n readonly server?: () => TResult;\n};\n\ntype SelectorCache<TSchema extends ObjectNode, TResult> = {\n readonly runtime: DocumentReadable<TSchema>;\n readonly value: TResult;\n readonly targets: readonly ImpactTarget<unknown>[];\n};\n\nconst objectIs = <T>(previous: T, next: T): boolean => Object.is(previous, next);\nconst sameTargets = (\n left: readonly ImpactTarget<unknown>[],\n right: readonly ImpactTarget<unknown>[]\n): boolean => {\n if (left.length !== right.length) return false;\n for (let index = 0; index < left.length; index += 1)\n if (!sameTarget(left[index], right[index])) return false;\n return true;\n};\n\nexport function useDocumentSelector<TSchema extends ObjectNode, TResult>(\n runtime: DocumentReadable<TSchema>,\n selector: DocumentSelector<TSchema, TResult>,\n options?: DocumentSelectorOptions<TResult>\n): TResult {\n const equality = options?.isEqual ?? objectIs;\n const cache = useRef<SelectorCache<TSchema, TResult> | undefined>(undefined);\n const serverCache = useRef<\n | {\n readonly runtime: DocumentReadable<TSchema>;\n readonly selector: DocumentSelector<TSchema, TResult>;\n readonly source: (() => TResult) | undefined;\n readonly value: TResult;\n }\n | undefined\n >(undefined);\n\n const read = useMemo(() => {\n // Each selector closure owns its revision cache, including inline selectors\n // that allocate arrays or objects. Equality only compares distinct snapshots.\n let snapshot: { readonly revision: number; readonly value: TResult } | undefined;\n return (): TResult => {\n const revision = runtime.revision();\n if (snapshot?.revision === revision) return snapshot.value;\n const selection = track(runtime, selector);\n const previous = cache.current;\n const value =\n previous && previous.runtime === runtime && equality(previous.value, selection.value)\n ? previous.value\n : selection.value;\n cache.current = { runtime, value, targets: selection.targets };\n snapshot = { revision, value };\n return value;\n };\n }, [equality, runtime, selector]);\n\n const subscribe = useCallback(\n (listener: () => void) => {\n read();\n let targets = cache.current?.targets ?? [];\n let unsubscribe: () => void = () => undefined;\n const install = () => {\n if (targets.length === 0) return () => undefined;\n return subscribeDependencies(runtime, targets, onCommit);\n };\n const onCommit = () => {\n const previous = cache.current;\n const next = read();\n const nextTargets = cache.current?.targets ?? [];\n if (!sameTargets(targets, nextTargets)) {\n unsubscribe();\n targets = nextTargets;\n unsubscribe = install();\n }\n if (previous && !Object.is(previous.value, next)) listener();\n };\n unsubscribe = install();\n return () => unsubscribe();\n },\n [read, runtime]\n );\n\n const server = options?.server;\n const readServer = useCallback((): TResult => {\n const previous = serverCache.current;\n if (\n previous &&\n previous.source === server &&\n previous.runtime === runtime &&\n previous.selector === selector\n )\n return previous.value;\n const value = server ? server() : read();\n serverCache.current = { runtime, selector, source: server, value };\n return value;\n }, [read, server, runtime, selector]);\n\n return useSyncExternalStore(subscribe, read, readServer);\n}\n\nexport function useReadable<T>(readable: Readable<T>): T {\n const subscribe = useCallback((listener: () => void) => readable.subscribe(listener), [readable]);\n const read = useCallback(() => readable.current(), [readable]);\n return useSyncExternalStore(subscribe, read, read);\n}\n\nexport function useHistory<TCommit>(history: LocalHistory<TCommit>): HistoryState & {\n undo(): OperationResult<TCommit>;\n redo(): OperationResult<TCommit>;\n} {\n const subscribe = useCallback((listener: () => void) => history.subscribe(listener), [history]);\n const read = useCallback(() => history.current(), [history]);\n const state = useSyncExternalStore(subscribe, read, read);\n const undo = useCallback(() => history.undo(), [history]);\n const redo = useCallback(() => history.redo(), [history]);\n\n return useMemo(() => ({ ...state, undo, redo }), [redo, state, undo]);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { _ as Unsubscribe } from "./contract-XmKnroJq.cjs";
|
|
2
|
+
import { c as BatchOptions, m as ProjectionError, n as Projection, t as Input } from "./definition-kxnWUvX9.cjs";
|
|
3
|
+
|
|
4
|
+
//#region core/src/projection/store.d.ts
|
|
5
|
+
type ProjectionRuntime = {
|
|
6
|
+
get<T>(projection: Projection<T>): T;
|
|
7
|
+
subscribe<T>(projection: Projection<T>, listener: () => void): Unsubscribe;
|
|
8
|
+
set<T>(input: Input<T>, value: T): void;
|
|
9
|
+
batch<T>(run: () => T): T;
|
|
10
|
+
batch<T>(options: BatchOptions, run: () => T): T;
|
|
11
|
+
dispose(): void;
|
|
12
|
+
};
|
|
13
|
+
declare const createProjectionRuntime: (options?: {
|
|
14
|
+
readonly onError?: (error: ProjectionError) => void;
|
|
15
|
+
}) => ProjectionRuntime;
|
|
16
|
+
type ProjectionSelection = {
|
|
17
|
+
readonly keys: ReadonlySet<string>;
|
|
18
|
+
readonly all: boolean;
|
|
19
|
+
readonly structure: boolean;
|
|
20
|
+
};
|
|
21
|
+
declare const trackProjection: <T, R>(owner: ProjectionRuntime, projection: Projection<T>, selector: (value: T) => R) => {
|
|
22
|
+
readonly value: R;
|
|
23
|
+
readonly selection: ProjectionSelection;
|
|
24
|
+
};
|
|
25
|
+
declare const subscribeProjection: (owner: ProjectionRuntime, projection: Projection<unknown>, selection: ProjectionSelection, listener: () => void) => Unsubscribe;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { trackProjection as a, subscribeProjection as i, ProjectionSelection as n, createProjectionRuntime as r, ProjectionRuntime as t };
|
|
28
|
+
//# sourceMappingURL=store-CDeqZEE3.d.cts.map
|