doxum 0.1.5 → 0.1.7
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 +75 -9
- package/dist/{contract-4E3moCbY.d.ts → contract-DNZ4D53r.d.ts} +87 -76
- package/dist/{contract-uYJTmT8o.d.cts → contract-j3SLGAwh.d.cts} +87 -76
- package/dist/index.cjs +284 -947
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -64
- package/dist/index.d.ts +3 -64
- package/dist/index.js +218 -872
- package/dist/index.js.map +1 -1
- package/dist/integration-B56u1l9V.js +30 -0
- package/dist/integration-B56u1l9V.js.map +1 -0
- package/dist/integration-CZwCwFBS.cjs +35 -0
- package/dist/integration-CZwCwFBS.cjs.map +1 -0
- package/dist/integration.cjs +12 -14
- package/dist/integration.d.cts +3 -2
- package/dist/integration.d.ts +3 -2
- package/dist/integration.js +3 -14
- package/dist/local-sync.cjs +57 -18
- package/dist/local-sync.cjs.map +1 -1
- package/dist/local-sync.d.cts +2 -2
- package/dist/local-sync.d.ts +2 -2
- package/dist/local-sync.js +57 -18
- package/dist/local-sync.js.map +1 -1
- package/dist/{ownership-CU-9DKJQ.cjs → ownership-CY0nPXGF.cjs} +4 -1
- package/dist/ownership-CY0nPXGF.cjs.map +1 -0
- package/dist/{ownership-B-VAPcce.js → ownership-CduRygE7.js} +4 -1
- package/dist/ownership-CduRygE7.js.map +1 -0
- package/dist/react.cjs +27 -19
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +27 -19
- package/dist/react.js.map +1 -1
- package/dist/runtime-0mOFbe_H.cjs +2439 -0
- package/dist/runtime-0mOFbe_H.cjs.map +1 -0
- package/dist/runtime-B22tuj9A.d.cts +150 -0
- package/dist/runtime-BFmhzPpZ.d.ts +150 -0
- package/dist/runtime-DF1q9Gje.js +2129 -0
- package/dist/runtime-DF1q9Gje.js.map +1 -0
- package/package.json +1 -1
- package/skills/doxum-runtime/SKILL.md +2 -1
- package/skills/doxum-runtime/references/guide.en.md +38 -26
- package/skills/doxum-runtime/references/guide.zh-CN.md +24 -21
- package/skills/doxum-runtime/references/invariants.en.md +13 -10
- package/skills/doxum-runtime/references/invariants.zh-CN.md +3 -3
- package/skills/doxum-runtime/references/patterns.en.md +26 -64
- package/skills/doxum-runtime/references/patterns.zh-CN.md +15 -52
- package/dist/dependency-C5_R1tvQ.js +0 -496
- package/dist/dependency-C5_R1tvQ.js.map +0 -1
- package/dist/dependency-Dfzs3khk.cjs +0 -722
- package/dist/dependency-Dfzs3khk.cjs.map +0 -1
- package/dist/integration.cjs.map +0 -1
- package/dist/integration.js.map +0 -1
- package/dist/ownership-B-VAPcce.js.map +0 -1
- package/dist/ownership-CU-9DKJQ.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -100,8 +100,8 @@ in that update is rolled back.
|
|
|
100
100
|
|
|
101
101
|
Mutation failure codes are a closed public `MutationIssueCode` union. For
|
|
102
102
|
application validation, use `tx.report` or `tx.reject` with a
|
|
103
|
-
`
|
|
104
|
-
frozen.
|
|
103
|
+
diagnostic `{ code, message, address? }`; Doxum adds `source: 'application'`.
|
|
104
|
+
Published diagnostic arrays and addresses are copied and frozen.
|
|
105
105
|
|
|
106
106
|
## Read And Subscribe
|
|
107
107
|
|
|
@@ -141,6 +141,13 @@ runtime.history.redo();
|
|
|
141
141
|
runtime.apply([{ type: 'field.set', at: ['title'], value: 'Ship Doxum' }]);
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
+
Use `runtime.history.group()` for one action spanning multiple synchronous
|
|
145
|
+
updates, such as a drag. Keep its handle until the action ends, then call
|
|
146
|
+
`end()` to retain one undo entry or `cancel()` to apply its inverses atomically.
|
|
147
|
+
Groups cannot nest. Undo, redo, clear, remote/replace commits, and committed
|
|
148
|
+
updates with `history: false` end the current group. History implements
|
|
149
|
+
`Readable<HistoryState>` and can be used with `useReadable` or `fromReadable`.
|
|
150
|
+
|
|
144
151
|
`apply` is the boundary for replaying operations from persistence or a network
|
|
145
152
|
adapter. Doxum does not provide those adapters. A `replace` or a commit marked
|
|
146
153
|
as `remote` invalidates local history because its prior inverse sequence is no
|
|
@@ -177,7 +184,7 @@ the log can faithfully append. `flush()` is the explicit point that waits for
|
|
|
177
184
|
commits observed before the call to persist (or, in a follower, waits to catch
|
|
178
185
|
up to the durable head). A browser crash, quota failure, or malformed JSON
|
|
179
186
|
payload can therefore leave an already visible leader commit unpersisted;
|
|
180
|
-
|
|
187
|
+
observe `state` or use `onError` to surface that condition.
|
|
181
188
|
|
|
182
189
|
```ts
|
|
183
190
|
import { createDocument, select } from 'doxum';
|
|
@@ -197,7 +204,7 @@ const localSync = await attachLocalSync({
|
|
|
197
204
|
documentId: 'project-1',
|
|
198
205
|
});
|
|
199
206
|
|
|
200
|
-
if (localSync.state().status === 'leader') {
|
|
207
|
+
if (localSync.state.current().status === 'leader') {
|
|
201
208
|
runtime.update(tx => {
|
|
202
209
|
tx.write.title.set('Ship Doxum');
|
|
203
210
|
});
|
|
@@ -211,6 +218,10 @@ await localSync.flush(); // persist observed leader commands / catch up a follow
|
|
|
211
218
|
await localSync.dispose();
|
|
212
219
|
```
|
|
213
220
|
|
|
221
|
+
`localSync.state` is a `Readable`: `state.current()` returns a stable snapshot,
|
|
222
|
+
`state.subscribe(listener)` observes persistence, leadership and error changes,
|
|
223
|
+
and React can consume it with `useReadable(localSync.state)`.
|
|
224
|
+
|
|
214
225
|
`attachLocalSync` first hydrates the passed runtime from IndexedDB; await it
|
|
215
226
|
before allowing reads or edits. It does not make runtime mutation asynchronous,
|
|
216
227
|
does not own `runtime.dispose()`, and does not expose a second undo API. Runtime
|
|
@@ -239,11 +250,66 @@ views, materialized views, and history state.
|
|
|
239
250
|
|
|
240
251
|
## Derived Views
|
|
241
252
|
|
|
242
|
-
`
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
253
|
+
`createProjectionRuntime` owns an explicit graph of derived values and keyed
|
|
254
|
+
collections. It combines document runtimes and external values without owning
|
|
255
|
+
their mutations or history.
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
const projection = createProjectionRuntime({ onError: error => console.error(error) });
|
|
259
|
+
const document = projection.document(runtime);
|
|
260
|
+
const taskTitles = projection.map(
|
|
261
|
+
document.collection(path => path.tasks),
|
|
262
|
+
(_id, task) => task.title.get()
|
|
263
|
+
);
|
|
264
|
+
const taskCount = projection.value({ tasks: taskTitles }, ({ tasks }) => tasks.ids().length);
|
|
265
|
+
const labels = projection.map(taskTitles, (id, title) => `${id}: ${title}`);
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
`projection.value(sources, compute, { isEqual }?)` is the ordinary pure-compute
|
|
269
|
+
entry. Stateful algorithms use `projection.value({ sources, build }, { isEqual }?)`,
|
|
270
|
+
where build returns `{ value, update }`. Both use the same scheduler and lifecycle.
|
|
271
|
+
|
|
272
|
+
`projection.collection<Item>()(spec)` handles custom incremental algorithms. Its scoped
|
|
273
|
+
writer supports `set`, `remove`, `order`, and `replace`; `previous` and `next`
|
|
274
|
+
provide scoped reads. Declare all sources and use their native commit impacts
|
|
275
|
+
or upstream collection changes to choose candidate keys. A document collection
|
|
276
|
+
context also provides `candidates.keys`, `candidates.orderDirty` and `reset`,
|
|
277
|
+
aggregated across the entire batch. Candidates include net-zero changes; read
|
|
278
|
+
final state to decide the output. Doxum stages writes,
|
|
279
|
+
applies equality, and publishes exact `CollectionImpact` changes. It does not
|
|
280
|
+
automatically track item dependencies. `ids`, lazy `all`, and cached `item(id)`
|
|
281
|
+
implement `Readable` and work with `useReadable`.
|
|
282
|
+
|
|
283
|
+
`map` accepts document collections and upstream projection collections while
|
|
284
|
+
preserving keys and order. Source dependencies stay explicit.
|
|
285
|
+
|
|
286
|
+
Use `projection.input(initial, { isEqual })` for boundary values such as container
|
|
287
|
+
size. Its application-owned `set` updates a read-only `source`. Use
|
|
288
|
+
`projection.fromReadable(existing, { isEqual })` for an existing external source.
|
|
289
|
+
Neither replaces a document with domain mutation semantics.
|
|
290
|
+
|
|
291
|
+
Wrap the entire synchronous application action in `projection.batch(() => ...)`
|
|
292
|
+
before its first document commit to combine document changes and editor cleanup.
|
|
293
|
+
Batches nest, preserve committed source changes on exceptions, and provide no
|
|
294
|
+
cross-document rollback. Projection reads inside a batch return the last
|
|
295
|
+
published state. Document listeners still run synchronously.
|
|
296
|
+
|
|
297
|
+
All affected nodes settle before listeners. Output revisions change only when
|
|
298
|
+
their output changes. Update failures discard the processor instance and attempt
|
|
299
|
+
one fresh build; persistent faults block descendants, while independent branches
|
|
300
|
+
continue. Errors reach `onError` and, when inside document notification, the
|
|
301
|
+
committed result's `observerErrors`. Manual `rebuild()` uses the same graph.
|
|
302
|
+
Dispose the projection with its service; component unmount only unsubscribes.
|
|
303
|
+
Disposing a node with consumers is rejected, and disposed handles throw.
|
|
304
|
+
|
|
305
|
+
Schema access uses `object` for structured entities and `dict` for keyed values.
|
|
306
|
+
Variants expose `reader.get()` as a discriminated union and `writer.replace()`
|
|
307
|
+
for replacement. Optional presence is supported by field, variant, dict, list
|
|
308
|
+
and tree nodes. Dictionaries expose `get(key)`, `has(key)`, `keys()` and
|
|
309
|
+
`values()`; lists additionally support `get(key)` and `has(key)` using `keyOf`.
|
|
310
|
+
Tree insert/move accept `{ parentId, index }`, with index denoting the final
|
|
311
|
+
position after removing a moved node. See [API migration](docs/api-migration.md)
|
|
312
|
+
for breaking changes and the public surface.
|
|
247
313
|
|
|
248
314
|
## Data Ownership
|
|
249
315
|
|
|
@@ -40,19 +40,12 @@ type VariantNode<TTag extends string, TVariants extends VariantShape> = BaseNode
|
|
|
40
40
|
readonly tag: TTag;
|
|
41
41
|
readonly variants: TVariants;
|
|
42
42
|
};
|
|
43
|
-
type SingleNode<TValue extends ObjectNode<ObjectShape> | VariantNode<string, VariantShape>> = BaseNode<'single'> & {
|
|
44
|
-
readonly value: TValue;
|
|
45
|
-
};
|
|
46
43
|
type TableNode<TValue extends ObjectNode<ObjectShape> | VariantNode<string, VariantShape>> = BaseNode<'table'> & {
|
|
47
44
|
readonly value: TValue;
|
|
48
45
|
};
|
|
49
46
|
type MapNode<TValue extends ObjectNode<ObjectShape> | VariantNode<string, VariantShape>> = BaseNode<'map'> & {
|
|
50
47
|
readonly value: TValue;
|
|
51
48
|
};
|
|
52
|
-
type RecordNode<TId extends string, TValue> = BaseNode<'record'> & {
|
|
53
|
-
readonly __id?: TId;
|
|
54
|
-
readonly __value?: TValue;
|
|
55
|
-
};
|
|
56
49
|
type DictNode<TKey extends string, TValue> = BaseNode<'dict'> & {
|
|
57
50
|
readonly __key?: TKey;
|
|
58
51
|
readonly __value?: TValue;
|
|
@@ -64,12 +57,12 @@ type ListNode<TItem> = BaseNode<'list'> & {
|
|
|
64
57
|
type TreeNode<TValue> = BaseNode<'tree'> & {
|
|
65
58
|
readonly __value?: TValue;
|
|
66
59
|
};
|
|
67
|
-
type DocumentNode = FieldNode<unknown, false> | FieldNode<unknown, true> | ObjectNode<ObjectShape> | VariantNode<string, VariantShape> |
|
|
60
|
+
type DocumentNode = FieldNode<unknown, false> | FieldNode<unknown, true> | ObjectNode<ObjectShape> | VariantNode<string, VariantShape> | TableNode<ObjectNode<ObjectShape> | VariantNode<string, VariantShape>> | MapNode<ObjectNode<ObjectShape> | VariantNode<string, VariantShape>> | DictNode<string, unknown> | ListNode<unknown> | TreeNode<unknown>;
|
|
68
61
|
type EntityValue<N extends ObjectNode<ObjectShape> | VariantNode<string, VariantShape>> = N extends ObjectNode<infer S> ? DocumentValueOfShape<S> : N extends VariantNode<infer T, infer V> ? { [K in keyof V & string]: { [P in T]: K } & DocumentValueOfShape<V[K] extends ObjectNode<infer S> ? S : never> }[keyof V & string] : never;
|
|
69
|
-
type DocumentValueOfNode<N> = N extends FieldNode<infer T, infer O> ? O extends true ? T | undefined : T : N extends ObjectNode<infer S> ? DocumentValueOfShape<S> : N extends VariantNode<infer T, infer V> ? EntityValue<VariantNode<T, V>> : N extends
|
|
62
|
+
type DocumentValueOfNode<N> = N extends FieldNode<infer T, infer O> ? O extends true ? T | undefined : T : N extends ObjectNode<infer S> ? DocumentValueOfShape<S> : N extends VariantNode<infer T, infer V> ? EntityValue<VariantNode<T, V>> : N extends TableNode<infer V> ? {
|
|
70
63
|
readonly ids: readonly string[];
|
|
71
64
|
readonly byId: Readonly<Record<string, EntityValue<V>>>;
|
|
72
|
-
} : N extends MapNode<infer V> ? Readonly<Record<string, EntityValue<V>>> : N extends
|
|
65
|
+
} : N extends MapNode<infer V> ? Readonly<Record<string, EntityValue<V>>> : N extends DictNode<infer K, infer T> ? Readonly<Partial<Record<K, T>>> : N extends ListNode<infer I> ? readonly I[] : N extends TreeNode<infer T> ? DocumentTreeValue<T> : never;
|
|
73
66
|
type OptionalKeys<S extends ObjectShape> = { [K in keyof S]: S[K] extends {
|
|
74
67
|
readonly optional: true;
|
|
75
68
|
} ? K : never }[keyof S];
|
|
@@ -98,43 +91,35 @@ type ImpactTarget<T = unknown> = {
|
|
|
98
91
|
readonly at: DocumentAddress;
|
|
99
92
|
readonly id?: string;
|
|
100
93
|
} | CollectionSelector<string>;
|
|
94
|
+
declare const pathValue: unique symbol;
|
|
95
|
+
declare const collectionNode: unique symbol;
|
|
101
96
|
type PathMarker<TValue> = {
|
|
102
|
-
readonly
|
|
97
|
+
readonly [pathValue]: TValue;
|
|
103
98
|
};
|
|
104
|
-
type SchemaPathFor<S extends ObjectShape = ObjectShape, TValue = unknown> = { readonly [K in keyof S]: PathValue<S[K]> } &
|
|
105
|
-
readonly item: (id: string) => SchemaPathFor<{}, unknown>;
|
|
106
|
-
} & PathMarker<TValue>;
|
|
99
|
+
type SchemaPathFor<S extends ObjectShape = ObjectShape, TValue = unknown> = { readonly [K in keyof S]: PathValue<S[K]> } & PathMarker<TValue>;
|
|
107
100
|
type DocumentSchema<TShape extends ObjectShape = {}> = {
|
|
108
101
|
readonly kind: 'schema';
|
|
109
102
|
readonly shape: TShape;
|
|
110
|
-
collection<TPath extends
|
|
103
|
+
collection<TPath extends CollectionPath>(pick: (path: SchemaPath<TShape>) => TPath): CollectionSelector<CollectionId<TPath>, CollectionNode<TPath>>;
|
|
111
104
|
value<TPath extends PathMarker<unknown>>(pick: (path: SchemaPath<TShape>) => TPath): ValueSelector<PathValueResult<TPath>>;
|
|
112
105
|
};
|
|
113
106
|
type SchemaPath<S extends ObjectShape = {}> = SchemaPathFor<S, DocumentValueOfShape<S>>;
|
|
114
107
|
type VariantKeys<V extends VariantShape> = { [K in keyof V & string]: keyof (V[K] extends ObjectNode<infer S> ? S : {}) }[keyof V & string] & string;
|
|
115
108
|
type VariantFieldPath<V extends VariantShape, K extends string> = { [P in keyof V & string]: V[P] extends ObjectNode<infer S> ? K extends keyof S ? PathValue<S[K]> : never : never }[keyof V & string];
|
|
116
|
-
type VariantPath<V extends VariantShape> = { readonly [K in VariantKeys<V>]: VariantFieldPath<V, K> } & {
|
|
117
|
-
readonly item: (id: string) => SchemaPathFor<{}, unknown>;
|
|
118
|
-
} & PathMarker<EntityValue<VariantNode<string, V>>>;
|
|
109
|
+
type VariantPath<T extends string, V extends VariantShape> = { readonly [K in VariantKeys<V>]: VariantFieldPath<V, K> } & { readonly [K in T]: PathMarker<keyof V & string> } & PathMarker<EntityValue<VariantNode<T, V>>>;
|
|
119
110
|
type PathNodeValue<N extends DocumentNode> = N extends {
|
|
120
111
|
readonly optional: true;
|
|
121
112
|
} ? DocumentValueOfNode<N> | undefined : DocumentValueOfNode<N>;
|
|
122
|
-
type EntityPath<N extends ObjectNode<ObjectShape> | VariantNode<string, VariantShape>> = N extends ObjectNode<infer S> ? SchemaPathFor<S, PathNodeValue<N>> : N extends VariantNode<
|
|
123
|
-
type CollectionPath<N extends
|
|
113
|
+
type EntityPath<N extends ObjectNode<ObjectShape> | VariantNode<string, VariantShape>> = N extends ObjectNode<infer S> ? SchemaPathFor<S, PathNodeValue<N>> : N extends VariantNode<infer T, infer V> ? VariantPath<T, V> : never;
|
|
114
|
+
type CollectionPath<N extends EntitySchemaNode = EntitySchemaNode, TValue = unknown> = PathMarker<TValue> & {
|
|
124
115
|
readonly item: (id: string) => EntityPath<N>;
|
|
125
|
-
readonly
|
|
126
|
-
readonly id: string;
|
|
127
|
-
readonly node: N;
|
|
128
|
-
};
|
|
116
|
+
readonly [collectionNode]: N;
|
|
129
117
|
};
|
|
130
|
-
type PathValue<N extends DocumentNode> = N extends ObjectNode<infer S> ? SchemaPathFor<S, PathNodeValue<N>> : N extends VariantNode<infer
|
|
118
|
+
type PathValue<N extends DocumentNode> = N extends ObjectNode<infer S> ? SchemaPathFor<S, PathNodeValue<N>> : N extends VariantNode<infer TTag, infer V> ? VariantPath<TTag, V> : N extends TableNode<infer V> | MapNode<infer V> ? CollectionPath<V, PathNodeValue<N>> : PathMarker<PathNodeValue<N>>;
|
|
131
119
|
type CollectionInfo<T> = T extends {
|
|
132
|
-
readonly
|
|
133
|
-
readonly id: infer TId;
|
|
134
|
-
readonly node: infer TNode extends EntitySchemaNode;
|
|
135
|
-
};
|
|
120
|
+
readonly [collectionNode]: infer TNode extends EntitySchemaNode;
|
|
136
121
|
} ? {
|
|
137
|
-
readonly id:
|
|
122
|
+
readonly id: string;
|
|
138
123
|
readonly node: TNode;
|
|
139
124
|
} : never;
|
|
140
125
|
type CollectionId<T> = CollectionInfo<T> extends {
|
|
@@ -145,13 +130,12 @@ type CollectionNode<T> = CollectionInfo<T> extends {
|
|
|
145
130
|
} ? TNode : EntitySchemaNode;
|
|
146
131
|
type PathValueResult<T> = T extends PathMarker<infer TValue> ? TValue : unknown;
|
|
147
132
|
declare const field: <T>() => FieldNode<T>;
|
|
148
|
-
|
|
133
|
+
type OptionalLeaf = FieldNode<unknown, boolean> | VariantNode<string, VariantShape> | DictNode<string, unknown> | ListNode<unknown> | TreeNode<unknown>;
|
|
134
|
+
declare const optional: <T extends OptionalLeaf>(value: T) => OptionalNode<T>;
|
|
149
135
|
declare const object: <S extends ObjectShape>(shape: S) => ObjectNode<S>;
|
|
150
136
|
declare const variant: <T extends string, V extends VariantShape>(tag: T, variants: V) => VariantNode<T, V>;
|
|
151
|
-
declare const single: <V extends ObjectNode<ObjectShape> | VariantNode<string, VariantShape>>(value: V) => SingleNode<V>;
|
|
152
137
|
declare const table: <V extends ObjectNode<ObjectShape> | VariantNode<string, VariantShape>>(value: V) => TableNode<V>;
|
|
153
138
|
declare const map: <V extends ObjectNode<ObjectShape> | VariantNode<string, VariantShape>>(value: V) => MapNode<V>;
|
|
154
|
-
declare const record: <TId extends string = string, TValue = unknown>() => RecordNode<TId, TValue>;
|
|
155
139
|
declare const dict: <TKey extends string = string, TValue = unknown>() => DictNode<TKey, TValue>;
|
|
156
140
|
declare const list: <TItem>(config: DocumentListConfig<TItem>) => ListNode<TItem>;
|
|
157
141
|
declare const tree: <TValue = unknown>() => TreeNode<TValue>;
|
|
@@ -168,34 +152,34 @@ type DocumentAnchor = {
|
|
|
168
152
|
type OperationBase = {
|
|
169
153
|
readonly at: DocumentAddress;
|
|
170
154
|
};
|
|
171
|
-
type FieldSetOperation
|
|
155
|
+
type FieldSetOperation = OperationBase & {
|
|
172
156
|
readonly type: 'field.set';
|
|
173
157
|
readonly value: unknown;
|
|
174
158
|
};
|
|
175
|
-
type FieldClearOperation
|
|
159
|
+
type FieldClearOperation = OperationBase & {
|
|
176
160
|
readonly type: 'field.clear';
|
|
177
161
|
};
|
|
178
|
-
type ValueClearOperation
|
|
162
|
+
type ValueClearOperation = OperationBase & {
|
|
179
163
|
readonly type: 'value.clear';
|
|
180
164
|
};
|
|
181
|
-
type VariantReplaceOperation
|
|
165
|
+
type VariantReplaceOperation = OperationBase & {
|
|
182
166
|
readonly type: 'variant.replace';
|
|
183
167
|
readonly value: unknown;
|
|
184
168
|
};
|
|
185
|
-
type DictSetOperation
|
|
169
|
+
type DictSetOperation = OperationBase & {
|
|
186
170
|
readonly type: 'dict.set';
|
|
187
171
|
readonly key: string;
|
|
188
172
|
readonly value: unknown;
|
|
189
173
|
};
|
|
190
|
-
type DictDeleteOperation
|
|
174
|
+
type DictDeleteOperation = OperationBase & {
|
|
191
175
|
readonly type: 'dict.delete';
|
|
192
176
|
readonly key: string;
|
|
193
177
|
};
|
|
194
|
-
type DictReplaceOperation
|
|
178
|
+
type DictReplaceOperation = OperationBase & {
|
|
195
179
|
readonly type: 'dict.replace';
|
|
196
180
|
readonly value: Readonly<Record<string, unknown>>;
|
|
197
181
|
};
|
|
198
|
-
type EntityCreateOperation
|
|
182
|
+
type EntityCreateOperation = OperationBase & {
|
|
199
183
|
readonly type: 'entity.create';
|
|
200
184
|
readonly entries: readonly EntityEntry[];
|
|
201
185
|
readonly anchor?: DocumentAnchor; /** Generated inverse metadata with strictly increasing final indices. Normal creates omit it. */
|
|
@@ -205,74 +189,81 @@ type EntityEntry = {
|
|
|
205
189
|
readonly id: string;
|
|
206
190
|
readonly value: unknown;
|
|
207
191
|
};
|
|
208
|
-
type EntityRemoveOperation
|
|
192
|
+
type EntityRemoveOperation = OperationBase & {
|
|
209
193
|
readonly type: 'entity.remove';
|
|
210
194
|
readonly ids: readonly string[];
|
|
211
195
|
};
|
|
212
|
-
type EntityMoveOperation
|
|
196
|
+
type EntityMoveOperation = OperationBase & {
|
|
213
197
|
readonly type: 'entity.move';
|
|
214
198
|
readonly id: string;
|
|
215
199
|
readonly anchor?: DocumentAnchor;
|
|
216
200
|
};
|
|
217
|
-
type ListInsertOperation
|
|
201
|
+
type ListInsertOperation = OperationBase & {
|
|
218
202
|
readonly type: 'list.insert';
|
|
219
203
|
readonly key: string;
|
|
220
204
|
readonly value: unknown;
|
|
221
205
|
readonly anchor?: DocumentAnchor;
|
|
222
206
|
};
|
|
223
|
-
type ListMoveOperation
|
|
207
|
+
type ListMoveOperation = OperationBase & {
|
|
224
208
|
readonly type: 'list.move';
|
|
225
209
|
readonly key: string;
|
|
226
210
|
readonly anchor?: DocumentAnchor;
|
|
227
211
|
};
|
|
228
|
-
type ListRemoveOperation
|
|
212
|
+
type ListRemoveOperation = OperationBase & {
|
|
229
213
|
readonly type: 'list.remove';
|
|
230
214
|
readonly key: string;
|
|
231
215
|
};
|
|
232
|
-
type ListReplaceOperation
|
|
216
|
+
type ListReplaceOperation = OperationBase & {
|
|
233
217
|
readonly type: 'list.replace';
|
|
234
218
|
readonly value: readonly unknown[];
|
|
235
219
|
readonly keys: readonly string[];
|
|
236
220
|
};
|
|
237
|
-
type TreeInsertOperation
|
|
221
|
+
type TreeInsertOperation = OperationBase & {
|
|
238
222
|
readonly type: 'tree.insert';
|
|
239
223
|
readonly treeNodeId: string;
|
|
240
224
|
readonly parentId?: string;
|
|
241
225
|
readonly index?: number;
|
|
242
226
|
readonly value?: unknown;
|
|
243
227
|
};
|
|
244
|
-
type TreeMoveOperation
|
|
228
|
+
type TreeMoveOperation = OperationBase & {
|
|
245
229
|
readonly type: 'tree.move';
|
|
246
230
|
readonly treeNodeId: string;
|
|
247
231
|
readonly parentId?: string;
|
|
248
232
|
readonly index?: number;
|
|
249
233
|
};
|
|
250
|
-
type TreeRemoveOperation
|
|
234
|
+
type TreeRemoveOperation = OperationBase & {
|
|
251
235
|
readonly type: 'tree.remove';
|
|
252
236
|
readonly treeNodeId: string;
|
|
253
237
|
};
|
|
254
|
-
type TreeSetOperation
|
|
238
|
+
type TreeSetOperation = OperationBase & {
|
|
255
239
|
readonly type: 'tree.set';
|
|
256
240
|
readonly treeNodeId: string;
|
|
257
241
|
readonly value: unknown;
|
|
258
242
|
};
|
|
259
|
-
type TreeReplaceOperation
|
|
243
|
+
type TreeReplaceOperation = OperationBase & {
|
|
260
244
|
readonly type: 'tree.replace';
|
|
261
245
|
readonly value: unknown;
|
|
262
246
|
};
|
|
263
|
-
type
|
|
264
|
-
type DocumentOperation<TSchema extends DocumentSchema = DocumentSchema> = DocumentOperationUnion<TSchema>;
|
|
247
|
+
type DocumentOperation = FieldSetOperation | FieldClearOperation | ValueClearOperation | VariantReplaceOperation | DictSetOperation | DictDeleteOperation | DictReplaceOperation | EntityCreateOperation | EntityRemoveOperation | EntityMoveOperation | ListInsertOperation | ListMoveOperation | ListRemoveOperation | ListReplaceOperation | TreeInsertOperation | TreeMoveOperation | TreeRemoveOperation | TreeSetOperation | TreeReplaceOperation;
|
|
265
248
|
//#endregion
|
|
266
249
|
//#region core/src/access/reader.d.ts
|
|
267
250
|
type FieldReader<T> = {
|
|
268
251
|
readonly get: () => T;
|
|
269
252
|
};
|
|
253
|
+
type DictionaryReader<K extends string, V> = {
|
|
254
|
+
get(key: K): V | undefined;
|
|
255
|
+
has(key: K): boolean;
|
|
256
|
+
keys(): readonly K[];
|
|
257
|
+
values(): Readonly<Partial<Record<K, V>>>;
|
|
258
|
+
};
|
|
270
259
|
type CollectionReader<TId, TNode extends EntitySchemaNode> = {
|
|
271
260
|
readonly ids: () => readonly TId[];
|
|
272
261
|
readonly has: (id: TId) => boolean;
|
|
273
262
|
readonly get: (id: TId) => ReaderOfNode<TNode> | undefined;
|
|
274
263
|
};
|
|
275
264
|
type ListReader<T> = {
|
|
265
|
+
readonly get: (key: string) => T | undefined;
|
|
266
|
+
readonly has: (key: string) => boolean;
|
|
276
267
|
readonly values: () => readonly T[];
|
|
277
268
|
readonly length: () => number;
|
|
278
269
|
readonly at: (index: number) => T | undefined;
|
|
@@ -286,7 +277,9 @@ type TreeReader<T> = {
|
|
|
286
277
|
};
|
|
287
278
|
type ReaderOfNode<TNode extends DocumentNode> = TNode extends {
|
|
288
279
|
kind: 'field';
|
|
289
|
-
} ? FieldReader<DocumentValueOfNode<TNode>> : TNode extends ObjectNode<infer TShape> ? { readonly [K in keyof TShape]: ReaderOfNode<TShape[K]> } : TNode extends VariantNode<string, infer
|
|
280
|
+
} ? FieldReader<DocumentValueOfNode<TNode>> : TNode extends ObjectNode<infer TShape> ? { readonly [K in keyof TShape]: ReaderOfNode<TShape[K]> } : TNode extends VariantNode<string, infer _TVariants> ? FieldReader<DocumentValueOfNode<TNode> | (TNode extends {
|
|
281
|
+
readonly optional: true;
|
|
282
|
+
} ? undefined : never)> : TNode extends TableNode<infer TValue> ? CollectionReader<string, TValue> : TNode extends MapNode<infer TValue> ? CollectionReader<string, TValue> : TNode extends DictNode<infer TKey, infer TValue> ? DictionaryReader<TKey, TValue> : TNode extends ListNode<infer TItem> ? ListReader<TItem> : TNode extends TreeNode<infer TValue> ? TreeReader<TValue> : FieldReader<DocumentValueOfNode<TNode>>;
|
|
290
283
|
type DocumentReader<TSchema extends DocumentSchema> = ReaderOfNode<ObjectNode<TSchema['shape']>>;
|
|
291
284
|
//#endregion
|
|
292
285
|
//#region core/src/access/writer.d.ts
|
|
@@ -330,8 +323,14 @@ type ListWriter<T> = {
|
|
|
330
323
|
readonly replace: (value: readonly T[]) => void;
|
|
331
324
|
};
|
|
332
325
|
type TreeWriter<T> = {
|
|
333
|
-
readonly insert: (id: string, value: T,
|
|
334
|
-
|
|
326
|
+
readonly insert: (id: string, value: T, position?: {
|
|
327
|
+
readonly parentId?: string;
|
|
328
|
+
readonly index?: number;
|
|
329
|
+
}) => void;
|
|
330
|
+
readonly move: (id: string, position?: {
|
|
331
|
+
readonly parentId?: string;
|
|
332
|
+
readonly index?: number;
|
|
333
|
+
}) => void;
|
|
335
334
|
readonly remove: (id: string) => void;
|
|
336
335
|
readonly set: (id: string, value: T) => void;
|
|
337
336
|
readonly replace: (value: DocumentTreeValue<T>) => void;
|
|
@@ -347,7 +346,7 @@ type WriterOfNode<TNode extends DocumentNode> = TNode extends {
|
|
|
347
346
|
readonly optional: true;
|
|
348
347
|
} ? FieldWriter<DocumentValueOfNode<TNode>, true> : FieldWriter<DocumentValueOfNode<TNode>> : TNode extends ObjectNode<infer TShape> ? { readonly [K in keyof TShape]: WriterOfNode<TShape[K]> } : TNode extends VariantNode<string, infer _TVariants> ? OptionalClear<TNode, {
|
|
349
348
|
readonly replace: (value: DocumentValueOfNode<TNode>) => void;
|
|
350
|
-
}> : TNode extends
|
|
349
|
+
}> : TNode extends TableNode<infer TValue> ? CollectionWriter<string, TValue> : TNode extends MapNode<infer TValue> ? MapWriter<string, TValue> : TNode extends DictNode<infer TKey, infer TValue> ? OptionalClear<TNode, DictionaryWriter<TKey, TValue>> : TNode extends ListNode<infer TItem> ? OptionalClear<TNode, ListWriter<TItem>> : TNode extends TreeNode<infer TValue> ? OptionalClear<TNode, TreeWriter<TValue>> : FieldWriter<DocumentValueOfNode<TNode>>;
|
|
351
350
|
type DocumentWriter<TSchema extends DocumentSchema> = WriterOfNode<ObjectNode<TSchema['shape']>>;
|
|
352
351
|
//#endregion
|
|
353
352
|
//#region core/src/mutation/issue.d.ts
|
|
@@ -357,7 +356,7 @@ type MutationIssue = {
|
|
|
357
356
|
readonly code: MutationIssueCode;
|
|
358
357
|
readonly address: DocumentAddress;
|
|
359
358
|
readonly message: string;
|
|
360
|
-
readonly operation?:
|
|
359
|
+
readonly operation?: DocumentOperation['type'];
|
|
361
360
|
};
|
|
362
361
|
//#endregion
|
|
363
362
|
//#region core/src/impact.d.ts
|
|
@@ -374,7 +373,7 @@ type DocumentImpact<TSchema extends DocumentSchema> = {
|
|
|
374
373
|
readonly kind: 'incremental' | 'reset';
|
|
375
374
|
readonly affects: (target: ImpactTarget<unknown>) => boolean;
|
|
376
375
|
readonly collection: <TId extends string>(selector: CollectionSelector<TId>) => CollectionImpact<TId>;
|
|
377
|
-
readonly operations: readonly
|
|
376
|
+
readonly operations: readonly DocumentOperation[];
|
|
378
377
|
};
|
|
379
378
|
//#endregion
|
|
380
379
|
//#region core/src/address.d.ts
|
|
@@ -423,12 +422,20 @@ type CommandFootprintTarget = {
|
|
|
423
422
|
readonly id: string;
|
|
424
423
|
};
|
|
425
424
|
type CommandFootprint = readonly CommandFootprintTarget[];
|
|
426
|
-
declare const commandFootprint: (operations: readonly
|
|
425
|
+
declare const commandFootprint: (operations: readonly DocumentOperation[]) => CommandFootprint;
|
|
427
426
|
declare const footprintsOverlap: (left: CommandFootprint, right: CommandFootprint) => boolean;
|
|
428
427
|
declare const decodeCommandFootprint: (value: unknown) => CommandFootprint | undefined;
|
|
429
428
|
//#endregion
|
|
429
|
+
//#region core/src/projection/readable.d.ts
|
|
430
|
+
type Readable<TValue> = {
|
|
431
|
+
current(): TValue;
|
|
432
|
+
revision(): number;
|
|
433
|
+
subscribe(listener: () => void): Unsubscribe;
|
|
434
|
+
};
|
|
435
|
+
//#endregion
|
|
430
436
|
//#region core/src/runtime/contract.d.ts
|
|
431
437
|
type Unsubscribe = () => void;
|
|
438
|
+
type Synchronous<T> = T extends PromiseLike<unknown> ? never : T;
|
|
432
439
|
type CommitSource = 'local' | 'system' | 'history' | 'remote';
|
|
433
440
|
declare class DocumentReentrancyError extends Error {
|
|
434
441
|
constructor();
|
|
@@ -440,16 +447,18 @@ type DocumentCommit<TSchema extends DocumentSchema> = {
|
|
|
440
447
|
readonly revision: number;
|
|
441
448
|
readonly kind: 'operations' | 'replace';
|
|
442
449
|
readonly source: CommitSource;
|
|
443
|
-
readonly operations: readonly
|
|
444
|
-
readonly inverse: readonly
|
|
450
|
+
readonly operations: readonly DocumentOperation[];
|
|
451
|
+
readonly inverse: readonly DocumentOperation[];
|
|
445
452
|
readonly impact: DocumentImpact<TSchema>;
|
|
446
453
|
};
|
|
447
|
-
type
|
|
448
|
-
readonly source: 'application';
|
|
454
|
+
type DiagnosticInput = {
|
|
449
455
|
readonly code: string;
|
|
450
456
|
readonly message: string;
|
|
451
457
|
readonly address?: DocumentAddress;
|
|
452
458
|
};
|
|
459
|
+
type DocumentDiagnostic = DiagnosticInput & {
|
|
460
|
+
readonly source: 'application';
|
|
461
|
+
};
|
|
453
462
|
type DocumentProblem = DocumentDiagnostic | MutationIssue;
|
|
454
463
|
type ObserverError = {
|
|
455
464
|
readonly phase: 'processor' | 'flush' | 'listener';
|
|
@@ -474,8 +483,8 @@ type TransactionResult<TValue, TCommit> = {
|
|
|
474
483
|
type PreparedUpdateResult<TValue, TSchema extends DocumentSchema> = {
|
|
475
484
|
readonly status: 'prepared';
|
|
476
485
|
readonly value: TValue;
|
|
477
|
-
readonly operations: readonly
|
|
478
|
-
readonly inverse: readonly
|
|
486
|
+
readonly operations: readonly DocumentOperation[];
|
|
487
|
+
readonly inverse: readonly DocumentOperation[];
|
|
479
488
|
readonly impact: DocumentImpact<TSchema>;
|
|
480
489
|
readonly footprint: CommandFootprint;
|
|
481
490
|
readonly reports: readonly DocumentDiagnostic[];
|
|
@@ -503,18 +512,20 @@ type HistoryState = {
|
|
|
503
512
|
readonly undoDepth: number;
|
|
504
513
|
readonly redoDepth: number;
|
|
505
514
|
};
|
|
506
|
-
type LocalHistory<TCommit> = {
|
|
507
|
-
current(): HistoryState;
|
|
508
|
-
subscribe(listener: () => void): Unsubscribe;
|
|
515
|
+
type LocalHistory<TCommit> = Readable<HistoryState> & {
|
|
509
516
|
undo(): OperationResult<TCommit>;
|
|
510
517
|
redo(): OperationResult<TCommit>;
|
|
511
518
|
clear(): void;
|
|
519
|
+
group(): {
|
|
520
|
+
end(): void;
|
|
521
|
+
cancel(): OperationResult<TCommit>;
|
|
522
|
+
};
|
|
512
523
|
};
|
|
513
524
|
type DocumentTransaction<TSchema extends DocumentSchema> = {
|
|
514
525
|
readonly read: DocumentReader<TSchema>;
|
|
515
526
|
readonly write: DocumentWriter<TSchema>;
|
|
516
|
-
readonly reject: (issue:
|
|
517
|
-
readonly report: (issue:
|
|
527
|
+
readonly reject: (issue: DiagnosticInput | readonly DiagnosticInput[]) => never;
|
|
528
|
+
readonly report: (issue: DiagnosticInput) => void;
|
|
518
529
|
};
|
|
519
530
|
type CommitListener<TSchema extends DocumentSchema> = (commit: DocumentCommit<TSchema>) => void;
|
|
520
531
|
type DocumentReadable<TSchema extends DocumentSchema> = {
|
|
@@ -531,11 +542,11 @@ type DocumentReadable<TSchema extends DocumentSchema> = {
|
|
|
531
542
|
};
|
|
532
543
|
type DocumentRuntime<TSchema extends DocumentSchema> = DocumentReadable<TSchema> & {
|
|
533
544
|
/** Schema configuration captured when this runtime was created. */readonly schema: TSchema;
|
|
534
|
-
update<TResult>(run: (transaction: DocumentTransaction<TSchema>) => TResult
|
|
545
|
+
update<TResult>(run: (transaction: DocumentTransaction<TSchema>) => Synchronous<TResult>, options?: {
|
|
535
546
|
readonly source?: Extract<CommitSource, 'local' | 'system'>;
|
|
536
547
|
readonly history?: boolean;
|
|
537
548
|
}): TransactionResult<TResult, DocumentCommit<TSchema>>;
|
|
538
|
-
prepare<TResult>(run: (transaction: DocumentTransaction<TSchema>) => TResult): PreparedUpdateResult<TResult, TSchema>;
|
|
549
|
+
prepare<TResult>(run: (transaction: DocumentTransaction<TSchema>) => Synchronous<TResult>): PreparedUpdateResult<TResult, TSchema>;
|
|
539
550
|
apply(operations: unknown, options?: {
|
|
540
551
|
readonly source?: Exclude<CommitSource, 'history'>;
|
|
541
552
|
readonly history?: boolean;
|
|
@@ -548,5 +559,5 @@ type DocumentRuntime<TSchema extends DocumentSchema> = DocumentReadable<TSchema>
|
|
|
548
559
|
dispose(): void;
|
|
549
560
|
};
|
|
550
561
|
//#endregion
|
|
551
|
-
export {
|
|
552
|
-
//# sourceMappingURL=contract-
|
|
562
|
+
export { DocumentOperation as $, variant as $t, CollectionImpact as A, FieldNode as At, TreeWriter as B, TreeNode as Bt, footprintsOverlap as C, DocumentNode as Ct, overlaps as D, DocumentValueOfNode as Dt, debugKey as E, DocumentTreeValue as Et, DictionaryWriter as F, ObjectShape as Ft, FieldReader as G, field as Gt, CollectionReader as H, VariantNode as Ht, DocumentWriter as I, OptionalNode as It, TreeReader as J, object as Jt, ListReader as K, list as Kt, FieldWriter as L, ReadonlyDocument as Lt, MutationIssue as M, ListNode as Mt, MutationIssueCode as N, MapNode as Nt, read as O, DocumentValueOfShape as Ot, CollectionWriter as P, ObjectNode as Pt, DocumentAnchor as Q, tree as Qt, ListWriter as R, SchemaPath as Rt, decodeCommandFootprint as S, DocumentListConfig as St, contains as T, DocumentTreeNode as Tt, DictionaryReader as U, VariantShape as Ut, WriterOfNode as V, ValueSelector as Vt, DocumentReader as W, dict as Wt, DictReplaceOperation as X, schema as Xt, DictDeleteOperation as Y, optional as Yt, DictSetOperation as Z, table as Zt, Unsubscribe as _, CollectionNode as _t, DocumentProblem as a, FieldSetOperation as at, CommandFootprintTarget as b, DictNode as bt, DocumentRuntime as c, ListRemoveOperation as ct, LocalHistory as d, TreeMoveOperation as dt, EntityCreateOperation as et, ObserverError as f, TreeRemoveOperation as ft, TransactionResult as g, VariantReplaceOperation as gt, Synchronous as h, ValueClearOperation as ht, DocumentDisposedError as i, FieldClearOperation as it, DocumentImpact as j, ImpactTarget as jt, resolveAddress as k, EntitySchemaNode as kt, DocumentTransaction as l, ListReplaceOperation as lt, PreparedUpdateResult as m, TreeSetOperation as mt, DocumentCommit as n, EntityMoveOperation as nt, DocumentReadable as o, ListInsertOperation as ot, OperationResult as p, TreeReplaceOperation as pt, ReaderOfNode as q, map as qt, DocumentDiagnostic as r, EntityRemoveOperation as rt, DocumentReentrancyError as s, ListMoveOperation as st, CommitSource as t, EntityEntry as tt, HistoryState as u, TreeInsertOperation as ut, Readable as v, CollectionPath as vt, AddressRef as w, DocumentSchema as wt, commandFootprint as x, DocumentAddress as xt, CommandFootprint as y, CollectionSelector as yt, MapWriter as z, TableNode as zt };
|
|
563
|
+
//# sourceMappingURL=contract-DNZ4D53r.d.ts.map
|