doxum 0.1.11 → 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.
Files changed (64) hide show
  1. package/README.md +43 -33
  2. package/dist/advanced.cjs +116 -0
  3. package/dist/advanced.cjs.map +1 -0
  4. package/dist/advanced.d.cts +42 -0
  5. package/dist/advanced.d.ts +42 -0
  6. package/dist/advanced.js +115 -0
  7. package/dist/advanced.js.map +1 -0
  8. package/dist/{contract-CeAnEPBA.d.ts → contract-BT53Gg94.d.ts} +5 -4
  9. package/dist/{contract-DtGVSXSK.d.cts → contract-XmKnroJq.d.cts} +5 -4
  10. package/dist/definition-177L4Amk.cjs +898 -0
  11. package/dist/definition-177L4Amk.cjs.map +1 -0
  12. package/dist/definition-BlMeHwdz.d.ts +98 -0
  13. package/dist/definition-DXrKMVs7.js +785 -0
  14. package/dist/definition-DXrKMVs7.js.map +1 -0
  15. package/dist/definition-kxnWUvX9.d.cts +98 -0
  16. package/dist/{driver-xOIkwrB8.cjs → driver-BCyfqxsl.cjs} +1 -1
  17. package/dist/{driver-xOIkwrB8.cjs.map → driver-BCyfqxsl.cjs.map} +1 -1
  18. package/dist/{driver-BlR81Dqg.js → driver-CSnhMjbP.js} +1 -1
  19. package/dist/{driver-BlR81Dqg.js.map → driver-CSnhMjbP.js.map} +1 -1
  20. package/dist/index.cjs +31 -29
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +5 -4
  23. package/dist/index.d.ts +5 -4
  24. package/dist/index.js +7 -6
  25. package/dist/index.js.map +1 -1
  26. package/dist/{integration-VTZ3ICsO.js → integration-Bco8ZB16.js} +7 -3
  27. package/dist/integration-Bco8ZB16.js.map +1 -0
  28. package/dist/integration-CEUn96tx.cjs +52 -0
  29. package/dist/integration-CEUn96tx.cjs.map +1 -0
  30. package/dist/integration.cjs +7 -3
  31. package/dist/integration.d.cts +7 -3
  32. package/dist/integration.d.ts +7 -3
  33. package/dist/integration.js +3 -3
  34. package/dist/local-sync.cjs +1 -1
  35. package/dist/local-sync.d.cts +1 -1
  36. package/dist/local-sync.d.ts +1 -1
  37. package/dist/local-sync.js +1 -1
  38. package/dist/react.cjs +66 -12
  39. package/dist/react.cjs.map +1 -1
  40. package/dist/react.d.cts +8 -6
  41. package/dist/react.d.ts +8 -6
  42. package/dist/react.js +66 -12
  43. package/dist/react.js.map +1 -1
  44. package/dist/store-CDeqZEE3.d.cts +28 -0
  45. package/dist/{store-DHFXfWSz.js → store-CtgvCVFg.js} +585 -917
  46. package/dist/store-CtgvCVFg.js.map +1 -0
  47. package/dist/{store-DU2u-qFH.cjs → store-DcDpDgjk.cjs} +595 -987
  48. package/dist/store-DcDpDgjk.cjs.map +1 -0
  49. package/dist/store-P5dJ7TVe.d.ts +28 -0
  50. package/package.json +6 -1
  51. package/skills/doxum-runtime/SKILL.md +5 -5
  52. package/skills/doxum-runtime/references/guide.en.md +12 -12
  53. package/skills/doxum-runtime/references/guide.zh-CN.md +9 -11
  54. package/skills/doxum-runtime/references/patterns.en.md +12 -17
  55. package/skills/doxum-runtime/references/patterns.zh-CN.md +12 -16
  56. package/skills/doxum-runtime/references/projections.en.md +56 -190
  57. package/skills/doxum-runtime/references/projections.zh-CN.md +49 -171
  58. package/dist/integration-BKgGuodm.cjs +0 -30
  59. package/dist/integration-BKgGuodm.cjs.map +0 -1
  60. package/dist/integration-VTZ3ICsO.js.map +0 -1
  61. package/dist/store-Bs0C0rNd.d.ts +0 -262
  62. package/dist/store-CJuwJl_K.d.cts +0 -262
  63. package/dist/store-DHFXfWSz.js.map +0 -1
  64. package/dist/store-DU2u-qFH.cjs.map +0 -1
package/dist/react.cjs CHANGED
@@ -1,22 +1,76 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_store = require("./store-DU2u-qFH.cjs");
3
- const require_integration = require("./integration-BKgGuodm.cjs");
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
- function useProjection(projection, 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) {
9
14
  const context = (0, react.useContext)(ProjectionContext);
10
- const owner = store ?? context;
11
- if (!owner) throw new Error("ProjectionStore is required.");
12
- const read = (0, react.useCallback)(() => owner.get(projection), [owner, projection]);
13
- return (0, react.useSyncExternalStore)((0, react.useCallback)((listener) => owner.subscribe(projection, listener), [owner, projection]), read, read);
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,
35
+ owner,
36
+ projection,
37
+ selector
38
+ ]);
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
45
+ };
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);
14
66
  }
15
- function useSetProjection(projection, store) {
67
+ function useInput(input, runtime) {
16
68
  const context = (0, react.useContext)(ProjectionContext);
17
- const owner = store ?? context;
18
- if (!owner) throw new Error("ProjectionStore is required.");
19
- return (0, react.useCallback)((value) => owner.set(projection, value), [owner, projection]);
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]);
20
74
  }
21
75
  const objectIs = (previous, next) => Object.is(previous, next);
22
76
  const sameTargets = (left, right) => {
@@ -119,8 +173,8 @@ exports.ProjectionContext = ProjectionContext;
119
173
  exports.ProjectionProvider = ProjectionProvider;
120
174
  exports.useDocumentSelector = useDocumentSelector;
121
175
  exports.useHistory = useHistory;
176
+ exports.useInput = useInput;
122
177
  exports.useProjection = useProjection;
123
178
  exports.useReadable = useReadable;
124
- exports.useSetProjection = useSetProjection;
125
179
 
126
180
  //# sourceMappingURL=react.cjs.map
@@ -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 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\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,11 +1,13 @@
1
1
  import * as _$react from "react";
2
- import { DocumentReadable, DocumentSelector, HistoryState, InputProjection, LocalHistory, ObjectNode, OperationResult, ProjectionStore, Readable, ValueProjection } from "doxum";
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<ProjectionStore | undefined>;
6
- declare const ProjectionProvider: _$react.Provider<ProjectionStore | undefined>;
7
- declare function useProjection<T>(projection: ValueProjection<T>, store?: ProjectionStore): T;
8
- declare function useSetProjection<T>(projection: InputProjection<T>, store?: ProjectionStore): (value: T) => void;
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];
9
11
  type DocumentSelectorOptions<TResult> = {
10
12
  readonly isEqual?: (previous: TResult, next: TResult) => boolean;
11
13
  readonly server?: () => TResult;
@@ -17,5 +19,5 @@ declare function useHistory<TCommit>(history: LocalHistory<TCommit>): HistorySta
17
19
  redo(): OperationResult<TCommit>;
18
20
  };
19
21
  //#endregion
20
- export { type DocumentSelectorOptions, ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useProjection, useReadable, useSetProjection };
22
+ export { type DocumentSelectorOptions, ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
21
23
  //# sourceMappingURL=react.d.cts.map
package/dist/react.d.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  import * as _$react from "react";
2
- import { DocumentReadable, DocumentSelector, HistoryState, InputProjection, LocalHistory, ObjectNode, OperationResult, ProjectionStore, Readable, ValueProjection } from "doxum";
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<ProjectionStore | undefined>;
6
- declare const ProjectionProvider: _$react.Provider<ProjectionStore | undefined>;
7
- declare function useProjection<T>(projection: ValueProjection<T>, store?: ProjectionStore): T;
8
- declare function useSetProjection<T>(projection: InputProjection<T>, store?: ProjectionStore): (value: T) => void;
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];
9
11
  type DocumentSelectorOptions<TResult> = {
10
12
  readonly isEqual?: (previous: TResult, next: TResult) => boolean;
11
13
  readonly server?: () => TResult;
@@ -17,5 +19,5 @@ declare function useHistory<TCommit>(history: LocalHistory<TCommit>): HistorySta
17
19
  redo(): OperationResult<TCommit>;
18
20
  };
19
21
  //#endregion
20
- export { type DocumentSelectorOptions, ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useProjection, useReadable, useSetProjection };
22
+ export { type DocumentSelectorOptions, ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
21
23
  //# sourceMappingURL=react.d.ts.map
package/dist/react.js CHANGED
@@ -1,21 +1,75 @@
1
- import { S as same, f as subscribeDependencies } from "./store-DHFXfWSz.js";
2
- import { t as track } from "./integration-VTZ3ICsO.js";
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
- function useProjection(projection, 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) {
8
13
  const context = useContext(ProjectionContext);
9
- const owner = store ?? context;
10
- if (!owner) throw new Error("ProjectionStore is required.");
11
- const read = useCallback(() => owner.get(projection), [owner, projection]);
12
- return useSyncExternalStore(useCallback((listener) => owner.subscribe(projection, listener), [owner, projection]), read, read);
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,
34
+ owner,
35
+ projection,
36
+ selector
37
+ ]);
38
+ return useSyncExternalStore(useCallback((listener) => {
39
+ read();
40
+ let selection = cache.current?.selection ?? {
41
+ keys: /* @__PURE__ */ new Set(),
42
+ all: true,
43
+ structure: false
44
+ };
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);
13
65
  }
14
- function useSetProjection(projection, store) {
66
+ function useInput(input, runtime) {
15
67
  const context = useContext(ProjectionContext);
16
- const owner = store ?? context;
17
- if (!owner) throw new Error("ProjectionStore is required.");
18
- return useCallback((value) => owner.set(projection, value), [owner, projection]);
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]);
19
73
  }
20
74
  const objectIs = (previous, next) => Object.is(previous, next);
21
75
  const sameTargets = (left, right) => {
@@ -114,6 +168,6 @@ function useHistory(history) {
114
168
  ]);
115
169
  }
116
170
  //#endregion
117
- export { ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useProjection, useReadable, useSetProjection };
171
+ export { ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
118
172
 
119
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 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\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