doxum 0.1.6 → 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.
Files changed (45) hide show
  1. package/README.md +38 -13
  2. package/dist/{contract-I99DUMbN.d.ts → contract-DNZ4D53r.d.ts} +87 -76
  3. package/dist/{contract-uYJTmT8o.d.cts → contract-j3SLGAwh.d.cts} +87 -76
  4. package/dist/index.cjs +221 -349
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +3 -3
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.js +209 -327
  9. package/dist/index.js.map +1 -1
  10. package/dist/{integration-xupBIKjU.js → integration-B56u1l9V.js} +2 -2
  11. package/dist/integration-B56u1l9V.js.map +1 -0
  12. package/dist/{integration-Bs3pOk65.cjs → integration-CZwCwFBS.cjs} +2 -2
  13. package/dist/integration-CZwCwFBS.cjs.map +1 -0
  14. package/dist/integration.cjs +10 -2
  15. package/dist/integration.d.cts +3 -3
  16. package/dist/integration.d.ts +3 -3
  17. package/dist/integration.js +3 -3
  18. package/dist/local-sync.cjs +56 -17
  19. package/dist/local-sync.cjs.map +1 -1
  20. package/dist/local-sync.d.cts +2 -2
  21. package/dist/local-sync.d.ts +2 -2
  22. package/dist/local-sync.js +56 -17
  23. package/dist/local-sync.js.map +1 -1
  24. package/dist/react.cjs +27 -19
  25. package/dist/react.cjs.map +1 -1
  26. package/dist/react.js +27 -19
  27. package/dist/react.js.map +1 -1
  28. package/dist/{runtime-CRijXjYp.cjs → runtime-0mOFbe_H.cjs} +899 -451
  29. package/dist/runtime-0mOFbe_H.cjs.map +1 -0
  30. package/dist/{runtime-CUcvhFNP.d.ts → runtime-B22tuj9A.d.cts} +18 -20
  31. package/dist/{runtime-C_vKHmhy.d.cts → runtime-BFmhzPpZ.d.ts} +18 -20
  32. package/dist/{runtime-BJRXF0gq.js → runtime-DF1q9Gje.js} +823 -429
  33. package/dist/runtime-DF1q9Gje.js.map +1 -0
  34. package/package.json +1 -1
  35. package/skills/doxum-runtime/SKILL.md +2 -1
  36. package/skills/doxum-runtime/references/guide.en.md +18 -18
  37. package/skills/doxum-runtime/references/guide.zh-CN.md +12 -17
  38. package/skills/doxum-runtime/references/invariants.en.md +1 -1
  39. package/skills/doxum-runtime/references/invariants.zh-CN.md +1 -1
  40. package/skills/doxum-runtime/references/patterns.en.md +9 -20
  41. package/skills/doxum-runtime/references/patterns.zh-CN.md +5 -18
  42. package/dist/integration-Bs3pOk65.cjs.map +0 -1
  43. package/dist/integration-xupBIKjU.js.map +0 -1
  44. package/dist/runtime-BJRXF0gq.js.map +0 -1
  45. package/dist/runtime-CRijXjYp.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_runtime = require("./runtime-CRijXjYp.cjs");
2
+ const require_runtime = require("./runtime-0mOFbe_H.cjs");
3
3
  const require_ownership = require("./ownership-CY0nPXGF.cjs");
4
4
  const require_driver = require("./driver-CNxqMVFH.cjs");
5
5
  //#region core/src/impact.ts
@@ -89,78 +89,170 @@ const createImpact = (input) => {
89
89
  //#endregion
90
90
  //#region core/src/history.ts
91
91
  const createHistory = (input) => {
92
- const undos = [];
93
- const redos = [];
92
+ let undos = [];
93
+ let redos = [];
94
94
  const listeners = /* @__PURE__ */ new Set();
95
95
  let state = Object.freeze({
96
96
  undoDepth: 0,
97
97
  redoDepth: 0
98
98
  });
99
- const current = () => {
100
- if (state.undoDepth !== undos.length || state.redoDepth !== redos.length) state = Object.freeze({
99
+ let revision = 0;
100
+ let pending = false;
101
+ let disposed = false;
102
+ let group;
103
+ const unchanged = () => ({
104
+ status: "unchanged",
105
+ revision: input.revision()
106
+ });
107
+ const publish = () => {
108
+ if (state.undoDepth === undos.length && state.redoDepth === redos.length) return;
109
+ state = Object.freeze({
101
110
  undoDepth: undos.length,
102
111
  redoDepth: redos.length
103
112
  });
104
- return state;
113
+ revision++;
114
+ pending = true;
105
115
  };
106
- const emit = () => {
107
- if (listeners.size === 0) return;
108
- current();
109
- Array.from(listeners).forEach((listener) => listener());
116
+ const flush = () => {
117
+ if (!pending) return [];
118
+ pending = false;
119
+ const errors = [];
120
+ for (const listener of [...listeners]) {
121
+ if (!listeners.has(listener)) continue;
122
+ try {
123
+ listener();
124
+ } catch (error) {
125
+ errors.push({
126
+ phase: "listener",
127
+ error
128
+ });
129
+ }
130
+ }
131
+ return errors;
110
132
  };
111
133
  const clear = () => {
112
- if (undos.length || redos.length) {
113
- undos.length = 0;
114
- redos.length = 0;
115
- emit();
134
+ group = void 0;
135
+ undos.length = redos.length = 0;
136
+ publish();
137
+ };
138
+ const travel = (direction) => {
139
+ input.assertIdle();
140
+ const from = direction === "redo" ? redos : undos;
141
+ const to = direction === "redo" ? undos : redos;
142
+ const previousUndos = undos;
143
+ const previousRedos = redos;
144
+ const entry = direction === "cancel" ? from.at(-1) : from.pop();
145
+ if (!entry) return unchanged();
146
+ if (direction === "cancel") {
147
+ if (!group || group.entry !== entry) throw new Error("History group no longer owns its entry.");
148
+ undos = group.undos;
149
+ redos = group.redos;
150
+ } else to.push(entry);
151
+ let committed = false;
152
+ try {
153
+ const operations = direction === "redo" ? entry.batches.flatMap((batch) => batch.operations) : entry.batches.slice().reverse().flatMap((batch) => batch.inverse);
154
+ const result = input.apply(operations);
155
+ committed = result.status !== "rejected";
156
+ if (committed && direction === "cancel") group = void 0;
157
+ if (result.status === "unchanged") {
158
+ publish();
159
+ const errors = input.notify(flush);
160
+ if (errors.length) throw new AggregateError(errors.map((entry) => entry.error), "History listeners failed.");
161
+ }
162
+ return result;
163
+ } finally {
164
+ if (!committed) if (direction === "cancel") {
165
+ undos = previousUndos;
166
+ redos = previousRedos;
167
+ } else {
168
+ to.pop();
169
+ from.push(entry);
170
+ }
116
171
  }
117
172
  };
118
173
  return {
119
174
  api: {
120
- current,
175
+ current: () => state,
176
+ revision: () => revision,
121
177
  subscribe: (listener) => {
178
+ if (disposed) throw new require_runtime.DocumentDisposedError();
122
179
  listeners.add(listener);
123
- return () => listeners.delete(listener);
180
+ return () => {
181
+ listeners.delete(listener);
182
+ };
124
183
  },
125
184
  undo: () => {
126
- const entry = undos.pop();
127
- if (!entry) return {
128
- status: "unchanged",
129
- revision: input.revision()
130
- };
131
- const result = input.apply(entry.inverse);
132
- if (result.status === "committed") {
133
- redos.push(entry);
134
- emit();
135
- } else undos.push(entry);
136
- return result;
185
+ input.assertIdle();
186
+ group = void 0;
187
+ return travel("undo");
137
188
  },
138
189
  redo: () => {
139
- const entry = redos.pop();
140
- if (!entry) return {
141
- status: "unchanged",
142
- revision: input.revision()
143
- };
144
- const result = input.apply(entry.operations);
145
- if (result.status === "committed") {
146
- undos.push(entry);
147
- emit();
148
- } else redos.push(entry);
149
- return result;
190
+ input.assertIdle();
191
+ group = void 0;
192
+ return travel("redo");
150
193
  },
151
- clear
194
+ clear: () => {
195
+ input.assertIdle();
196
+ clear();
197
+ const errors = input.notify(flush);
198
+ if (errors.length) throw new AggregateError(errors.map((entry) => entry.error), "History listeners failed.");
199
+ },
200
+ group: () => {
201
+ input.assertIdle();
202
+ if (group) throw new Error("A history group is already active.");
203
+ if (input.capacity <= 0) throw new Error("History is disabled.");
204
+ const scope = {
205
+ undos: undos.slice(),
206
+ redos: redos.slice()
207
+ };
208
+ group = scope;
209
+ return Object.freeze({
210
+ end: () => {
211
+ input.assertIdle();
212
+ if (group === scope) group = void 0;
213
+ },
214
+ cancel: () => {
215
+ input.assertIdle();
216
+ if (group !== scope) return unchanged();
217
+ if (!scope.entry) {
218
+ group = void 0;
219
+ return unchanged();
220
+ }
221
+ const result = travel("cancel");
222
+ if (result.status !== "rejected") group = void 0;
223
+ return result;
224
+ }
225
+ });
226
+ }
152
227
  },
153
228
  record: (operations, inverse) => {
154
229
  if (input.capacity <= 0) return;
155
- undos.push({
230
+ const batch = {
156
231
  operations,
157
232
  inverse
158
- });
159
- if (undos.length > input.capacity) undos.shift();
233
+ };
234
+ if (group?.entry) group.entry.batches.push(batch);
235
+ else {
236
+ const entry = { batches: [batch] };
237
+ undos.push(entry);
238
+ if (group) group.entry = entry;
239
+ if (undos.length > input.capacity) undos.shift();
240
+ }
160
241
  redos.length = 0;
161
- emit();
242
+ publish();
243
+ },
244
+ publish,
245
+ flush,
246
+ endGroup: () => {
247
+ group = void 0;
162
248
  },
163
- invalidate: clear
249
+ invalidate: clear,
250
+ dispose: () => {
251
+ disposed = true;
252
+ listeners.clear();
253
+ clear();
254
+ pending = false;
255
+ }
164
256
  };
165
257
  };
166
258
  //#endregion
@@ -180,7 +272,7 @@ const writerFor = (node, inputAddress, sink) => {
180
272
  at: address
181
273
  }) : void 0
182
274
  };
183
- if (node.kind === "dict" || node.kind === "record") return {
275
+ if (node.kind === "dict") return {
184
276
  set: (key, value) => emit(sink, {
185
277
  type: "dict.set",
186
278
  at: address,
@@ -233,20 +325,20 @@ const writerFor = (node, inputAddress, sink) => {
233
325
  }) } : {}
234
326
  };
235
327
  if (node.kind === "tree") return {
236
- insert: (treeNodeId, value, parentId, index) => emit(sink, {
328
+ insert: (treeNodeId, value, position) => emit(sink, {
237
329
  type: "tree.insert",
238
330
  at: address,
239
331
  treeNodeId,
240
332
  value,
241
- parentId,
242
- index
333
+ parentId: position?.parentId,
334
+ index: position?.index
243
335
  }),
244
- move: (treeNodeId, parentId, index) => emit(sink, {
336
+ move: (treeNodeId, position) => emit(sink, {
245
337
  type: "tree.move",
246
338
  at: address,
247
339
  treeNodeId,
248
- parentId,
249
- index
340
+ parentId: position?.parentId,
341
+ index: position?.index
250
342
  }),
251
343
  remove: (treeNodeId) => emit(sink, {
252
344
  type: "tree.remove",
@@ -330,7 +422,6 @@ const writerFor = (node, inputAddress, sink) => {
330
422
  })
331
423
  };
332
424
  }
333
- if (node.kind === "single") return writerFor(node.value, address, sink);
334
425
  if (node.kind === "variant") return {
335
426
  replace: (value) => emit(sink, {
336
427
  type: "variant.replace",
@@ -356,69 +447,15 @@ const documentWriter = (schema, sink) => writerFor(schemaRoot(schema), [], sink)
356
447
  //#endregion
357
448
  //#region core/src/mutation/issue.ts
358
449
  const ownAddress$1 = (address) => Object.freeze(address.slice());
359
- const at$1 = (address, code, message, operation) => Object.freeze({
450
+ const at = (address, code, message, operation) => Object.freeze({
360
451
  source: "mutation",
361
452
  code,
362
453
  address: ownAddress$1(address),
363
454
  message,
364
455
  ...operation === void 0 ? {} : { operation }
365
456
  });
366
- const from = (operation, code, message) => at$1(operation.at, code, message, operation.type);
367
- const input = (code, message) => at$1([], code, message);
368
- //#endregion
369
- //#region core/src/mutation/anchor.ts
370
- const length = (keys) => keys.length;
371
- const keyAt = (keys, index) => Array.isArray(keys) ? keys[index] : keys.at(index);
372
- const keyIndex = (keys, key) => Array.isArray(keys) ? keys.indexOf(key) : keys.index(key);
373
- const keys = (values, keyOf) => ({
374
- length: values.length,
375
- at: (index) => index >= 0 && index < values.length ? keyOf(values[index]) : void 0,
376
- index: (key) => {
377
- for (let index = 0; index < values.length; index += 1) if (keyOf(values[index]) === key) return index;
378
- return -1;
379
- }
380
- });
381
- const index = (keys, anchor) => {
382
- if (!anchor) return length(keys);
383
- if ("at" in anchor) return anchor.at === "start" ? 0 : length(keys);
384
- if ("before" in anchor) return keyIndex(keys, anchor.before);
385
- return keyIndex(keys, anchor.after) + 1;
386
- };
387
- const at = (keys, position) => position <= 0 ? { at: "start" } : { after: keyAt(keys, position - 1) };
388
- const valid = (keys, anchor) => {
389
- if (!anchor) return true;
390
- if (typeof anchor !== "object" || anchor === null) return false;
391
- if (Number("at" in anchor) + Number("before" in anchor) + Number("after" in anchor) !== 1) return false;
392
- if ("at" in anchor) return anchor.at === "start" || anchor.at === "end";
393
- return keyIndex(keys, "before" in anchor ? anchor.before : anchor.after) >= 0;
394
- };
395
- const afterRemove = (keys, removedIndex, anchor) => {
396
- const position = index(keys, anchor);
397
- return position > removedIndex ? position - 1 : position;
398
- };
399
- const validPositions = (length, positions) => {
400
- let previous = -1;
401
- for (let index = 0; index < positions.length; index += 1) {
402
- const position = positions[index];
403
- if (!Number.isInteger(position) || position < 0 || position <= previous || position > length + index) return false;
404
- previous = position;
405
- }
406
- return true;
407
- };
408
- const restore = (keys, inserted, positions) => {
409
- const currentLength = keys.length;
410
- if (inserted.length !== positions.length || !validPositions(currentLength, positions)) throw new Error("Ordered restore positions are invalid.");
411
- let readIndex = currentLength - 1;
412
- let insertedIndex = inserted.length - 1;
413
- keys.length = currentLength + inserted.length;
414
- for (let writeIndex = keys.length - 1; writeIndex >= 0; writeIndex -= 1) if (insertedIndex >= 0 && positions[insertedIndex] === writeIndex) {
415
- keys[writeIndex] = inserted[insertedIndex];
416
- insertedIndex -= 1;
417
- } else {
418
- keys[writeIndex] = keys[readIndex];
419
- readIndex -= 1;
420
- }
421
- };
457
+ const from = (operation, code, message) => at(operation.at, code, message, operation.type);
458
+ const input = (code, message) => at([], code, message);
422
459
  //#endregion
423
460
  //#region core/src/mutation/execute-entity.ts
424
461
  const resolveEntityCollection = (node, value) => {
@@ -463,13 +500,13 @@ const executeEntity = (target, operation, copyPayload) => {
463
500
  }
464
501
  if (collection.kind === "map" && (operation.anchor || operation.positions)) return rejected$4(operation, "invalid-anchor", "Map entries do not support ordering metadata.");
465
502
  if (ids && operation.positions) {
466
- if (operation.positions.length !== operation.entries.length || !validPositions(ids.length, operation.positions)) return rejected$4(operation, "invalid-operation", "Entity restore positions are invalid.");
467
- } else if (ids && !valid(ids, operation.anchor)) return rejected$4(operation, "invalid-anchor", "Collection anchor is invalid.");
503
+ if (operation.positions.length !== operation.entries.length || !require_runtime.validPositions(ids.length, operation.positions)) return rejected$4(operation, "invalid-operation", "Entity restore positions are invalid.");
504
+ } else if (ids && !require_runtime.valid(ids, operation.anchor)) return rejected$4(operation, "invalid-anchor", "Collection anchor is invalid.");
468
505
  for (const entry of operation.entries) byId[entry.id] = copyPayload ? require_ownership.cloneValue(entry.value, "canonical") : require_ownership.transferPayload(entry.value);
469
- if (ids) if (operation.positions) restore(ids, operation.entries.map((entry) => entry.id), operation.positions);
506
+ if (ids) if (operation.positions) require_runtime.restore(ids, operation.entries.map((entry) => entry.id), operation.positions);
470
507
  else if (!operation.anchor || "at" in operation.anchor && operation.anchor.at === "end") for (const entry of operation.entries) ids.push(entry.id);
471
508
  else {
472
- const insertion = index(ids, operation.anchor);
509
+ const insertion = require_runtime.index(ids, operation.anchor);
473
510
  const currentLength = ids.length;
474
511
  ids.length = currentLength + operation.entries.length;
475
512
  for (let index = currentLength - 1; index >= insertion; index -= 1) ids[index + operation.entries.length] = ids[index];
@@ -535,15 +572,15 @@ const executeEntity = (target, operation, copyPayload) => {
535
572
  const position = ids?.indexOf(operation.id) ?? -1;
536
573
  if (!exists) return rejected$4(operation, "missing-entity", `Entity '${operation.id}' does not exist.`);
537
574
  if (!ids || position < 0) return rejected$4(operation, "invalid-collection", `Collection index is missing '${operation.id}'.`);
538
- if (!valid(ids, operation.anchor)) return rejected$4(operation, "invalid-anchor", "Collection anchor is invalid.");
575
+ if (!require_runtime.valid(ids, operation.anchor)) return rejected$4(operation, "invalid-anchor", "Collection anchor is invalid.");
539
576
  if (operation.anchor && ("before" in operation.anchor && operation.anchor.before === operation.id || "after" in operation.anchor && operation.anchor.after === operation.id)) return rejected$4(operation, "invalid-anchor", "An entity cannot be moved relative to itself.");
540
- const nextIndex = afterRemove(ids, position, operation.anchor);
577
+ const nextIndex = require_runtime.afterRemove(ids, position, operation.anchor);
541
578
  if (nextIndex === position) return { status: "unchanged" };
542
579
  const inverse = {
543
580
  type: "entity.move",
544
581
  at: operation.at,
545
582
  id: operation.id,
546
- anchor: at(ids, position)
583
+ anchor: require_runtime.at(ids, position)
547
584
  };
548
585
  ids.splice(position, 1);
549
586
  ids.splice(nextIndex, 0, operation.id);
@@ -564,7 +601,7 @@ const executeList = (target, operation, copyPayload) => {
564
601
  if (!Array.isArray(target.value) && !absent) return rejected$3(operation, "invalid-address", "List target is invalid.");
565
602
  if (absent && operation.type !== "list.replace") return rejected$3(operation, "invalid-address", "Only list replacement can initialize an optional list.");
566
603
  const list = Array.isArray(target.value) ? target.value : [];
567
- const orderedKeys = keys(list, target.node.keyOf);
604
+ const orderedKeys = require_runtime.keys(list, target.node.keyOf);
568
605
  const own = (value) => copyPayload ? require_ownership.ownPayload(value) : value;
569
606
  if (operation.type === "list.replace") {
570
607
  if (operation.keys.length !== operation.value.length) return rejected$3(operation, "invalid-list-keys", "List replacement keys are invalid.");
@@ -599,8 +636,8 @@ const executeList = (target, operation, copyPayload) => {
599
636
  if (operation.type === "list.insert") {
600
637
  if (target.node.keyOf(operation.value) !== operation.key) return rejected$3(operation, "invalid-list-key", "List item key does not match schema.");
601
638
  if (orderedKeys.index(operation.key) >= 0) return rejected$3(operation, "duplicate-list-item", `List item '${operation.key}' already exists.`);
602
- if (!valid(orderedKeys, operation.anchor)) return rejected$3(operation, "invalid-anchor", "List anchor is invalid.");
603
- list.splice(index(orderedKeys, operation.anchor), 0, own(operation.value));
639
+ if (!require_runtime.valid(orderedKeys, operation.anchor)) return rejected$3(operation, "invalid-anchor", "List anchor is invalid.");
640
+ list.splice(require_runtime.index(orderedKeys, operation.anchor), 0, own(operation.value));
604
641
  return {
605
642
  status: "changed",
606
643
  inverse: [{
@@ -618,7 +655,7 @@ const executeList = (target, operation, copyPayload) => {
618
655
  at: operation.at,
619
656
  key: operation.key,
620
657
  value: require_ownership.cloneValue(list[position], "inverse"),
621
- anchor: at(orderedKeys, position)
658
+ anchor: require_runtime.at(orderedKeys, position)
622
659
  };
623
660
  list.splice(position, 1);
624
661
  return {
@@ -626,15 +663,15 @@ const executeList = (target, operation, copyPayload) => {
626
663
  inverse: [inverse]
627
664
  };
628
665
  }
629
- if (!valid(orderedKeys, operation.anchor)) return rejected$3(operation, "invalid-anchor", "List anchor is invalid.");
666
+ if (!require_runtime.valid(orderedKeys, operation.anchor)) return rejected$3(operation, "invalid-anchor", "List anchor is invalid.");
630
667
  if (operation.anchor && ("before" in operation.anchor && operation.anchor.before === operation.key || "after" in operation.anchor && operation.anchor.after === operation.key)) return rejected$3(operation, "invalid-anchor", "A list item cannot be moved relative to itself.");
631
- const nextIndex = afterRemove(orderedKeys, position, operation.anchor);
668
+ const nextIndex = require_runtime.afterRemove(orderedKeys, position, operation.anchor);
632
669
  if (nextIndex === position) return { status: "unchanged" };
633
670
  const inverse = {
634
671
  type: "list.move",
635
672
  at: operation.at,
636
673
  key: operation.key,
637
- anchor: at(orderedKeys, position)
674
+ anchor: require_runtime.at(orderedKeys, position)
638
675
  };
639
676
  const [entry] = list.splice(position, 1);
640
677
  list.splice(nextIndex, 0, entry);
@@ -817,7 +854,7 @@ const changeChanged = (change, value) => {
817
854
  return false;
818
855
  };
819
856
  const is = (value) => require_ownership.isRecord(value) && require_ownership.isRecord(value.nodes);
820
- const contains$1 = (tree, id) => has$1(tree.nodes, id);
857
+ const contains = (tree, id) => has$1(tree.nodes, id);
821
858
  const validate = (value) => {
822
859
  if (!is(value)) return false;
823
860
  const ids = Object.keys(value.nodes);
@@ -859,7 +896,6 @@ const documentTreeError = (node, value, address) => {
859
896
  }
860
897
  return;
861
898
  }
862
- if (node.kind === "single") return documentTreeError(node.value, value, address);
863
899
  if (node.kind === "variant") {
864
900
  if (!require_ownership.isRecord(value) || typeof value[node.tag] !== "string") return void 0;
865
901
  const variant = node.variants[value[node.tag]];
@@ -898,7 +934,7 @@ const replace = (current, operation) => {
898
934
  };
899
935
  };
900
936
  const insert = (tree, operation, value) => {
901
- if (contains$1(tree, operation.treeNodeId)) return rejected$2("duplicate-tree-node", `Tree node '${operation.treeNodeId}' already exists.`);
937
+ if (contains(tree, operation.treeNodeId)) return rejected$2("duplicate-tree-node", `Tree node '${operation.treeNodeId}' already exists.`);
902
938
  if (!validIndex(operation.index)) return rejected$2("invalid-tree-index", "Tree index is invalid.");
903
939
  if (tree.rootId === void 0) {
904
940
  if (operation.parentId !== void 0) return rejected$2("missing-tree-parent", `Tree parent '${operation.parentId}' does not exist.`);
@@ -1023,9 +1059,8 @@ const move = (tree, operation) => {
1023
1059
  if (!currentParent || parentId === void 0) return rejected$2("invalid-tree", "Tree parent links are inconsistent.");
1024
1060
  const originalIndex = childIndex(currentParent, operation.treeNodeId);
1025
1061
  if (originalIndex < 0) return rejected$2("invalid-tree", "Tree parent links are inconsistent.");
1026
- let nextIndex = Math.min(operation.index ?? nextParent.children.length, nextParent.children.length);
1027
1062
  currentParent.children.splice(originalIndex, 1);
1028
- if (parentId === operation.parentId && nextIndex > originalIndex) nextIndex -= 1;
1063
+ const nextIndex = Math.min(operation.index ?? nextParent.children.length, nextParent.children.length);
1029
1064
  if (parentId === operation.parentId && nextIndex === originalIndex) {
1030
1065
  currentParent.children.splice(originalIndex, 0, operation.treeNodeId);
1031
1066
  return { status: "unchanged" };
@@ -1129,6 +1164,16 @@ const executeValue = (target, operation, copyPayload) => {
1129
1164
  }
1130
1165
  if (operation.type === "variant.replace") {
1131
1166
  if (require_ownership.sameStructuralValue(target.value, operation.value)) return { status: "unchanged" };
1167
+ if (target.value === void 0 && target.node.optional) {
1168
+ target.parent[target.key] = own(operation.value);
1169
+ return {
1170
+ status: "changed",
1171
+ inverse: [{
1172
+ type: "value.clear",
1173
+ at: operation.at
1174
+ }]
1175
+ };
1176
+ }
1132
1177
  const inverse = {
1133
1178
  type: "variant.replace",
1134
1179
  at: operation.at,
@@ -1207,7 +1252,7 @@ const executeClear = (target, operation) => {
1207
1252
  issue: from(operation, "required-field", "Only optional values can be cleared.")
1208
1253
  };
1209
1254
  if (!hasOwn$1(target.parent, target.key)) return { status: "unchanged" };
1210
- if (target.node.kind !== "field" && target.node.kind !== "variant" && target.node.kind !== "dict" && target.node.kind !== "record" && target.node.kind !== "list" && target.node.kind !== "tree") return {
1255
+ if (target.node.kind !== "field" && target.node.kind !== "variant" && target.node.kind !== "dict" && target.node.kind !== "list" && target.node.kind !== "tree") return {
1211
1256
  status: "rejected",
1212
1257
  issue: from(operation, "invalid-operation", "This optional value has no clear operation.")
1213
1258
  };
@@ -1223,8 +1268,7 @@ const executeClear = (target, operation) => {
1223
1268
  at: operation.at,
1224
1269
  value: require_ownership.cloneValue(target.value, "inverse")
1225
1270
  };
1226
- case "dict":
1227
- case "record": return {
1271
+ case "dict": return {
1228
1272
  type: "dict.replace",
1229
1273
  at: operation.at,
1230
1274
  value: require_ownership.cloneValue(target.value, "inverse")
@@ -1263,7 +1307,7 @@ const execute = (root, operation, target, copyPayload) => {
1263
1307
  if (operation.type === "value.clear") return !target ? invalidTarget(operation) : executeClear(target, operation);
1264
1308
  if (operation.type === "field.set" || operation.type === "field.clear") return !target || target.node.kind !== "field" ? invalidTarget(operation) : executeValue(target, operation, copyPayload);
1265
1309
  if (operation.type === "variant.replace") return !target || target.node.kind !== "variant" ? invalidTarget(operation) : executeValue(target, operation, copyPayload);
1266
- if (operation.type === "dict.set" || operation.type === "dict.delete" || operation.type === "dict.replace") return !target || target.node.kind !== "dict" && target.node.kind !== "record" ? invalidTarget(operation) : executeValue(target, operation, copyPayload);
1310
+ if (operation.type === "dict.set" || operation.type === "dict.delete" || operation.type === "dict.replace") return !target || target.node.kind !== "dict" ? invalidTarget(operation) : executeValue(target, operation, copyPayload);
1267
1311
  if (operation.type === "entity.create" || operation.type === "entity.remove" || operation.type === "entity.move") return !target || target.node.kind !== "table" && target.node.kind !== "map" ? invalidTarget(operation) : executeEntity(target, operation, copyPayload);
1268
1312
  if (operation.type === "list.insert" || operation.type === "list.move" || operation.type === "list.remove" || operation.type === "list.replace") return !target || target.node.kind !== "list" ? invalidTarget(operation) : executeList(target, operation, copyPayload);
1269
1313
  if (operation.type === "tree.insert" || operation.type === "tree.move" || operation.type === "tree.remove" || operation.type === "tree.set" || operation.type === "tree.replace") return !target || target.node.kind !== "tree" ? invalidTarget(operation) : executeTree(root, target, operation, copyPayload);
@@ -1276,7 +1320,7 @@ const execute = (root, operation, target, copyPayload) => {
1276
1320
  //#region core/src/mutation/journal.ts
1277
1321
  const indexNode = () => ({ children: /* @__PURE__ */ new Map() });
1278
1322
  const hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
1279
- const sameAddress$1 = (left, right) => {
1323
+ const sameAddress = (left, right) => {
1280
1324
  if (left.length !== right.length) return false;
1281
1325
  for (let index = 0; index < left.length; index += 1) if (left[index] !== right[index]) return false;
1282
1326
  return true;
@@ -1375,7 +1419,7 @@ const restoreEntity = (value, subject) => {
1375
1419
  };
1376
1420
  const restoreRootSubject = (value, subject) => {
1377
1421
  if (subject.kind === "value") return subject.before.status === "present" ? subject.before.value : void 0;
1378
- if (subject.kind === "variant") return subject.before;
1422
+ if (subject.kind === "variant") return subject.before.status === "present" ? subject.before.value : void 0;
1379
1423
  if (subject.kind === "dict") {
1380
1424
  if (require_ownership.isRecord(value)) restoreDict(value, subject.state);
1381
1425
  return value;
@@ -1391,14 +1435,14 @@ const restoreRootSubject = (value, subject) => {
1391
1435
  return restoreChange(value, subject.state);
1392
1436
  };
1393
1437
  const restoreSubject = (value, prefix, subject) => {
1394
- if (sameAddress$1(prefix, subject.address)) return restoreRootSubject(value, subject);
1438
+ if (sameAddress(prefix, subject.address)) return restoreRootSubject(value, subject);
1395
1439
  const address = subject.address.slice(prefix.length);
1396
1440
  if (subject.kind === "value") {
1397
1441
  writePresence(value, address, subject.before);
1398
1442
  return value;
1399
1443
  }
1400
1444
  if (subject.kind === "variant") {
1401
- writeContainer(value, address, subject.before);
1445
+ writePresence(value, address, subject.before);
1402
1446
  return value;
1403
1447
  }
1404
1448
  const current = require_runtime.read(value, address);
@@ -1499,7 +1543,11 @@ const analyzeEntity = (root, subject) => {
1499
1543
  };
1500
1544
  const subjectChanged = (root, subject) => {
1501
1545
  if (subject.kind === "value") return valueChanged(root, subject);
1502
- if (subject.kind === "variant") return !require_ownership.sameStructuralValue(subject.before, require_runtime.read(root, subject.address));
1546
+ if (subject.kind === "variant") {
1547
+ const target = require_runtime.locate(root, subject.address);
1548
+ const exists = !!target && hasOwn(target.parent, target.key);
1549
+ return subject.before.status === "absent" ? exists : !exists || !require_ownership.sameStructuralValue(subject.before.value, target?.value);
1550
+ }
1503
1551
  if (subject.kind === "dict") return dictChanged(root, subject);
1504
1552
  if (subject.kind === "list") return listChanged(root, subject);
1505
1553
  return changeChanged(subject.state, require_runtime.read(root, subject.address));
@@ -1508,13 +1556,13 @@ const listOrderBefore = (value, node, inverse) => {
1508
1556
  const order = value.map(node.keyOf);
1509
1557
  if (inverse.type === "list.remove") return order.filter((key) => key !== inverse.key);
1510
1558
  if (inverse.type === "list.insert") {
1511
- order.splice(index(order, inverse.anchor), 0, inverse.key);
1559
+ order.splice(require_runtime.index(order, inverse.anchor), 0, inverse.key);
1512
1560
  return order;
1513
1561
  }
1514
1562
  if (inverse.type === "list.move") {
1515
1563
  const position = order.indexOf(inverse.key);
1516
1564
  if (position >= 0) order.splice(position, 1);
1517
- order.splice(index(order, inverse.anchor), 0, inverse.key);
1565
+ order.splice(require_runtime.index(order, inverse.anchor), 0, inverse.key);
1518
1566
  }
1519
1567
  return order;
1520
1568
  };
@@ -1556,12 +1604,12 @@ const restoreEntityOrder = (order, inverses) => {
1556
1604
  continue;
1557
1605
  }
1558
1606
  if (inverse.kind === "restore") {
1559
- restore(order, inverse.ids, inverse.positions);
1607
+ require_runtime.restore(order, inverse.ids, inverse.positions);
1560
1608
  continue;
1561
1609
  }
1562
1610
  const position = order.indexOf(inverse.id);
1563
- if (position < 0 || !valid(order, inverse.anchor)) throw new Error(`Entity order inverse cannot restore '${inverse.id}'.`);
1564
- const nextIndex = afterRemove(order, position, inverse.anchor);
1611
+ if (position < 0 || !require_runtime.valid(order, inverse.anchor)) throw new Error(`Entity order inverse cannot restore '${inverse.id}'.`);
1612
+ const nextIndex = require_runtime.afterRemove(order, position, inverse.anchor);
1565
1613
  order.splice(position, 1);
1566
1614
  order.splice(nextIndex, 0, inverse.id);
1567
1615
  }
@@ -1618,7 +1666,7 @@ const createChangeJournal = (root) => {
1618
1666
  const candidates = buckets.get(addressHash) ?? [];
1619
1667
  for (const subject of candidates) {
1620
1668
  require_ownership.profile.journal.comparison();
1621
- if (subject.kind === kind && sameAddress$1(subject.address, address)) return subject;
1669
+ if (subject.kind === kind && sameAddress(subject.address, address)) return subject;
1622
1670
  }
1623
1671
  }
1624
1672
  const ownerOf = (address) => {
@@ -1661,11 +1709,11 @@ const createChangeJournal = (root) => {
1661
1709
  const recordVariant = (resolved, operation, inverse) => {
1662
1710
  if (find("variant", operation.at, resolved.addressHash)) return;
1663
1711
  const first = inverse[0];
1664
- if (first?.type !== "variant.replace") return inverseMismatch(operation);
1712
+ if (first?.type !== "variant.replace" && first?.type !== "value.clear") return inverseMismatch(operation);
1665
1713
  add({
1666
1714
  ...base(resolved, operation),
1667
1715
  kind: "variant",
1668
- before: absorb(first.value, operation.at)
1716
+ before: first.type === "value.clear" ? absent : present(absorb(first.value, operation.at))
1669
1717
  });
1670
1718
  };
1671
1719
  const recordDict = (resolved, operation, inverse) => {
@@ -1829,6 +1877,10 @@ const createChangeJournal = (root) => {
1829
1877
  record: (resolved, operation, inverse) => {
1830
1878
  require_ownership.profile.batch.journalRecord();
1831
1879
  if (ownerOf(operation.at)) return;
1880
+ if (operation.type === "value.clear" && resolved.node.kind === "variant") {
1881
+ recordVariant(resolved, operation, inverse);
1882
+ return;
1883
+ }
1832
1884
  if (operation.type === "field.set" || operation.type === "field.clear" || operation.type === "value.clear") {
1833
1885
  recordValue(resolved, operation, inverse);
1834
1886
  return;
@@ -1870,7 +1922,7 @@ const createChangeJournal = (root) => {
1870
1922
  const changeAt = (address, addressHash) => {
1871
1923
  const candidates = collectionBuckets.get(addressHash) ?? [];
1872
1924
  collectionBuckets.set(addressHash, candidates);
1873
- let change = candidates.find((entry) => sameAddress$1(entry.address, address));
1925
+ let change = candidates.find((entry) => sameAddress(entry.address, address));
1874
1926
  if (!change) {
1875
1927
  change = {
1876
1928
  address,
@@ -1914,7 +1966,7 @@ const createChangeJournal = (root) => {
1914
1966
  const has = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
1915
1967
  const stringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
1916
1968
  const positions = (value) => Array.isArray(value) && value.every((entry) => Number.isInteger(entry) && entry >= 0);
1917
- const address$1 = (value) => stringArray(value);
1969
+ const address = (value) => stringArray(value);
1918
1970
  const anchor = (value) => {
1919
1971
  if (!require_ownership.isRecord(value)) return false;
1920
1972
  if (Number(has(value, "at")) + Number(has(value, "before")) + Number(has(value, "after")) !== 1) return false;
@@ -1935,7 +1987,7 @@ const rejected = (code, message) => ({
1935
1987
  });
1936
1988
  const decode = (input) => {
1937
1989
  if (!require_ownership.isRecord(input)) return rejected("invalid-operation", "Operation must be an object.");
1938
- if (!address$1(input.at)) return rejected("invalid-address", "Operation address is malformed.");
1990
+ if (!address(input.at)) return rejected("invalid-address", "Operation address is malformed.");
1939
1991
  if (typeof input.type !== "string") return rejected("invalid-operation", "Operation type must be a string.");
1940
1992
  switch (input.type) {
1941
1993
  case "field.set":
@@ -2111,192 +2163,6 @@ const mutateOperations = (root, schema, operations, options = {}) => {
2111
2163
  return session.finish();
2112
2164
  };
2113
2165
  //#endregion
2114
- //#region core/src/mutation/footprint.ts
2115
- const sameAddress = (left, right) => left.length === right.length && left.every((segment, index) => segment === right[index]);
2116
- const containsAddress = (parent, child) => parent.length <= child.length && parent.every((segment, index) => segment === child[index]);
2117
- const address = (value) => Array.isArray(value) && value.every((segment) => typeof segment === "string") ? Object.freeze(value.slice()) : void 0;
2118
- const targetKey = (target) => {
2119
- const at = target.at.join("\0");
2120
- if (target.kind === "dictionary-key" || target.kind === "list-item") return `${target.kind}:${at}:${target.key}`;
2121
- if (target.kind === "entity" || target.kind === "tree-node") return `${target.kind}:${at}:${target.id}`;
2122
- return `${target.kind}:${at}`;
2123
- };
2124
- const freezeTarget = (target) => Object.freeze({
2125
- ...target,
2126
- at: Object.freeze(target.at.slice())
2127
- });
2128
- const add = (targets, target) => {
2129
- const stable = freezeTarget(target);
2130
- targets.set(targetKey(stable), stable);
2131
- };
2132
- const commandFootprint = (operations) => {
2133
- const targets = /* @__PURE__ */ new Map();
2134
- for (const operation of operations) switch (operation.type) {
2135
- case "field.set":
2136
- case "field.clear":
2137
- case "value.clear":
2138
- case "variant.replace":
2139
- add(targets, {
2140
- kind: "value",
2141
- at: operation.at
2142
- });
2143
- break;
2144
- case "dict.replace":
2145
- add(targets, {
2146
- kind: "dictionary",
2147
- at: operation.at
2148
- });
2149
- break;
2150
- case "dict.set":
2151
- case "dict.delete":
2152
- add(targets, {
2153
- kind: "dictionary-key",
2154
- at: operation.at,
2155
- key: operation.key
2156
- });
2157
- break;
2158
- case "entity.create":
2159
- add(targets, {
2160
- kind: "collection",
2161
- at: operation.at
2162
- });
2163
- for (const entry of operation.entries) add(targets, {
2164
- kind: "entity",
2165
- at: operation.at,
2166
- id: entry.id
2167
- });
2168
- break;
2169
- case "entity.remove":
2170
- add(targets, {
2171
- kind: "collection",
2172
- at: operation.at
2173
- });
2174
- for (const id of operation.ids) add(targets, {
2175
- kind: "entity",
2176
- at: operation.at,
2177
- id
2178
- });
2179
- break;
2180
- case "entity.move":
2181
- add(targets, {
2182
- kind: "collection",
2183
- at: operation.at
2184
- });
2185
- add(targets, {
2186
- kind: "entity",
2187
- at: operation.at,
2188
- id: operation.id
2189
- });
2190
- break;
2191
- case "list.insert":
2192
- case "list.move":
2193
- case "list.remove":
2194
- add(targets, {
2195
- kind: "list",
2196
- at: operation.at
2197
- });
2198
- add(targets, {
2199
- kind: "list-item",
2200
- at: operation.at,
2201
- key: operation.key
2202
- });
2203
- break;
2204
- case "list.replace":
2205
- add(targets, {
2206
- kind: "list",
2207
- at: operation.at
2208
- });
2209
- for (const key of operation.keys) add(targets, {
2210
- kind: "list-item",
2211
- at: operation.at,
2212
- key
2213
- });
2214
- break;
2215
- case "tree.insert":
2216
- case "tree.move":
2217
- case "tree.remove":
2218
- case "tree.set":
2219
- add(targets, {
2220
- kind: "tree",
2221
- at: operation.at
2222
- });
2223
- add(targets, {
2224
- kind: "tree-node",
2225
- at: operation.at,
2226
- id: operation.treeNodeId
2227
- });
2228
- break;
2229
- case "tree.replace":
2230
- add(targets, {
2231
- kind: "tree",
2232
- at: operation.at
2233
- });
2234
- break;
2235
- }
2236
- return Object.freeze(Array.from(targets.values()));
2237
- };
2238
- const overlapsValueAndEntity = (value, entity) => containsAddress([...entity.at, entity.id], value.at) || containsAddress(value.at, [...entity.at, entity.id]);
2239
- const targetsOverlap = (left, right) => {
2240
- if (left.kind === "value" && right.kind === "value") return containsAddress(left.at, right.at) || containsAddress(right.at, left.at);
2241
- if (left.kind === "value" && right.kind === "entity") return overlapsValueAndEntity(left, right);
2242
- if (left.kind === "entity" && right.kind === "value") return overlapsValueAndEntity(right, left);
2243
- if (left.kind === "dictionary" && right.kind === "dictionary") return sameAddress(left.at, right.at);
2244
- if (left.kind === "dictionary" && right.kind === "dictionary-key") return sameAddress(left.at, right.at);
2245
- if (left.kind === "dictionary-key" && right.kind === "dictionary") return sameAddress(left.at, right.at);
2246
- if (left.kind === "dictionary-key" && right.kind === "dictionary-key") return sameAddress(left.at, right.at) && left.key === right.key;
2247
- if (left.kind === "collection" && right.kind === "collection") return sameAddress(left.at, right.at);
2248
- if (left.kind === "collection" && right.kind === "entity") return sameAddress(left.at, right.at);
2249
- if (left.kind === "entity" && right.kind === "collection") return sameAddress(left.at, right.at);
2250
- if (left.kind === "entity" && right.kind === "entity") return sameAddress(left.at, right.at) && left.id === right.id;
2251
- if (left.kind === "list" && (right.kind === "list" || right.kind === "list-item")) return sameAddress(left.at, right.at);
2252
- if (right.kind === "list" && left.kind === "list-item") return sameAddress(left.at, right.at);
2253
- if (left.kind === "list-item" && right.kind === "list-item") return sameAddress(left.at, right.at) && left.key === right.key;
2254
- if (left.kind === "tree" && (right.kind === "tree" || right.kind === "tree-node")) return sameAddress(left.at, right.at);
2255
- if (right.kind === "tree" && left.kind === "tree-node") return sameAddress(left.at, right.at);
2256
- if (left.kind === "tree-node" && right.kind === "tree-node") return sameAddress(left.at, right.at) && left.id === right.id;
2257
- return false;
2258
- };
2259
- const footprintsOverlap = (left, right) => left.some((leftTarget) => right.some((rightTarget) => targetsOverlap(leftTarget, rightTarget)));
2260
- const decodedTarget = (value) => {
2261
- if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
2262
- const record = value;
2263
- const at = address(record.at);
2264
- if (!at || typeof record.kind !== "string") return void 0;
2265
- switch (record.kind) {
2266
- case "value":
2267
- case "dictionary":
2268
- case "collection":
2269
- case "list":
2270
- case "tree": return freezeTarget({
2271
- kind: record.kind,
2272
- at
2273
- });
2274
- case "dictionary-key":
2275
- case "list-item": return typeof record.key === "string" ? freezeTarget({
2276
- kind: record.kind,
2277
- at,
2278
- key: record.key
2279
- }) : void 0;
2280
- case "entity":
2281
- case "tree-node": return typeof record.id === "string" ? freezeTarget({
2282
- kind: record.kind,
2283
- at,
2284
- id: record.id
2285
- }) : void 0;
2286
- default: return;
2287
- }
2288
- };
2289
- const decodeCommandFootprint = (value) => {
2290
- if (!Array.isArray(value)) return void 0;
2291
- const targets = /* @__PURE__ */ new Map();
2292
- for (const entry of value) {
2293
- const target = decodedTarget(entry);
2294
- if (!target) return void 0;
2295
- targets.set(targetKey(target), target);
2296
- }
2297
- return Object.freeze(Array.from(targets.values()));
2298
- };
2299
- //#endregion
2300
2166
  //#region core/src/runtime.ts
2301
2167
  var RejectedUpdate = class extends Error {
2302
2168
  issues;
@@ -2308,6 +2174,7 @@ var RejectedUpdate = class extends Error {
2308
2174
  const EMPTY = Object.freeze([]);
2309
2175
  const publishDiagnostic = (value) => Object.freeze({
2310
2176
  ...value,
2177
+ source: "application",
2311
2178
  ...value.address === void 0 ? {} : { address: Object.freeze(value.address.slice()) }
2312
2179
  });
2313
2180
  const createDocument = (input) => {
@@ -2368,7 +2235,19 @@ const createDocument = (input) => {
2368
2235
  const history = createHistory({
2369
2236
  capacity: input.history === false ? 0 : Math.max(0, input.history?.capacity ?? 100),
2370
2237
  revision: () => revision,
2371
- apply: (operations) => applyBatch(operations, "history", false)
2238
+ apply: (operations) => applyBatch(operations, "history", false),
2239
+ assertIdle: () => {
2240
+ if (state.disposed) throw new require_runtime.DocumentDisposedError();
2241
+ if (busy || require_runtime.accessOf(runtime).projectionLocks) throw new require_runtime.DocumentReentrancyError();
2242
+ },
2243
+ notify: (run) => {
2244
+ busy = true;
2245
+ try {
2246
+ return run();
2247
+ } finally {
2248
+ busy = false;
2249
+ }
2250
+ }
2372
2251
  });
2373
2252
  const publish = (batch, source, kind, recordHistory) => {
2374
2253
  revision += 1;
@@ -2382,10 +2261,12 @@ const createDocument = (input) => {
2382
2261
  });
2383
2262
  if (kind === "replace" || source === "remote") history.invalidate();
2384
2263
  else if (recordHistory && (source === "local" || source === "system")) history.record(batch.operations, batch.inverse);
2264
+ else if (source === "history") history.publish();
2265
+ else history.endGroup();
2385
2266
  busy = true;
2386
2267
  let observerErrors;
2387
2268
  try {
2388
- observerErrors = require_runtime.notify(notification, commit);
2269
+ observerErrors = require_runtime.notify(notification, commit, history.flush);
2389
2270
  } finally {
2390
2271
  busy = false;
2391
2272
  }
@@ -2500,7 +2381,7 @@ const createDocument = (input) => {
2500
2381
  operations: batch.operations,
2501
2382
  inverse: batch.inverse,
2502
2383
  impact,
2503
- footprint: commandFootprint(batch.operations),
2384
+ footprint: require_runtime.commandFootprint(batch.operations),
2504
2385
  reports
2505
2386
  };
2506
2387
  } catch (error) {
@@ -2528,7 +2409,7 @@ const createDocument = (input) => {
2528
2409
  const invalidTree = invalidDocument(input.schema, document);
2529
2410
  if (invalidTree) return {
2530
2411
  status: "rejected",
2531
- issues: [at$1(invalidTree, "invalid-tree", "Document replacement contains an invalid tree.")],
2412
+ issues: [at(invalidTree, "invalid-tree", "Document replacement contains an invalid tree.")],
2532
2413
  revision
2533
2414
  };
2534
2415
  if (require_ownership.deepEqual(state.document, document)) return {
@@ -2563,7 +2444,7 @@ const createDocument = (input) => {
2563
2444
  try {
2564
2445
  require_runtime.disposeNotification(notification);
2565
2446
  } finally {
2566
- history.api.clear();
2447
+ history.dispose();
2567
2448
  require_driver.disposeRuntimeDriver(runtime);
2568
2449
  }
2569
2450
  }
@@ -2571,6 +2452,7 @@ const createDocument = (input) => {
2571
2452
  require_runtime.bindRuntimeAccess(runtime, state);
2572
2453
  require_driver.bindRuntimeDriver(runtime);
2573
2454
  notification = require_runtime.createNotification(runtime);
2455
+ require_runtime.bindDocumentReadable(history.api, runtime);
2574
2456
  return runtime;
2575
2457
  };
2576
2458
  //#endregion
@@ -2594,26 +2476,16 @@ exports.DocumentReentrancyError = require_runtime.DocumentReentrancyError;
2594
2476
  exports.ProjectionDisposedError = require_runtime.ProjectionDisposedError;
2595
2477
  exports.ProjectionError = require_runtime.ProjectionError;
2596
2478
  exports.asReadable = asReadable;
2597
- exports.commandFootprint = commandFootprint;
2598
- exports.contains = require_runtime.contains;
2599
2479
  exports.createDocument = createDocument;
2600
2480
  exports.createProjectionRuntime = require_runtime.createProjectionRuntime;
2601
- exports.debugKey = require_runtime.debugKey;
2602
- exports.decodeCommandFootprint = decodeCommandFootprint;
2603
2481
  exports.dict = require_runtime.dict;
2604
2482
  exports.field = require_runtime.field;
2605
- exports.footprintsOverlap = footprintsOverlap;
2606
2483
  exports.list = require_runtime.list;
2607
2484
  exports.map = require_runtime.map;
2608
2485
  exports.object = require_runtime.object;
2609
2486
  exports.optional = require_runtime.optional;
2610
- exports.overlaps = require_runtime.overlaps;
2611
- exports.readAddress = require_runtime.read;
2612
- exports.record = require_runtime.record;
2613
- exports.resolveAddress = require_runtime.resolveAddress;
2614
2487
  exports.schema = require_runtime.schema;
2615
2488
  exports.select = select;
2616
- exports.single = require_runtime.single;
2617
2489
  exports.table = require_runtime.table;
2618
2490
  Object.defineProperty(exports, "target", {
2619
2491
  enumerable: true,