doxum 0.1.16 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.cjs CHANGED
@@ -5,11 +5,8 @@ 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, selectorOrRuntime, equalityOrRuntime, suppliedRuntime) {
9
- const context = (0, react.useContext)(ProjectionContext);
10
- const selector = typeof selectorOrRuntime === "function" ? selectorOrRuntime : void 0;
11
- const equality = typeof equalityOrRuntime === "function" ? equalityOrRuntime : Object.is;
12
- const owner = (selector ? suppliedRuntime : void 0) ?? (selector ? equalityOrRuntime && typeof equalityOrRuntime !== "function" ? equalityOrRuntime : void 0 : void 0) ?? (selector ? context : typeof selectorOrRuntime === "object" ? selectorOrRuntime : context);
8
+ function useProjection(projection, selector, equality = Object.is) {
9
+ const owner = (0, react.useContext)(ProjectionContext);
13
10
  if (!owner) throw new Error("ProjectionRuntime is required.");
14
11
  return useReadable((0, react.useMemo)(() => selector ? owner.readable(projection, selector, equality) : owner.readable(projection), [
15
12
  equality,
@@ -18,11 +15,10 @@ function useProjection(projection, selectorOrRuntime, equalityOrRuntime, supplie
18
15
  selector
19
16
  ]));
20
17
  }
21
- function useInput(input, runtime) {
22
- const context = (0, react.useContext)(ProjectionContext);
23
- const owner = runtime ?? context;
18
+ function useInput(input) {
19
+ const owner = (0, react.useContext)(ProjectionContext);
24
20
  if (!owner) throw new Error("ProjectionRuntime is required.");
25
- const value = useProjection(input, owner);
21
+ const value = useProjection(input);
26
22
  const set = (0, react.useCallback)((next) => owner.set(input, next), [input, owner]);
27
23
  return (0, react.useMemo)(() => [value, set], [set, value]);
28
24
  }
@@ -123,7 +119,6 @@ function useHistory(history) {
123
119
  ]);
124
120
  }
125
121
  //#endregion
126
- exports.ProjectionContext = ProjectionContext;
127
122
  exports.ProjectionProvider = ProjectionProvider;
128
123
  exports.useDocumentSelector = useDocumentSelector;
129
124
  exports.useHistory = useHistory;
@@ -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 ProjectionRuntime,\n Projection,\n Input,\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<ProjectionRuntime | undefined>(undefined);\nexport const ProjectionProvider = ProjectionContext.Provider;\n\nexport function useProjection<T>(\n projection: Projection<T, unknown>,\n runtime?: ProjectionRuntime\n): T;\nexport function useProjection<T, R>(\n projection: Projection<T, unknown>,\n selector: (value: T) => R,\n runtime?: ProjectionRuntime\n): R;\nexport function useProjection<T, R>(\n projection: Projection<T, unknown>,\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, unknown>,\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 const readable = useMemo(\n () => (selector ? owner.readable(projection, selector, equality) : owner.readable(projection)),\n [equality, owner, projection, selector]\n );\n return useReadable(readable as Readable<T | R>);\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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"}
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 ProjectionRuntime,\n Projection,\n Input,\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\nconst ProjectionContext = createContext<ProjectionRuntime | undefined>(undefined);\nexport const ProjectionProvider = ProjectionContext.Provider;\n\nexport function useProjection<T>(projection: Projection<T, unknown>): T;\nexport function useProjection<T, R>(\n projection: Projection<T, unknown>,\n selector: (value: T) => R,\n equality?: (previous: R, next: R) => boolean\n): R;\nexport function useProjection<T, R>(\n projection: Projection<T, unknown>,\n selector?: (value: T) => R,\n equality: (previous: R, next: R) => boolean = Object.is\n): T | R {\n const context = useContext(ProjectionContext);\n const owner = context;\n if (!owner) throw new Error('ProjectionRuntime is required.');\n const readable = useMemo(\n () => (selector ? owner.readable(projection, selector, equality) : owner.readable(projection)),\n [equality, owner, projection, selector]\n );\n return useReadable(readable as Readable<T | R>);\n}\n\nexport function useInput<T>(input: Input<T>): readonly [T, (value: T) => void] {\n const context = useContext(ProjectionContext);\n const owner = context;\n if (!owner) throw new Error('ProjectionRuntime is required.');\n const value = useProjection(input);\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
@@ -2,12 +2,10 @@ import * as _$react from "react";
2
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<ProjectionRuntime | undefined>;
6
5
  declare const ProjectionProvider: _$react.Provider<ProjectionRuntime | undefined>;
7
- declare function useProjection<T>(projection: Projection<T, unknown>, runtime?: ProjectionRuntime): T;
8
- declare function useProjection<T, R>(projection: Projection<T, unknown>, selector: (value: T) => R, runtime?: ProjectionRuntime): R;
9
- declare function useProjection<T, R>(projection: Projection<T, unknown>, 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];
6
+ declare function useProjection<T>(projection: Projection<T, unknown>): T;
7
+ declare function useProjection<T, R>(projection: Projection<T, unknown>, selector: (value: T) => R, equality?: (previous: R, next: R) => boolean): R;
8
+ declare function useInput<T>(input: Input<T>): readonly [T, (value: T) => void];
11
9
  type DocumentSelectorOptions<TResult> = {
12
10
  readonly isEqual?: (previous: TResult, next: TResult) => boolean;
13
11
  readonly server?: () => TResult;
@@ -19,5 +17,5 @@ declare function useHistory<TCommit>(history: LocalHistory<TCommit>): HistorySta
19
17
  redo(): OperationResult<TCommit>;
20
18
  };
21
19
  //#endregion
22
- export { type DocumentSelectorOptions, ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
20
+ export { type DocumentSelectorOptions, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
23
21
  //# sourceMappingURL=react.d.cts.map
package/dist/react.d.ts CHANGED
@@ -2,12 +2,10 @@ import * as _$react from "react";
2
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<ProjectionRuntime | undefined>;
6
5
  declare const ProjectionProvider: _$react.Provider<ProjectionRuntime | undefined>;
7
- declare function useProjection<T>(projection: Projection<T, unknown>, runtime?: ProjectionRuntime): T;
8
- declare function useProjection<T, R>(projection: Projection<T, unknown>, selector: (value: T) => R, runtime?: ProjectionRuntime): R;
9
- declare function useProjection<T, R>(projection: Projection<T, unknown>, 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];
6
+ declare function useProjection<T>(projection: Projection<T, unknown>): T;
7
+ declare function useProjection<T, R>(projection: Projection<T, unknown>, selector: (value: T) => R, equality?: (previous: R, next: R) => boolean): R;
8
+ declare function useInput<T>(input: Input<T>): readonly [T, (value: T) => void];
11
9
  type DocumentSelectorOptions<TResult> = {
12
10
  readonly isEqual?: (previous: TResult, next: TResult) => boolean;
13
11
  readonly server?: () => TResult;
@@ -19,5 +17,5 @@ declare function useHistory<TCommit>(history: LocalHistory<TCommit>): HistorySta
19
17
  redo(): OperationResult<TCommit>;
20
18
  };
21
19
  //#endregion
22
- export { type DocumentSelectorOptions, ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
20
+ export { type DocumentSelectorOptions, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
23
21
  //# sourceMappingURL=react.d.ts.map
package/dist/react.js CHANGED
@@ -4,11 +4,8 @@ import { createContext, useCallback, useContext, useMemo, useRef, useSyncExterna
4
4
  //#region react/src/hooks.ts
5
5
  const ProjectionContext = createContext(void 0);
6
6
  const ProjectionProvider = ProjectionContext.Provider;
7
- function useProjection(projection, selectorOrRuntime, equalityOrRuntime, suppliedRuntime) {
8
- const context = useContext(ProjectionContext);
9
- const selector = typeof selectorOrRuntime === "function" ? selectorOrRuntime : void 0;
10
- const equality = typeof equalityOrRuntime === "function" ? equalityOrRuntime : Object.is;
11
- const owner = (selector ? suppliedRuntime : void 0) ?? (selector ? equalityOrRuntime && typeof equalityOrRuntime !== "function" ? equalityOrRuntime : void 0 : void 0) ?? (selector ? context : typeof selectorOrRuntime === "object" ? selectorOrRuntime : context);
7
+ function useProjection(projection, selector, equality = Object.is) {
8
+ const owner = useContext(ProjectionContext);
12
9
  if (!owner) throw new Error("ProjectionRuntime is required.");
13
10
  return useReadable(useMemo(() => selector ? owner.readable(projection, selector, equality) : owner.readable(projection), [
14
11
  equality,
@@ -17,11 +14,10 @@ function useProjection(projection, selectorOrRuntime, equalityOrRuntime, supplie
17
14
  selector
18
15
  ]));
19
16
  }
20
- function useInput(input, runtime) {
21
- const context = useContext(ProjectionContext);
22
- const owner = runtime ?? context;
17
+ function useInput(input) {
18
+ const owner = useContext(ProjectionContext);
23
19
  if (!owner) throw new Error("ProjectionRuntime is required.");
24
- const value = useProjection(input, owner);
20
+ const value = useProjection(input);
25
21
  const set = useCallback((next) => owner.set(input, next), [input, owner]);
26
22
  return useMemo(() => [value, set], [set, value]);
27
23
  }
@@ -122,6 +118,6 @@ function useHistory(history) {
122
118
  ]);
123
119
  }
124
120
  //#endregion
125
- export { ProjectionContext, ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
121
+ export { ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
126
122
 
127
123
  //# 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 ProjectionRuntime,\n Projection,\n Input,\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<ProjectionRuntime | undefined>(undefined);\nexport const ProjectionProvider = ProjectionContext.Provider;\n\nexport function useProjection<T>(\n projection: Projection<T, unknown>,\n runtime?: ProjectionRuntime\n): T;\nexport function useProjection<T, R>(\n projection: Projection<T, unknown>,\n selector: (value: T) => R,\n runtime?: ProjectionRuntime\n): R;\nexport function useProjection<T, R>(\n projection: Projection<T, unknown>,\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, unknown>,\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 const readable = useMemo(\n () => (selector ? owner.readable(projection, selector, equality) : owner.readable(projection)),\n [equality, owner, projection, selector]\n );\n return useReadable(readable as Readable<T | R>);\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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"}
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 { 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\nconst ProjectionContext = createContext<ProjectionRuntime | undefined>(undefined);\nexport const ProjectionProvider = ProjectionContext.Provider;\n\nexport function useProjection<T>(projection: Projection<T, unknown>): T;\nexport function useProjection<T, R>(\n projection: Projection<T, unknown>,\n selector: (value: T) => R,\n equality?: (previous: R, next: R) => boolean\n): R;\nexport function useProjection<T, R>(\n projection: Projection<T, unknown>,\n selector?: (value: T) => R,\n equality: (previous: R, next: R) => boolean = Object.is\n): T | R {\n const context = useContext(ProjectionContext);\n const owner = context;\n if (!owner) throw new Error('ProjectionRuntime is required.');\n const readable = useMemo(\n () => (selector ? owner.readable(projection, selector, equality) : owner.readable(projection)),\n [equality, owner, projection, selector]\n );\n return useReadable(readable as Readable<T | R>);\n}\n\nexport function useInput<T>(input: Input<T>): readonly [T, (value: T) => void] {\n const context = useContext(ProjectionContext);\n const owner = context;\n if (!owner) throw new Error('ProjectionRuntime is required.');\n const value = useProjection(input);\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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doxum",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "description": "Doxum is a typed runtime for complex mutable documents.",
@@ -87,7 +87,8 @@
87
87
  "build": "tsdown --config tsdown.config.ts",
88
88
  "typecheck": "tsc -p tsconfig.json --noEmit",
89
89
  "test": "vitest run --config vitest.config.ts",
90
- "check": "pnpm run format:check && pnpm run lint && pnpm run typecheck && pnpm run test",
90
+ "check": "pnpm run format:check && pnpm run lint && pnpm run typecheck && pnpm run test && pnpm run check:projection-surface",
91
+ "check:projection-surface": "node scripts/check-projection-surface.mjs",
91
92
  "bench": "vitest bench --config vitest.bench.config.ts",
92
93
  "profile": "node --expose-gc --import tsx core/bench/profile.ts",
93
94
  "format": "prettier --write --ignore-unknown .",
@@ -33,7 +33,8 @@ Before runtime changes read [invariants](references/invariants.en.md) or
33
33
  Use tuple `derive` for pure values. Advanced `incremental` processors declare every
34
34
  source, own any forward/reverse dependency indexes, derive from final batched source
35
35
  state, and recover from resets internally. Core projections never track reads
36
- automatically; React selectors do through `useProjection(projection, selector)`.
36
+ automatically; React selectors do through `ProjectionProvider` and
37
+ `useProjection(projection, selector)`.
37
38
  - Observer errors leave commits accepted. Do not retry as if they rolled back.
38
39
  - Core stays framework-neutral; adapters use integration capabilities.
39
40
  - Local sync owns browser persistence/leadership. Network conflict policy and
@@ -95,8 +95,8 @@ runtime.get(scaled);
95
95
  const title = runtime.get(tasks).get(taskId);
96
96
  ```
97
97
 
98
- Use `useProjection` with a Runtime for projection definitions and
99
- `useProjection(projection, selector)` for keyed reads. `useInput` returns a value
100
- and setter. Advanced collection processors in `doxum/advanced` stage
101
- `output.set/remove/order/replace` and use scoped previous/next reads. Processor
98
+ Provide the Runtime through `ProjectionProvider`, then use `useProjection` for
99
+ projection definitions and `useProjection(projection, selector)` for keyed reads.
100
+ `useInput` returns a value and setter. Advanced collection processors in `doxum/advanced` stage
101
+ `output.set/remove/order` and use scoped previous/next reads. Processor
102
102
  dependencies remain explicit even though React selectors track actual reads.
@@ -94,8 +94,8 @@ runtime.get(scaled);
94
94
  const title = runtime.get(tasks).get(taskId);
95
95
  ```
96
96
 
97
- React 使用 Runtime 上下文中的 `useProjection` 读取 Projection,单键读取写成
97
+ React 使用 `ProjectionProvider` 提供 Runtime,再用 `useProjection` 读取 Projection,单键读取写成
98
98
  `useProjection(projection, selector)`;`useInput` 返回值和 setter。高级集合 processor
99
99
  从 `doxum/advanced` 引入,在同步 callback 中使用
100
- `output.set/remove/order/replace` 与 previous/next。Processor 依赖仍显式声明,
100
+ `output.set/remove/order` 与 previous/next。Processor 依赖仍显式声明,
101
101
  React selector 追踪只属于消费端。
@@ -23,8 +23,8 @@ sources use `kind: 'value'` or `kind: 'collection'`; the caller still uses only
23
23
 
24
24
  External events are smaller than Runtime contexts. A value event carries the new
25
25
  `value` and `revision`; a collection event carries a stable `previous` read,
26
- `revision`, and an optional keyed `change`. The Runtime derives `changed` and
27
- transitions itself.
26
+ `revision`, and an optional `impact` hint. The Runtime derives the exact
27
+ `CollectionChange`; processors never receive the impact directly.
28
28
 
29
29
  `derive(dependencies, compute, equality?)` takes a tuple. Dependencies are
30
30
  explicit and fixed when the definition is created. Processors must not discover
@@ -67,10 +67,13 @@ dependencies receive `reset` or grouped `added`/`updated`/`removed` entries with
67
67
  complete `before`/`after` values and optional `order.before`/`order.after`.
68
68
  The initial build reports `reset` for collection dependencies. A committed batch
69
69
  is already coalesced into one net transition.
70
+ Collection values inside `sources` are callback-local lazy `ReadonlyMap` views;
71
+ do not retain or return them. Keyed `get`/`has` avoids a scan, while iteration is
72
+ an explicit full-collection read.
70
73
 
71
74
  `incremental.collection(...)` uses a separate collection processor protocol and additionally exposes borrowed
72
75
  `previous`/`next` keyed reads and a callback-local `output` draft. Draft methods are
73
- `set`, `remove`, `order`, and `replace`; the Runtime validates and seals them after
76
+ `set`, `remove`, and `order`; the Runtime validates and seals them after
74
77
  the synchronous callback, computes keyed transitions and publishes one immutable
75
78
  map-like value. Reset or fault recovery is internal.
76
79
 
@@ -22,7 +22,8 @@ source 通过 `kind: 'value'` 或 `kind: 'collection'` 区分语义,但调用
22
22
 
23
23
  External event 不再复用 Runtime context:value event 提供新 `value` 和
24
24
  `revision`;collection event 提供稳定的 `previous` read、`revision` 和可选的
25
- keyed `change`。`changed` 与 transitions 由 Runtime 自己计算。
25
+ `impact` hint。Runtime 自己计算精确的 `CollectionChange`,processor 不会直接收到
26
+ impact。
26
27
 
27
28
  `derive(dependencies, compute, equality?)` 使用 tuple,依赖在定义创建时固定。
28
29
  Processor 不能通过读取另一个 Projection 隐式建立图依赖。
@@ -62,11 +63,13 @@ const doubled = incremental.collection([tasks], ({ sources, output }) => {
62
63
  标量依赖为 `undefined`,集合依赖则是 `reset`,或带完整 `before`/`after` 值的
63
64
  `added`/`updated`/`removed` 分组,并可选提供 `order.before`/`order.after`。初次
64
65
  build 对集合依赖报告 `reset`;一次已提交的 batch 已经合并成一个净 transition。
66
+ `sources` 内的集合值是 callback-local 的惰性 `ReadonlyMap` 视图,不能保存或直接
67
+ 返回。`get`/`has` 保持按 key 读取,迭代才显式扫描整个集合。
65
68
 
66
69
  `incremental.collection(...)` 使用独立的 collection processor 协议,另外提供借用的
67
70
  `previous`/`next` keyed read,以及
68
- 只在同步 callback 内有效的 `output` draft。Draft 只有 `set`、`remove`、`order`、
69
- `replace`;Runtime 在 callback 返回后校验并 seal,计算 keyed transitions,发布
71
+ 只在同步 callback 内有效的 `output` draft。Draft 只有 `set`、`remove`、`order`;
72
+ Runtime 在 callback 返回后校验并 seal,计算 keyed transitions,发布
70
73
  一个不可变 map-like 值。reset 或故障恢复由 Runtime 内部完成。
71
74
 
72
75
  ## React selector 追踪
@@ -1,136 +0,0 @@
1
- import { J as Infer, L as CollectionId, R as CollectionNode, Z as ObjectNode, _ as Unsubscribe, et as PathValueOf, m as Synchronous, nt as SchemaPath, s as DocumentReadable, tt as ReadonlyValue, v as Readable, x as CollectionImpact, z as CollectionPath } from "./contract-XmKnroJq.cjs";
2
-
3
- //#region core/src/projection/contract.d.ts
4
- /** Opaque application metadata identifying the action that produced a source event. */
5
- type Cause = unknown;
6
- type BatchOptions = {
7
- readonly cause?: Cause;
8
- };
9
- type CollectionEntryTransition<K extends string, V> = {
10
- readonly key: K;
11
- readonly kind: 'added';
12
- readonly before: undefined;
13
- readonly after: V;
14
- } | {
15
- readonly key: K;
16
- readonly kind: 'updated';
17
- readonly before: V;
18
- readonly after: V;
19
- } | {
20
- readonly key: K;
21
- readonly kind: 'removed';
22
- readonly before: V;
23
- readonly after: undefined;
24
- };
25
- type CollectionChange<K extends string, V> = {
26
- readonly kind: 'reset';
27
- } | {
28
- readonly kind: 'incremental';
29
- readonly added: readonly Omit<Extract<CollectionEntryTransition<K, V>, {
30
- readonly kind: 'added';
31
- }>, 'before'>[];
32
- readonly updated: readonly Extract<CollectionEntryTransition<K, V>, {
33
- readonly kind: 'updated';
34
- }>[];
35
- readonly removed: readonly Omit<Extract<CollectionEntryTransition<K, V>, {
36
- readonly kind: 'removed';
37
- }>, 'after'>[];
38
- readonly order?: {
39
- readonly before: readonly K[];
40
- readonly after: readonly K[];
41
- };
42
- };
43
- type CollectionRead<K extends string, V> = {
44
- get(key: K): V | undefined;
45
- has(key: K): boolean;
46
- ids(): readonly K[];
47
- };
48
- type ExternalCollectionRead<K extends string, V> = {
49
- readonly get: (key: K) => V | undefined;
50
- readonly has: (key: K) => boolean;
51
- readonly ids: () => readonly K[];
52
- };
53
- type ExternalValueSource<T, D = unknown> = {
54
- readonly kind: 'value';
55
- current(): T;
56
- revision(): number;
57
- subscribe(listener: (event: ExternalValueEvent<T, D>) => void): Unsubscribe;
58
- };
59
- type ExternalCollectionSource<K extends string, V, D = unknown> = {
60
- readonly kind: 'collection';
61
- current(): ExternalCollectionRead<K, V>;
62
- revision(): number;
63
- subscribe(listener: (event: ExternalCollectionEvent<K, V, D>) => void): Unsubscribe;
64
- };
65
- type ExternalValueEvent<T, D = unknown> = {
66
- readonly value: T;
67
- readonly revision: number;
68
- readonly reset?: boolean;
69
- readonly detail?: D;
70
- readonly cause?: Cause;
71
- readonly batch?: {
72
- readonly id: number;
73
- readonly cause?: Cause;
74
- };
75
- };
76
- type ExternalCollectionEvent<K extends string, V, D = unknown> = {
77
- readonly previous: ExternalCollectionRead<K, V>;
78
- readonly revision: number;
79
- readonly reset?: boolean;
80
- readonly change?: CollectionImpact<K>;
81
- readonly detail?: D;
82
- readonly cause?: Cause;
83
- readonly batch?: {
84
- readonly id: number;
85
- readonly cause?: Cause;
86
- };
87
- };
88
- type CollectionDraft<K extends string, V> = {
89
- set(key: K, value: V): void;
90
- remove(key: K): void;
91
- order(ids: readonly K[]): void;
92
- replace(entries: readonly (readonly [K, V])[]): void;
93
- };
94
- declare class ProjectionError extends Error {
95
- readonly phase: 'processor' | 'listener' | 'source' | 'blocked';
96
- readonly identity: string;
97
- readonly revisions: readonly number[];
98
- constructor(phase: 'processor' | 'listener' | 'source' | 'blocked', identity: string, revisions: readonly number[], cause: unknown);
99
- }
100
- declare class ProjectionDisposedError extends Error {
101
- constructor();
102
- }
103
- //#endregion
104
- //#region core/src/projection/definition.d.ts
105
- declare const projectionDefinition: unique symbol;
106
- declare const projectionChanges: unique symbol;
107
- declare const writableInput: unique symbol;
108
- /** A lazy, reusable projection definition. Its value is materialized per runtime. */
109
- type Projection<T, C = undefined> = {
110
- readonly [projectionDefinition]: T;
111
- readonly [projectionChanges]: C;
112
- };
113
- /** A runtime-local writable projection definition. */
114
- type Input<T> = Projection<T> & {
115
- readonly [writableInput]: true;
116
- };
117
- type ProjectionValues<D extends readonly Projection<unknown, unknown>[]> = { readonly [K in keyof D]: D[K] extends Projection<infer T, unknown> ? T : never };
118
- type ProjectionChanges<D extends readonly Projection<unknown, unknown>[]> = { readonly [K in keyof D]: D[K] extends Projection<unknown, infer C> ? [C] extends [undefined] ? undefined : C | undefined : undefined };
119
- type PublicCollection<K extends string, V> = ReadonlyMap<K, V>;
120
- type CollectionProjection<K extends string, V> = Projection<PublicCollection<K, V>, CollectionChange<K, V>>;
121
- declare const input: <T>(initial: T, equality?: (previous: T, next: T) => boolean) => Input<T>;
122
- /**
123
- * Establishes a reactive boundary from a document, readable, or external
124
- * source. The selector is compiled when the definition is materialized, so
125
- * declarations stay lazy and reusable.
126
- */
127
- declare function observe<S extends ObjectNode>(document: DocumentReadable<S>): Projection<Infer<S>>;
128
- declare function observe<T, D>(source: ExternalValueSource<T, D>): Projection<T>;
129
- declare function observe<K extends string, V, D>(source: ExternalCollectionSource<K, V, D>): CollectionProjection<K, V>;
130
- declare function observe<T>(readable: Readable<T>): Projection<T>;
131
- declare function observe<S extends ObjectNode, P extends CollectionPath>(document: DocumentReadable<S>, selector: (path: SchemaPath<S['shape']>) => P): CollectionProjection<CollectionId<P>, ReadonlyValue<Infer<CollectionNode<P>>>>;
132
- declare function observe<S extends ObjectNode, P>(document: DocumentReadable<S>, selector: (path: SchemaPath<S['shape']>) => P): Projection<PathValueOf<P>>;
133
- declare function derive<const D extends readonly Projection<unknown, unknown>[], T>(dependencies: D, compute: (...values: ProjectionValues<D>) => Synchronous<T>, equality?: (previous: T, next: T) => boolean): Projection<T>;
134
- //#endregion
135
- export { ExternalValueEvent as _, ProjectionValues as a, ProjectionError as b, input as c, CollectionChange as d, CollectionDraft as f, ExternalCollectionSource as g, ExternalCollectionRead as h, ProjectionChanges as i, observe as l, ExternalCollectionEvent as m, Input as n, PublicCollection as o, CollectionRead as p, Projection as r, derive as s, CollectionProjection as t, BatchOptions as u, ExternalValueSource as v, ProjectionDisposedError as y };
136
- //# sourceMappingURL=definition-C__VJqA4.d.cts.map
@@ -1,136 +0,0 @@
1
- import { J as Infer, L as CollectionId, R as CollectionNode, Z as ObjectNode, _ as Unsubscribe, et as PathValueOf, m as Synchronous, nt as SchemaPath, s as DocumentReadable, tt as ReadonlyValue, v as Readable, x as CollectionImpact, z as CollectionPath } from "./contract-CATCCVu5.js";
2
-
3
- //#region core/src/projection/contract.d.ts
4
- /** Opaque application metadata identifying the action that produced a source event. */
5
- type Cause = unknown;
6
- type BatchOptions = {
7
- readonly cause?: Cause;
8
- };
9
- type CollectionEntryTransition<K extends string, V> = {
10
- readonly key: K;
11
- readonly kind: 'added';
12
- readonly before: undefined;
13
- readonly after: V;
14
- } | {
15
- readonly key: K;
16
- readonly kind: 'updated';
17
- readonly before: V;
18
- readonly after: V;
19
- } | {
20
- readonly key: K;
21
- readonly kind: 'removed';
22
- readonly before: V;
23
- readonly after: undefined;
24
- };
25
- type CollectionChange<K extends string, V> = {
26
- readonly kind: 'reset';
27
- } | {
28
- readonly kind: 'incremental';
29
- readonly added: readonly Omit<Extract<CollectionEntryTransition<K, V>, {
30
- readonly kind: 'added';
31
- }>, 'before'>[];
32
- readonly updated: readonly Extract<CollectionEntryTransition<K, V>, {
33
- readonly kind: 'updated';
34
- }>[];
35
- readonly removed: readonly Omit<Extract<CollectionEntryTransition<K, V>, {
36
- readonly kind: 'removed';
37
- }>, 'after'>[];
38
- readonly order?: {
39
- readonly before: readonly K[];
40
- readonly after: readonly K[];
41
- };
42
- };
43
- type CollectionRead<K extends string, V> = {
44
- get(key: K): V | undefined;
45
- has(key: K): boolean;
46
- ids(): readonly K[];
47
- };
48
- type ExternalCollectionRead<K extends string, V> = {
49
- readonly get: (key: K) => V | undefined;
50
- readonly has: (key: K) => boolean;
51
- readonly ids: () => readonly K[];
52
- };
53
- type ExternalValueSource<T, D = unknown> = {
54
- readonly kind: 'value';
55
- current(): T;
56
- revision(): number;
57
- subscribe(listener: (event: ExternalValueEvent<T, D>) => void): Unsubscribe;
58
- };
59
- type ExternalCollectionSource<K extends string, V, D = unknown> = {
60
- readonly kind: 'collection';
61
- current(): ExternalCollectionRead<K, V>;
62
- revision(): number;
63
- subscribe(listener: (event: ExternalCollectionEvent<K, V, D>) => void): Unsubscribe;
64
- };
65
- type ExternalValueEvent<T, D = unknown> = {
66
- readonly value: T;
67
- readonly revision: number;
68
- readonly reset?: boolean;
69
- readonly detail?: D;
70
- readonly cause?: Cause;
71
- readonly batch?: {
72
- readonly id: number;
73
- readonly cause?: Cause;
74
- };
75
- };
76
- type ExternalCollectionEvent<K extends string, V, D = unknown> = {
77
- readonly previous: ExternalCollectionRead<K, V>;
78
- readonly revision: number;
79
- readonly reset?: boolean;
80
- readonly change?: CollectionImpact<K>;
81
- readonly detail?: D;
82
- readonly cause?: Cause;
83
- readonly batch?: {
84
- readonly id: number;
85
- readonly cause?: Cause;
86
- };
87
- };
88
- type CollectionDraft<K extends string, V> = {
89
- set(key: K, value: V): void;
90
- remove(key: K): void;
91
- order(ids: readonly K[]): void;
92
- replace(entries: readonly (readonly [K, V])[]): void;
93
- };
94
- declare class ProjectionError extends Error {
95
- readonly phase: 'processor' | 'listener' | 'source' | 'blocked';
96
- readonly identity: string;
97
- readonly revisions: readonly number[];
98
- constructor(phase: 'processor' | 'listener' | 'source' | 'blocked', identity: string, revisions: readonly number[], cause: unknown);
99
- }
100
- declare class ProjectionDisposedError extends Error {
101
- constructor();
102
- }
103
- //#endregion
104
- //#region core/src/projection/definition.d.ts
105
- declare const projectionDefinition: unique symbol;
106
- declare const projectionChanges: unique symbol;
107
- declare const writableInput: unique symbol;
108
- /** A lazy, reusable projection definition. Its value is materialized per runtime. */
109
- type Projection<T, C = undefined> = {
110
- readonly [projectionDefinition]: T;
111
- readonly [projectionChanges]: C;
112
- };
113
- /** A runtime-local writable projection definition. */
114
- type Input<T> = Projection<T> & {
115
- readonly [writableInput]: true;
116
- };
117
- type ProjectionValues<D extends readonly Projection<unknown, unknown>[]> = { readonly [K in keyof D]: D[K] extends Projection<infer T, unknown> ? T : never };
118
- type ProjectionChanges<D extends readonly Projection<unknown, unknown>[]> = { readonly [K in keyof D]: D[K] extends Projection<unknown, infer C> ? [C] extends [undefined] ? undefined : C | undefined : undefined };
119
- type PublicCollection<K extends string, V> = ReadonlyMap<K, V>;
120
- type CollectionProjection<K extends string, V> = Projection<PublicCollection<K, V>, CollectionChange<K, V>>;
121
- declare const input: <T>(initial: T, equality?: (previous: T, next: T) => boolean) => Input<T>;
122
- /**
123
- * Establishes a reactive boundary from a document, readable, or external
124
- * source. The selector is compiled when the definition is materialized, so
125
- * declarations stay lazy and reusable.
126
- */
127
- declare function observe<S extends ObjectNode>(document: DocumentReadable<S>): Projection<Infer<S>>;
128
- declare function observe<T, D>(source: ExternalValueSource<T, D>): Projection<T>;
129
- declare function observe<K extends string, V, D>(source: ExternalCollectionSource<K, V, D>): CollectionProjection<K, V>;
130
- declare function observe<T>(readable: Readable<T>): Projection<T>;
131
- declare function observe<S extends ObjectNode, P extends CollectionPath>(document: DocumentReadable<S>, selector: (path: SchemaPath<S['shape']>) => P): CollectionProjection<CollectionId<P>, ReadonlyValue<Infer<CollectionNode<P>>>>;
132
- declare function observe<S extends ObjectNode, P>(document: DocumentReadable<S>, selector: (path: SchemaPath<S['shape']>) => P): Projection<PathValueOf<P>>;
133
- declare function derive<const D extends readonly Projection<unknown, unknown>[], T>(dependencies: D, compute: (...values: ProjectionValues<D>) => Synchronous<T>, equality?: (previous: T, next: T) => boolean): Projection<T>;
134
- //#endregion
135
- export { ExternalValueEvent as _, ProjectionValues as a, ProjectionError as b, input as c, CollectionChange as d, CollectionDraft as f, ExternalCollectionSource as g, ExternalCollectionRead as h, ProjectionChanges as i, observe as l, ExternalCollectionEvent as m, Input as n, PublicCollection as o, CollectionRead as p, Projection as r, derive as s, CollectionProjection as t, BatchOptions as u, ExternalValueSource as v, ProjectionDisposedError as y };
136
- //# sourceMappingURL=definition-Dc1Udkop.d.ts.map