doxum 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +217 -296
- package/dist/contract-BNStLbSE.d.ts +441 -0
- package/dist/contract-CIU5FCC1.d.cts +441 -0
- package/dist/driver-BlR81Dqg.js +200 -0
- package/dist/driver-BlR81Dqg.js.map +1 -0
- package/dist/driver-xOIkwrB8.cjs +241 -0
- package/dist/driver-xOIkwrB8.cjs.map +1 -0
- package/dist/index.cjs +666 -2222
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -20
- package/dist/index.d.ts +10 -18
- package/dist/index.js +634 -2189
- package/dist/index.js.map +1 -1
- package/dist/{integration-CZwCwFBS.cjs → integration-C87tjRop.cjs} +4 -9
- package/dist/integration-C87tjRop.cjs.map +1 -0
- package/dist/{integration-B56u1l9V.js → integration-D5XCBLJ8.js} +2 -7
- package/dist/integration-D5XCBLJ8.js.map +1 -0
- package/dist/integration.cjs +11 -11
- package/dist/integration.d.cts +10 -4
- package/dist/integration.d.ts +10 -4
- package/dist/integration.js +4 -3
- package/dist/issue-DVaGQGeP.js +576 -0
- package/dist/issue-DVaGQGeP.js.map +1 -0
- package/dist/issue-DhrNdQNg.cjs +797 -0
- package/dist/issue-DhrNdQNg.cjs.map +1 -0
- package/dist/local-sync.cjs +67 -39
- package/dist/local-sync.cjs.map +1 -1
- package/dist/local-sync.d.cts +10 -10
- package/dist/local-sync.d.ts +10 -10
- package/dist/local-sync.js +66 -38
- package/dist/local-sync.js.map +1 -1
- package/dist/react.cjs +23 -4
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +8 -3
- package/dist/react.d.ts +8 -3
- package/dist/react.js +21 -6
- package/dist/react.js.map +1 -1
- package/dist/store-1Uob0Ghk.cjs +2750 -0
- package/dist/store-1Uob0Ghk.cjs.map +1 -0
- package/dist/store-CD0KdGsq.d.cts +262 -0
- package/dist/store-D7QH6Rzw.js +2511 -0
- package/dist/store-D7QH6Rzw.js.map +1 -0
- package/dist/store-cp5CpfCy.d.ts +262 -0
- package/package.json +1 -1
- package/skills/doxum-runtime/SKILL.md +26 -44
- package/skills/doxum-runtime/references/guide.en.md +95 -359
- package/skills/doxum-runtime/references/guide.zh-CN.md +80 -285
- package/skills/doxum-runtime/references/invariants.en.md +42 -165
- package/skills/doxum-runtime/references/invariants.zh-CN.md +34 -97
- package/skills/doxum-runtime/references/patterns.en.md +73 -225
- package/skills/doxum-runtime/references/patterns.zh-CN.md +73 -179
- package/dist/chunk-pbuEa-1d.js +0 -13
- package/dist/contract-DNZ4D53r.d.ts +0 -563
- package/dist/contract-j3SLGAwh.d.cts +0 -563
- package/dist/driver-CNxqMVFH.cjs +0 -69
- package/dist/driver-CNxqMVFH.cjs.map +0 -1
- package/dist/driver-CbzfW5MR.js +0 -46
- package/dist/driver-CbzfW5MR.js.map +0 -1
- package/dist/integration-B56u1l9V.js.map +0 -1
- package/dist/integration-CZwCwFBS.cjs.map +0 -1
- package/dist/ownership-CY0nPXGF.cjs +0 -304
- package/dist/ownership-CY0nPXGF.cjs.map +0 -1
- package/dist/ownership-CduRygE7.js +0 -245
- package/dist/ownership-CduRygE7.js.map +0 -1
- package/dist/runtime-0mOFbe_H.cjs +0 -2439
- package/dist/runtime-0mOFbe_H.cjs.map +0 -1
- package/dist/runtime-B22tuj9A.d.cts +0 -150
- package/dist/runtime-BFmhzPpZ.d.ts +0 -150
- package/dist/runtime-DF1q9Gje.js +0 -2129
- package/dist/runtime-DF1q9Gje.js.map +0 -1
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { B as CollectionPath, C as CollectionAccess, Q as ObjectNode, R as CollectionId, T as Read, _ as Unsubscribe, m as Synchronous, ot as ValueSchemaNode, r as DocumentCommit, rt as SchemaPath, s as DocumentReadable, tt as PathPick, v as Readable, x as CollectionImpact, z as CollectionNode } from "./contract-BNStLbSE.js";
|
|
2
|
+
|
|
3
|
+
//#region core/src/projection/contract.d.ts
|
|
4
|
+
declare const sourceContext: unique symbol;
|
|
5
|
+
type EngineSource<T> = {
|
|
6
|
+
readonly [sourceContext]: T;
|
|
7
|
+
};
|
|
8
|
+
type EngineSources = Readonly<Record<string, EngineSource<unknown>>>;
|
|
9
|
+
type EngineInputs<S extends EngineSources> = { readonly [K in keyof S]: S[K] extends EngineSource<infer T> ? T : never };
|
|
10
|
+
type DocumentInput<S extends ObjectNode> = {
|
|
11
|
+
readonly read: Read<S>;
|
|
12
|
+
readonly revision: number;
|
|
13
|
+
readonly commits: readonly DocumentCommit<S>[];
|
|
14
|
+
readonly reset: boolean;
|
|
15
|
+
};
|
|
16
|
+
type DocumentCollectionInput<S extends ObjectNode, N extends ValueSchemaNode, K extends string = string> = {
|
|
17
|
+
readonly read: CollectionAccess<K, N>;
|
|
18
|
+
readonly revision: number;
|
|
19
|
+
readonly commits: readonly DocumentCommit<S>[];
|
|
20
|
+
readonly reset: boolean;
|
|
21
|
+
readonly candidates: {
|
|
22
|
+
readonly keys: readonly K[];
|
|
23
|
+
readonly orderDirty: boolean;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
type DocumentSource<S extends ObjectNode> = EngineSource<DocumentInput<S>> & {
|
|
27
|
+
collection<P extends CollectionPath>(pick: (path: SchemaPath<S['shape']>) => P): DocumentCollectionSource<S, CollectionNode<P>, CollectionId<P>>;
|
|
28
|
+
targets(...targets: readonly [PathPick<S>, ...PathPick<S>[]]): EngineSource<DocumentInput<S>>;
|
|
29
|
+
};
|
|
30
|
+
type DocumentCollectionSource<S extends ObjectNode, N extends ValueSchemaNode, K extends string = string> = EngineSource<DocumentCollectionInput<S, N, K>>;
|
|
31
|
+
type ValueInput<T> = {
|
|
32
|
+
readonly value: T;
|
|
33
|
+
readonly previous: T;
|
|
34
|
+
readonly changed: boolean;
|
|
35
|
+
readonly revision: number;
|
|
36
|
+
readonly reset: boolean;
|
|
37
|
+
};
|
|
38
|
+
type EngineInput<T> = {
|
|
39
|
+
readonly source: EngineSource<ValueInput<T>>;
|
|
40
|
+
set(value: T): void;
|
|
41
|
+
};
|
|
42
|
+
type ValueUpdate<T> = {
|
|
43
|
+
readonly kind: 'unchanged';
|
|
44
|
+
} | {
|
|
45
|
+
readonly kind: 'changed';
|
|
46
|
+
readonly value: T;
|
|
47
|
+
} | {
|
|
48
|
+
readonly kind: 'rebuild';
|
|
49
|
+
};
|
|
50
|
+
type EngineValueSpec<S extends EngineSources, T> = {
|
|
51
|
+
readonly name?: string;
|
|
52
|
+
readonly sources: S;
|
|
53
|
+
readonly build: (sources: EngineInputs<S>) => {
|
|
54
|
+
readonly value: T;
|
|
55
|
+
readonly update: (sources: EngineInputs<S>) => ValueUpdate<NoInfer<T>>;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
type MaterializedValue<T> = Readable<T> & EngineSource<ValueInput<T>> & {
|
|
59
|
+
rebuild(): void;
|
|
60
|
+
dispose(): void;
|
|
61
|
+
};
|
|
62
|
+
type CollectionRead<K extends string, V> = {
|
|
63
|
+
get(key: K): V | undefined;
|
|
64
|
+
has(key: K): boolean;
|
|
65
|
+
ids(): readonly K[];
|
|
66
|
+
};
|
|
67
|
+
type CollectionInput<K extends string, V> = CollectionRead<K, V> & {
|
|
68
|
+
readonly change: CollectionImpact<K> | undefined;
|
|
69
|
+
readonly revision: number;
|
|
70
|
+
readonly reset: boolean;
|
|
71
|
+
};
|
|
72
|
+
type MaterializedCollection<K extends string, V> = EngineSource<CollectionInput<K, V>> & {
|
|
73
|
+
current(): CollectionRead<K, V>;
|
|
74
|
+
readonly ids: Readable<readonly K[]>;
|
|
75
|
+
readonly all: Readable<readonly V[]>;
|
|
76
|
+
item(key: K): Readable<V | undefined>;
|
|
77
|
+
revision(): number;
|
|
78
|
+
subscribe(listener: (change: CollectionImpact<K>) => void): Unsubscribe;
|
|
79
|
+
rebuild(): void;
|
|
80
|
+
dispose(): void;
|
|
81
|
+
};
|
|
82
|
+
type MaterializedCollectionWriter<K extends string, V> = {
|
|
83
|
+
set(key: K, value: V): void;
|
|
84
|
+
remove(key: K): void;
|
|
85
|
+
order(ids: readonly K[]): void;
|
|
86
|
+
replace(entries: readonly (readonly [K, V])[]): void;
|
|
87
|
+
};
|
|
88
|
+
type EngineCollectionProcess<S extends EngineSources, K extends string, V> = {
|
|
89
|
+
readonly sources: EngineInputs<S>;
|
|
90
|
+
readonly previous: CollectionRead<K, V>;
|
|
91
|
+
readonly next: CollectionRead<K, V>;
|
|
92
|
+
readonly writer: MaterializedCollectionWriter<K, V>;
|
|
93
|
+
};
|
|
94
|
+
type EngineCollectionSpec<S extends EngineSources, K extends string, V> = {
|
|
95
|
+
readonly name?: string;
|
|
96
|
+
readonly sources: S;
|
|
97
|
+
readonly isEqual?: (previous: V, next: V) => boolean;
|
|
98
|
+
readonly build: (input: EngineCollectionProcess<S, K, V>) => {
|
|
99
|
+
readonly update: (input: EngineCollectionProcess<S, K, V>) => void | {
|
|
100
|
+
readonly kind: 'rebuild';
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
declare class ProjectionError extends Error {
|
|
105
|
+
readonly phase: 'processor' | 'listener' | 'source' | 'blocked';
|
|
106
|
+
readonly identity: string;
|
|
107
|
+
readonly revisions: readonly number[];
|
|
108
|
+
constructor(phase: 'processor' | 'listener' | 'source' | 'blocked', identity: string, revisions: readonly number[], cause: unknown);
|
|
109
|
+
}
|
|
110
|
+
declare class ProjectionDisposedError extends Error {
|
|
111
|
+
constructor();
|
|
112
|
+
}
|
|
113
|
+
type ProjectionEngine = {
|
|
114
|
+
document<S extends ObjectNode>(runtime: DocumentReadable<S>): DocumentSource<S>;
|
|
115
|
+
fromReadable<T>(readable: Readable<T>, options?: {
|
|
116
|
+
readonly isEqual?: (a: T, b: T) => boolean;
|
|
117
|
+
}): EngineSource<ValueInput<T>>;
|
|
118
|
+
input<T>(initial: T, options?: {
|
|
119
|
+
readonly isEqual?: (a: T, b: T) => boolean;
|
|
120
|
+
}): EngineInput<T>;
|
|
121
|
+
value<S extends EngineSources, T>(sources: S, compute: (sources: EngineInputs<S>) => Synchronous<T>, options?: {
|
|
122
|
+
readonly isEqual?: (a: NoInfer<T>, b: NoInfer<T>) => boolean;
|
|
123
|
+
}): MaterializedValue<T>;
|
|
124
|
+
value<S extends EngineSources, T>(spec: EngineValueSpec<S, T>, options?: {
|
|
125
|
+
readonly isEqual?: (a: NoInfer<T>, b: NoInfer<T>) => boolean;
|
|
126
|
+
}): MaterializedValue<T>;
|
|
127
|
+
collection<V, K extends string = string>(): <S extends EngineSources>(spec: EngineCollectionSpec<S, K, V>) => MaterializedCollection<K, V>;
|
|
128
|
+
map<S extends ObjectNode, N extends ValueSchemaNode, K extends string, V>(source: DocumentCollectionSource<S, N, K>, mapper: (id: K, entry: Read<N>) => Synchronous<V>, options?: {
|
|
129
|
+
readonly isEqual?: (a: V, b: V) => boolean;
|
|
130
|
+
}): MaterializedCollection<K, V>;
|
|
131
|
+
map<K extends string, V, R>(source: MaterializedCollection<K, V>, mapper: (id: K, entry: V) => Synchronous<R>, options?: {
|
|
132
|
+
readonly isEqual?: (a: NoInfer<R>, b: NoInfer<R>) => boolean;
|
|
133
|
+
}): MaterializedCollection<K, R>;
|
|
134
|
+
batch<T>(run: () => Synchronous<T>): T;
|
|
135
|
+
dispose(): void;
|
|
136
|
+
};
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region core/src/projection/definition.d.ts
|
|
139
|
+
declare const projectionDefinition: unique symbol;
|
|
140
|
+
declare const writableInput: unique symbol;
|
|
141
|
+
type Projection<T, E = T, K extends 'source' | 'value' | 'collection' = 'source' | 'value' | 'collection'> = {
|
|
142
|
+
readonly [projectionDefinition]: {
|
|
143
|
+
readonly value: T;
|
|
144
|
+
readonly event: E;
|
|
145
|
+
readonly kind: K;
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
type ProjectionSources = Readonly<Record<string, Projection<unknown, unknown, 'source' | 'value' | 'collection'>>>;
|
|
149
|
+
type ProjectionValues<S extends ProjectionSources> = { readonly [K in keyof S]: S[K] extends Projection<infer T, unknown, 'source' | 'value' | 'collection'> ? T : never };
|
|
150
|
+
type ProjectionEvents<S extends ProjectionSources> = { readonly [K in keyof S]: S[K] extends Projection<unknown, infer E, 'source' | 'value' | 'collection'> ? E : never };
|
|
151
|
+
type ValueProjection<T, E = ValueEvent<T>> = Projection<T, E, 'value'>;
|
|
152
|
+
type InputProjection<T> = ValueProjection<T> & {
|
|
153
|
+
readonly [writableInput]: true;
|
|
154
|
+
};
|
|
155
|
+
type CollectionProjection<K extends string, V, E = CollectionEvent<K, V>> = Projection<CollectionRead<K, V>, E, 'collection'>;
|
|
156
|
+
type CollectionSource<K extends string, V, E> = Projection<CollectionRead<K, V>, E, 'source'>;
|
|
157
|
+
type DocumentProjection<S extends ObjectNode> = Projection<Read<S>, DocumentEvent<S>, 'source'>;
|
|
158
|
+
type DocumentCollectionProjection<S extends ObjectNode, N extends ValueSchemaNode, K extends string = string> = CollectionSource<K, Read<N>, DocumentCollectionEvent<S, N, K>>;
|
|
159
|
+
type ValueEvent<T> = {
|
|
160
|
+
readonly value: T;
|
|
161
|
+
readonly previous: T;
|
|
162
|
+
readonly changed: boolean;
|
|
163
|
+
readonly revision: number;
|
|
164
|
+
readonly reset: boolean;
|
|
165
|
+
};
|
|
166
|
+
type DocumentEvent<S extends ObjectNode> = {
|
|
167
|
+
readonly read: Read<S>;
|
|
168
|
+
readonly revision: number;
|
|
169
|
+
readonly commits: readonly DocumentCommit<S>[];
|
|
170
|
+
readonly reset: boolean;
|
|
171
|
+
};
|
|
172
|
+
type DocumentCollectionEvent<S extends ObjectNode, N extends ValueSchemaNode, K extends string = string> = {
|
|
173
|
+
readonly read: CollectionAccess<K, N>;
|
|
174
|
+
readonly revision: number;
|
|
175
|
+
readonly commits: readonly DocumentCommit<S>[];
|
|
176
|
+
readonly reset: boolean;
|
|
177
|
+
readonly candidates: {
|
|
178
|
+
readonly keys: readonly K[];
|
|
179
|
+
readonly orderDirty: boolean;
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
type CollectionEvent<K extends string, V> = CollectionRead<K, V> & {
|
|
183
|
+
readonly change: CollectionImpact<K> | undefined;
|
|
184
|
+
readonly revision: number;
|
|
185
|
+
readonly reset: boolean;
|
|
186
|
+
};
|
|
187
|
+
declare const input: <T>(initial: T, options?: {
|
|
188
|
+
readonly isEqual?: (a: T, b: T) => boolean;
|
|
189
|
+
}) => InputProjection<T>;
|
|
190
|
+
type AdvancedValueSpec<S extends ProjectionSources, T> = {
|
|
191
|
+
readonly kind: 'value';
|
|
192
|
+
readonly name?: string;
|
|
193
|
+
readonly sources: S;
|
|
194
|
+
readonly build: (sources: ProjectionEvents<S>) => {
|
|
195
|
+
readonly value: T;
|
|
196
|
+
readonly update: (sources: ProjectionEvents<S>) => ValueUpdate<NoInfer<T>>;
|
|
197
|
+
};
|
|
198
|
+
readonly isEqual?: (previous: T, next: T) => boolean;
|
|
199
|
+
};
|
|
200
|
+
type AdvancedCollectionSpec<S extends ProjectionSources, K extends string, V> = {
|
|
201
|
+
readonly kind: 'collection';
|
|
202
|
+
readonly name?: string;
|
|
203
|
+
readonly sources: S;
|
|
204
|
+
readonly build: (input: AdvancedCollectionProcess<S, K, V>) => {
|
|
205
|
+
readonly update: (input: AdvancedCollectionProcess<S, K, V>) => void | {
|
|
206
|
+
readonly kind: 'rebuild';
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
readonly isEqual?: (previous: V, next: V) => boolean;
|
|
210
|
+
};
|
|
211
|
+
type AdvancedCollectionProcess<S extends ProjectionSources, K extends string, V> = {
|
|
212
|
+
readonly sources: ProjectionEvents<S>;
|
|
213
|
+
readonly previous: CollectionRead<K, V>;
|
|
214
|
+
readonly next: CollectionRead<K, V>;
|
|
215
|
+
readonly writer: MaterializedCollectionWriter<K, V>;
|
|
216
|
+
};
|
|
217
|
+
declare function project<T>(readable: Readable<T>): ValueProjection<T>;
|
|
218
|
+
declare function project<S extends ObjectNode>(document: DocumentReadable<S>): DocumentProjection<S>;
|
|
219
|
+
declare function project<S extends ObjectNode>(document: DocumentReadable<S>, targets: readonly [PathPick<S>, ...PathPick<S>[]]): DocumentProjection<S>;
|
|
220
|
+
declare function project<S extends ObjectNode, P extends CollectionPath>(document: DocumentReadable<S>, pick: (path: SchemaPath<S['shape']>) => P): DocumentCollectionProjection<S, CollectionNode<P>, CollectionId<P>>;
|
|
221
|
+
declare function project<S extends ObjectNode, P extends CollectionPath, V>(document: DocumentReadable<S>, pick: (path: SchemaPath<S['shape']>) => P, mapper: (id: CollectionId<P>, entry: Read<CollectionNode<P>>) => Synchronous<V>, options?: {
|
|
222
|
+
readonly isEqual?: (a: V, b: V) => boolean;
|
|
223
|
+
}): CollectionProjection<CollectionId<P>, V>;
|
|
224
|
+
declare function project<K extends string, V, E, R>(source: Projection<CollectionRead<K, V>, E, 'source' | 'collection'>, mapper: (id: K, entry: V) => Synchronous<R>, options?: {
|
|
225
|
+
readonly isEqual?: (a: R, b: R) => boolean;
|
|
226
|
+
}): CollectionProjection<K, R>;
|
|
227
|
+
declare function project<S extends ProjectionSources, T>(sources: S, compute: (sources: ProjectionValues<S>) => Synchronous<T>, options?: {
|
|
228
|
+
readonly isEqual?: (a: T, b: T) => boolean;
|
|
229
|
+
}): ValueProjection<T>;
|
|
230
|
+
declare function project<S extends ProjectionSources, T>(spec: AdvancedValueSpec<S, T>): ValueProjection<T>;
|
|
231
|
+
declare function project<V, K extends string = string, S extends ProjectionSources = ProjectionSources>(spec: AdvancedCollectionSpec<S, K, V>): CollectionProjection<K, V>;
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region core/src/projection/runtime.d.ts
|
|
234
|
+
declare const createProjectionEngine: (options: {
|
|
235
|
+
readonly onError: (error: ProjectionError) => void;
|
|
236
|
+
}) => ProjectionEngine;
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region core/src/projection/store.d.ts
|
|
239
|
+
type ProjectionStore = {
|
|
240
|
+
get<K extends string, V>(projection: CollectionProjection<K, V>): CollectionRead<K, V>;
|
|
241
|
+
get<T>(projection: ValueProjection<T>): T;
|
|
242
|
+
set<T>(projection: InputProjection<T>, value: T): void;
|
|
243
|
+
subscribe<K extends string, V>(projection: CollectionProjection<K, V>, listener: (change: CollectionImpact<K>) => void): Unsubscribe;
|
|
244
|
+
subscribe<T>(projection: ValueProjection<T>, listener: () => void): Unsubscribe;
|
|
245
|
+
revision(projection: ValueProjection<unknown> | CollectionProjection<string, unknown>): number;
|
|
246
|
+
rebuild(projection: ValueProjection<unknown> | CollectionProjection<string, unknown>): void;
|
|
247
|
+
release(projection: ValueProjection<unknown> | CollectionProjection<string, unknown>): void;
|
|
248
|
+
batch<T>(run: () => T): T;
|
|
249
|
+
dispose(): void;
|
|
250
|
+
};
|
|
251
|
+
declare const projectionStoreDebug: (store: ProjectionStore) => Readonly<{
|
|
252
|
+
nodes: number;
|
|
253
|
+
sources: number;
|
|
254
|
+
subscriptions: number;
|
|
255
|
+
pending: number;
|
|
256
|
+
}>;
|
|
257
|
+
declare const createProjectionStore: (options: {
|
|
258
|
+
readonly onError: Parameters<typeof createProjectionEngine>[0]["onError"];
|
|
259
|
+
}) => ProjectionStore;
|
|
260
|
+
//#endregion
|
|
261
|
+
export { ProjectionDisposedError as C, project as S, ProjectionSources as _, AdvancedCollectionSpec as a, ValueProjection as b, CollectionProjection as c, DocumentCollectionProjection as d, DocumentEvent as f, ProjectionEvents as g, Projection as h, AdvancedCollectionProcess as i, CollectionSource as l, InputProjection as m, createProjectionStore as n, AdvancedValueSpec as o, DocumentProjection as p, projectionStoreDebug as r, CollectionEvent as s, ProjectionStore as t, DocumentCollectionEvent as u, ProjectionValues as v, ProjectionError as w, input as x, ValueEvent as y };
|
|
262
|
+
//# sourceMappingURL=store-cp5CpfCy.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,52 +1,34 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: doxum-runtime
|
|
3
|
-
description: 'Use doxum and doxum/react
|
|
3
|
+
description: 'Use doxum and doxum/react for schemas, scoped draft updates, ChangeSets, history, projections, subscriptions and React integration.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Doxum Runtime
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
application happens to contain a Doxum runtime.
|
|
8
|
+
Read the [English guide](references/guide.en.md) or [中文指南](references/guide.zh-CN.md).
|
|
9
|
+
For examples read [patterns](references/patterns.en.md) or [中文模式](references/patterns.zh-CN.md).
|
|
10
|
+
Before runtime changes read [invariants](references/invariants.en.md) or
|
|
11
|
+
[中文不变量](references/invariants.zh-CN.md).
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
- Root object defines schema identity; Infer describes readonly data with shared immutable payloads.
|
|
14
|
+
- createDocument owns canonical state. update, apply and replace share one session.
|
|
15
|
+
- Draft and trusted internal readWith scopes are borrowed for synchronous callbacks;
|
|
16
|
+
their proxies must not escape. Public values should use snapshot when they need to
|
|
17
|
+
outlive the callback.
|
|
18
|
+
- Atomic fields are deeply readonly during access and replaced whole.
|
|
19
|
+
- Use assign(scope, key, value) for replacements containing nested collection tools.
|
|
20
|
+
- Expected business failure throws TransactionRejected. Other exceptions roll back
|
|
21
|
+
and rethrow unchanged. Callback returns carry business values and notices.
|
|
22
|
+
- Commits contain final reversible ChangeSets. History and impact share those facts.
|
|
23
|
+
- ChangeSets group member transitions by container, with explicit added/removed/updated
|
|
24
|
+
kinds, optional before/after order in the same group, and a separate root reset.
|
|
25
|
+
Standalone order records and duplicate groups are invalid. Grouping preserves field-level impact.
|
|
26
|
+
- Paths belong in subscription, impact and collection source callbacks.
|
|
27
|
+
- Projection dependencies are explicit; React selectors track actual reads.
|
|
28
|
+
- Observer errors leave commits accepted. Do not retry as if they rolled back.
|
|
29
|
+
- Core stays framework-neutral; adapters use integration capabilities.
|
|
30
|
+
- Local sync owns browser persistence/leadership. Network conflict policy and
|
|
31
|
+
collaborative undo belong at a separate boundary.
|
|
15
32
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
equivalent task-oriented introductions.
|
|
19
|
-
- Read [the English patterns](references/patterns.en.md) or
|
|
20
|
-
[中文模式参考](references/patterns.zh-CN.md) when implementing schema models,
|
|
21
|
-
transactions, replay, selectors, views, or React code.
|
|
22
|
-
- Read [the English invariants](references/invariants.en.md) or
|
|
23
|
-
[中文不变量](references/invariants.zh-CN.md) before changing mutation,
|
|
24
|
-
addressing, impact, notification, history, tree, or derived-view behavior.
|
|
25
|
-
|
|
26
|
-
## Required Doxum decisions
|
|
27
|
-
|
|
28
|
-
- Treat `createDocument` as the only write authority for canonical document
|
|
29
|
-
state. Application writes use `runtime.update`; replayed external operations
|
|
30
|
-
use `runtime.apply`.
|
|
31
|
-
- A transaction is synchronous and atomic. Do not retain a transaction reader
|
|
32
|
-
or writer after its callback returns, and do not introduce another writable
|
|
33
|
-
state cache.
|
|
34
|
-
- Use the runtime's schema selectors, anchors, addresses, and `target` APIs.
|
|
35
|
-
Do not add local path parsers, duplicate impact-target helpers, or manually
|
|
36
|
-
synchronize derived data.
|
|
37
|
-
- Handle expected mutation failure from the returned `rejected` result and its
|
|
38
|
-
`MutationIssue` values. Use `tx.report` or `tx.reject` with
|
|
39
|
-
`{ code, message, address? }` for application validation; runtime adds the
|
|
40
|
-
application source to published `DocumentDiagnostic` values. A thrown callback error
|
|
41
|
-
rolls back and is rethrown.
|
|
42
|
-
- A committed result with `observerErrors` is still committed. Do not retry its
|
|
43
|
-
write as if canonical state had been rolled back.
|
|
44
|
-
- Keep `core` framework-neutral. React code belongs behind `doxum/react` and
|
|
45
|
-
must not make `core` import UI concepts.
|
|
46
|
-
- Doxum does not define persistence, synchronization, authorization, or
|
|
47
|
-
conflict resolution. Keep those policies in the application boundary before
|
|
48
|
-
`apply` or `replace`.
|
|
49
|
-
|
|
50
|
-
When public behavior or lifecycle semantics change, update the README and
|
|
51
|
-
architecture guide and add focused tests for rollback, inverse history, impact
|
|
52
|
-
or subscription behavior, and performance-sensitive collection or tree paths.
|
|
33
|
+
Update examples and tests when behavior changes. Never add compatibility APIs,
|
|
34
|
+
a second path grammar or another writable derived cache.
|