doxum 0.1.21 → 0.1.22

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 (65) hide show
  1. package/README.md +21 -2
  2. package/dist/{access-BeSV5ve-.js → access-CZXv_DIF.js} +179 -37
  3. package/dist/access-CZXv_DIF.js.map +1 -0
  4. package/dist/{access-Bienf28h.cjs → access-D64MFRSm.cjs} +228 -38
  5. package/dist/access-D64MFRSm.cjs.map +1 -0
  6. package/dist/{advanced-COFJtWMT.js → advanced-BTStm2cW.js} +29 -25
  7. package/dist/advanced-BTStm2cW.js.map +1 -0
  8. package/dist/{advanced-FgdTwu5b.d.ts → advanced-CqrR_4dh.d.ts} +3 -3
  9. package/dist/{advanced-DfKc7TZR.d.cts → advanced-CyR5o3Xr.d.cts} +3 -3
  10. package/dist/{advanced-BRL5pN0y.cjs → advanced-GKZ-CZ6a.cjs} +29 -25
  11. package/dist/advanced-GKZ-CZ6a.cjs.map +1 -0
  12. package/dist/advanced.cjs +1 -1
  13. package/dist/advanced.d.cts +1 -1
  14. package/dist/advanced.d.ts +1 -1
  15. package/dist/advanced.js +1 -1
  16. package/dist/{contract-KG5XnQZt.d.ts → contract-CRrZ-3sF.d.cts} +64 -34
  17. package/dist/{contract-CdmDHRUq.d.cts → contract-CxiNcqMn.d.ts} +64 -34
  18. package/dist/{driver-Djr3BVvo.cjs → driver-BC06FEMF.cjs} +2 -2
  19. package/dist/{driver-Djr3BVvo.cjs.map → driver-BC06FEMF.cjs.map} +1 -1
  20. package/dist/{driver-CLYJOGDQ.js → driver-BqRjwFmU.js} +2 -2
  21. package/dist/{driver-CLYJOGDQ.js.map → driver-BqRjwFmU.js.map} +1 -1
  22. package/dist/index.cjs +480 -117
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +2 -2
  25. package/dist/index.d.ts +2 -2
  26. package/dist/index.js +478 -115
  27. package/dist/index.js.map +1 -1
  28. package/dist/{integration-Z6MsfFI7.cjs → integration-BqDw7e2w.cjs} +3 -4
  29. package/dist/{integration-Z6MsfFI7.cjs.map → integration-BqDw7e2w.cjs.map} +1 -1
  30. package/dist/{integration-C4Isp8lJ.js → integration-CSXaF8HP.js} +2 -3
  31. package/dist/{integration-C4Isp8lJ.js.map → integration-CSXaF8HP.js.map} +1 -1
  32. package/dist/integration.cjs +5 -4
  33. package/dist/integration.d.cts +1 -1
  34. package/dist/integration.d.ts +1 -1
  35. package/dist/integration.js +4 -3
  36. package/dist/{issue-W0hT8u8D.js → issue-9U6YLYz3.js} +11 -6
  37. package/dist/issue-9U6YLYz3.js.map +1 -0
  38. package/dist/{issue-DjK1xp5K.cjs → issue-Bo0FIO3b.cjs} +11 -6
  39. package/dist/issue-Bo0FIO3b.cjs.map +1 -0
  40. package/dist/local-sync.cjs +2 -2
  41. package/dist/local-sync.d.cts +1 -1
  42. package/dist/local-sync.d.ts +1 -1
  43. package/dist/local-sync.js +2 -2
  44. package/dist/{notification-Bkjau6B6.js → notification-CrZHVx3a.js} +3 -59
  45. package/dist/notification-CrZHVx3a.js.map +1 -0
  46. package/dist/{notification-DJfouMEb.cjs → notification-DFoA9bQY.cjs} +3 -77
  47. package/dist/notification-DFoA9bQY.cjs.map +1 -0
  48. package/dist/react.cjs +4 -3
  49. package/dist/react.cjs.map +1 -1
  50. package/dist/react.js +3 -2
  51. package/dist/react.js.map +1 -1
  52. package/package.json +1 -1
  53. package/skills/doxum-runtime/SKILL.md +5 -0
  54. package/skills/doxum-runtime/references/guide.en.md +9 -0
  55. package/skills/doxum-runtime/references/guide.zh-CN.md +8 -0
  56. package/skills/doxum-runtime/references/projections.en.md +5 -0
  57. package/skills/doxum-runtime/references/projections.zh-CN.md +5 -0
  58. package/dist/access-BeSV5ve-.js.map +0 -1
  59. package/dist/access-Bienf28h.cjs.map +0 -1
  60. package/dist/advanced-BRL5pN0y.cjs.map +0 -1
  61. package/dist/advanced-COFJtWMT.js.map +0 -1
  62. package/dist/issue-DjK1xp5K.cjs.map +0 -1
  63. package/dist/issue-W0hT8u8D.js.map +0 -1
  64. package/dist/notification-Bkjau6B6.js.map +0 -1
  65. package/dist/notification-DJfouMEb.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,13 +1,11 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_issue = require("./issue-DjK1xp5K.cjs");
3
- const require_access = require("./access-Bienf28h.cjs");
4
- const require_advanced = require("./advanced-BRL5pN0y.cjs");
5
- const require_notification = require("./notification-DJfouMEb.cjs");
6
- const require_driver = require("./driver-Djr3BVvo.cjs");
2
+ const require_issue = require("./issue-Bo0FIO3b.cjs");
3
+ const require_access = require("./access-D64MFRSm.cjs");
4
+ const require_advanced = require("./advanced-GKZ-CZ6a.cjs");
5
+ const require_driver = require("./driver-BC06FEMF.cjs");
6
+ const require_notification = require("./notification-DFoA9bQY.cjs");
7
7
  //#region core/src/impact.ts
8
8
  const queries = /* @__PURE__ */ new WeakMap();
9
- const affectsTarget = (impact, value) => queries.get(impact).affects(value);
10
- const collectionImpact = (impact, selector) => queries.get(impact).collection(selector);
11
9
  const createImpact = (schema, changes) => {
12
10
  const reset = changes.changes.some((change) => change.kind === "reset");
13
11
  let values;
@@ -17,10 +15,7 @@ const createImpact = (schema, changes) => {
17
15
  require_issue.profile.impact.index();
18
16
  values = new require_issue.AddressIndex();
19
17
  orders = new require_issue.AddressIndex();
20
- for (const change of changes.changes) if (change.kind === "members") {
21
- for (const member of change.members) values.add(change.at, true, member.key);
22
- if (change.order) orders.add(change.at, true);
23
- } else if (change.kind === "tree") values.add(change.at, true);
18
+ require_access.visitChangedLocations(changes, (at) => values.add(at, true), (at) => orders.add(at, true));
24
19
  }
25
20
  return values;
26
21
  };
@@ -28,13 +23,13 @@ const createImpact = (schema, changes) => {
28
23
  const implementation = {
29
24
  affects(value) {
30
25
  require_issue.profile.impact.affects();
31
- if (!require_notification.belongs(value, schema)) return false;
26
+ if (!require_access.belongs(value, schema)) return false;
32
27
  if (reset) return true;
33
- return require_notification.affected(value, index(), orders);
28
+ return require_access.affected(value, index(), orders);
34
29
  },
35
30
  collection(selector) {
36
31
  if (selector.schema !== schema) throw new TypeError("Collection belongs to another root model.");
37
- const key = JSON.stringify(selector.address), cached = cache.get(key);
32
+ const key = JSON.stringify(require_access.indexedAddress(selector)), cached = cache.get(key);
38
33
  if (cached) return cached;
39
34
  if (reset) {
40
35
  const result = { kind: "reset" };
@@ -42,6 +37,7 @@ const createImpact = (schema, changes) => {
42
37
  return result;
43
38
  }
44
39
  const at = selector.address;
40
+ const tree = selector.tree;
45
41
  const added = /* @__PURE__ */ new Set(), removed = /* @__PURE__ */ new Set(), updated = /* @__PURE__ */ new Set();
46
42
  let orderChanged = false;
47
43
  for (const change of changes.changes) {
@@ -71,6 +67,12 @@ const createImpact = (schema, changes) => {
71
67
  continue;
72
68
  }
73
69
  if (change.kind === "tree" && require_issue.contains(change.at, at)) {
70
+ if (tree?.kind === "nodes" && change.at.length === at.length && require_issue.contains(at, change.at)) {
71
+ for (const node of change.nodes) if (node.kind === "added") added.add(node.id);
72
+ else if (node.kind === "removed") removed.add(node.id);
73
+ else updated.add(node.id);
74
+ continue;
75
+ }
74
76
  const result = { kind: "reset" };
75
77
  cache.set(key, result);
76
78
  return result;
@@ -309,10 +311,6 @@ const forgetMember = (group, key) => {
309
311
  }
310
312
  };
311
313
  const emptyGroup = (group) => !group.order && (group.layout === "fixed" ? !group.members.some(Boolean) : !group.members?.size);
312
- const copyNode = (node) => ({
313
- ...node,
314
- children: [...node.children]
315
- });
316
314
  const transition = (node, key, beforePresent, before, afterPresent, after) => {
317
315
  if (beforePresent === afterPresent && (!beforePresent || Object.is(before, after))) return;
318
316
  if (node.kind !== "field" && beforePresent === afterPresent && require_access.equalValue(node, before, after)) return;
@@ -403,7 +401,7 @@ const restore = (fact, schema, root, skip = 0) => {
403
401
  const tree = location.value;
404
402
  if (fact.before === null) delete tree.rootId;
405
403
  else tree.rootId = fact.before;
406
- for (const [id, node] of fact.nodes) installMember(tree.nodes, id, node !== void 0, node && copyNode(node));
404
+ for (const [id, node] of fact.nodes) installMember(tree.nodes, id, node !== void 0, node && require_access.copyTreeNode(node));
407
405
  }
408
406
  return root;
409
407
  };
@@ -442,17 +440,16 @@ const sealMembers = (fact, changes) => {
442
440
  const sealTree = (fact, state, changes) => {
443
441
  const location = require_issue.resolveValue(state.schema, state.document, fact.at);
444
442
  const tree = location?.value;
445
- const node = location?.node;
446
- if (node?.kind !== "tree") throw new Error("Tree schema disappeared before sealing.");
443
+ if ((location?.node)?.kind !== "tree") throw new Error("Tree schema disappeared before sealing.");
447
444
  const nodes = [];
448
445
  for (const [id, before] of fact.nodes) {
449
446
  const after = Object.hasOwn(tree.nodes, id) ? tree.nodes[id] : void 0;
450
447
  if (!before && !after) continue;
451
- if (before && after && before.parentId === after.parentId && require_issue.equal(before.children, after.children) && Object.hasOwn(before, "value") === Object.hasOwn(after, "value") && require_access.equalValue(node.value, before.value, after.value)) continue;
448
+ if (before && after && require_access.equalTreeNode(before, after)) continue;
452
449
  nodes.push(!before ? {
453
450
  id,
454
451
  kind: "added",
455
- after: copyNode(after)
452
+ after: require_access.copyTreeNode(after)
456
453
  } : !after ? {
457
454
  id,
458
455
  kind: "removed",
@@ -461,7 +458,7 @@ const sealTree = (fact, state, changes) => {
461
458
  id,
462
459
  kind: "updated",
463
460
  before,
464
- after: copyNode(after)
461
+ after: require_access.copyTreeNode(after)
465
462
  });
466
463
  }
467
464
  const after = tree.rootId ?? null;
@@ -643,7 +640,7 @@ var ChangeRecorder = class {
643
640
  }
644
641
  if (id !== void 0 && !fact.nodes.has(id)) {
645
642
  require_issue.profile.recorder("treeNodes");
646
- fact.nodes.set(id, Object.hasOwn(tree.nodes, id) ? copyNode(tree.nodes[id]) : void 0);
643
+ fact.nodes.set(id, Object.hasOwn(tree.nodes, id) ? require_access.copyTreeNode(tree.nodes[id]) : void 0);
647
644
  }
648
645
  }
649
646
  rollback() {
@@ -830,12 +827,13 @@ function apply(session, changes, direction) {
830
827
  else current.rootId = root;
831
828
  for (const item of change.nodes) {
832
829
  const next = side === "after" ? item.kind !== "removed" ? item.after : void 0 : item.kind !== "added" ? item.before : void 0;
833
- installMember(current.nodes, item.id, next !== void 0, next && {
834
- ...next,
835
- children: [...next.children]
836
- });
830
+ if (next !== void 0) {
831
+ const issue = require_access.checkTreePayload(node.value, next, change.at.concat(item.id));
832
+ if (issue) require_issue.invalidValue(issue);
833
+ }
834
+ installMember(current.nodes, item.id, next !== void 0, next && require_access.copyTreeNode(next));
837
835
  }
838
- session.validate(node, current, change.at);
836
+ if (!require_issue.validate(current)) return require_issue.fail(change.at, "invalid-tree", "Invalid tree structure.");
839
837
  session.invalidate();
840
838
  }
841
839
  }
@@ -1430,12 +1428,220 @@ const createSelectorReadable = (source, selector, equality = Object.is) => {
1430
1428
  });
1431
1429
  };
1432
1430
  //#endregion
1431
+ //#region core/src/projection/document-materialization.ts
1432
+ const createDocumentDirty = () => ({
1433
+ replace: false,
1434
+ order: false,
1435
+ treeRoot: false,
1436
+ treeNodes: /* @__PURE__ */ new Set(),
1437
+ children: /* @__PURE__ */ new Map()
1438
+ });
1439
+ const clearDocumentDirty = (dirty) => {
1440
+ dirty.replace = false;
1441
+ dirty.order = false;
1442
+ dirty.treeRoot = false;
1443
+ dirty.treeNodes.clear();
1444
+ dirty.children.clear();
1445
+ };
1446
+ const hasDocumentDirty = (dirty) => dirty.replace || dirty.order || dirty.treeRoot || dirty.treeNodes.size > 0 || dirty.children.size > 0;
1447
+ const locate = (dirty, path) => {
1448
+ let current = dirty;
1449
+ for (const key of path) {
1450
+ if (current.replace) return void 0;
1451
+ let child = current.children.get(key);
1452
+ if (!child) {
1453
+ child = createDocumentDirty();
1454
+ current.children.set(key, child);
1455
+ }
1456
+ current = child;
1457
+ }
1458
+ return current;
1459
+ };
1460
+ const markDocumentReplace = (dirty, path) => {
1461
+ const current = locate(dirty, path);
1462
+ if (!current) return;
1463
+ current.replace = true;
1464
+ current.order = false;
1465
+ current.treeRoot = false;
1466
+ current.treeNodes.clear();
1467
+ current.children.clear();
1468
+ };
1469
+ const markDocumentOrder = (dirty, path) => {
1470
+ const current = locate(dirty, path);
1471
+ if (current && !current.replace) current.order = true;
1472
+ };
1473
+ const markDocumentTree = (dirty, path, root, nodes) => {
1474
+ const current = locate(dirty, path);
1475
+ if (!current || current.replace) return;
1476
+ current.treeRoot ||= root;
1477
+ for (const id of nodes) current.treeNodes.add(id);
1478
+ };
1479
+ const equivalent = (node, left, right) => node.kind === "field" ? Object.is(left, right) : require_access.equalValue(node, left, right);
1480
+ const replaceValue = (node, previous, current) => equivalent(node, previous, current) ? previous : require_access.copyValue(node, current);
1481
+ const cloneRecord = (value) => {
1482
+ require_issue.profile.copy.shallowRecord(Object.getOwnPropertyNames(value).length);
1483
+ return Object.create(Object.getPrototypeOf(value), Object.getOwnPropertyDescriptors(value));
1484
+ };
1485
+ const materializeRecordChild = (node, previous, current, key, dirty) => {
1486
+ const before = Object.hasOwn(previous, key);
1487
+ const after = Object.hasOwn(current, key);
1488
+ if (!before && !after) return { changed: false };
1489
+ if (!after) return {
1490
+ changed: true,
1491
+ present: false,
1492
+ value: void 0
1493
+ };
1494
+ const next = before ? materializeDocumentValue(node, previous[key], current[key], dirty) : require_access.copyValue(node, current[key]);
1495
+ if (before && next === previous[key]) return { changed: false };
1496
+ return {
1497
+ changed: true,
1498
+ present: true,
1499
+ value: next
1500
+ };
1501
+ };
1502
+ const materializeObject = (node, previous, current, dirty) => {
1503
+ if (node.kind === "variant" && previous[node.tag] !== current[node.tag]) return replaceValue(node, previous, current);
1504
+ const layout = require_issue.compiledShape(node, current);
1505
+ if (!layout) return replaceValue(node, previous, current);
1506
+ let result;
1507
+ for (const [key, childDirty] of dirty.children) {
1508
+ const member = layout.members.get(key);
1509
+ if (!member) return replaceValue(node, previous, current);
1510
+ const child = materializeRecordChild(member.node, previous, current, key, childDirty);
1511
+ if (!child.changed) continue;
1512
+ result ??= cloneRecord(previous);
1513
+ installMember(result, key, child.present, child.value);
1514
+ }
1515
+ return result ?? previous;
1516
+ };
1517
+ const materializeMap = (node, previous, current, dirty) => {
1518
+ let result;
1519
+ for (const [key, childDirty] of dirty.children) {
1520
+ const child = materializeRecordChild(node.value, previous, current, key, childDirty);
1521
+ if (!child.changed) continue;
1522
+ result ??= cloneRecord(previous);
1523
+ installMember(result, key, child.present, child.value);
1524
+ }
1525
+ return result ?? previous;
1526
+ };
1527
+ const materializeTable = (node, previous, current, dirty) => {
1528
+ if (!require_issue.isRecord(previous.byId) || !require_issue.isRecord(current.byId)) return replaceValue(node, previous, current);
1529
+ const beforeById = previous.byId;
1530
+ const afterById = current.byId;
1531
+ let result;
1532
+ let nextById;
1533
+ for (const [key, childDirty] of dirty.children) {
1534
+ const child = materializeRecordChild(node.value, beforeById, afterById, key, childDirty);
1535
+ if (!child.changed) continue;
1536
+ nextById ??= cloneRecord(beforeById);
1537
+ installMember(nextById, key, child.present, child.value);
1538
+ }
1539
+ if (nextById) {
1540
+ result = cloneRecord(previous);
1541
+ installMember(result, "byId", true, nextById);
1542
+ }
1543
+ if (dirty.order) {
1544
+ const beforeIds = previous.ids;
1545
+ const afterIds = current.ids;
1546
+ if (!Array.isArray(beforeIds) || !Array.isArray(afterIds)) return replaceValue(node, previous, current);
1547
+ if (!require_issue.equal(beforeIds, afterIds)) {
1548
+ result ??= cloneRecord(previous);
1549
+ installMember(result, "ids", true, [...afterIds]);
1550
+ }
1551
+ }
1552
+ return result ?? previous;
1553
+ };
1554
+ const materializeList = (node, previous, current, dirty) => {
1555
+ if (dirty.order) {
1556
+ const before = require_issue.listSequence(previous, node.keyOf);
1557
+ const after = require_issue.listSequence(current, node.keyOf);
1558
+ let changed = !require_issue.equal(before.order, after.order);
1559
+ const result = new Array(after.order.length);
1560
+ for (let index = 0; index < after.order.length; index++) {
1561
+ const key = after.order[index];
1562
+ const currentValue = after.values.get(key);
1563
+ if (!before.values.has(key)) {
1564
+ changed = true;
1565
+ result[index] = currentValue;
1566
+ continue;
1567
+ }
1568
+ const previousValue = before.values.get(key);
1569
+ const childDirty = dirty.children.get(key);
1570
+ const next = childDirty ? materializeDocumentValue(node.value, previousValue, currentValue, childDirty) : previousValue;
1571
+ changed ||= next !== previousValue;
1572
+ result[index] = next;
1573
+ }
1574
+ return changed ? result : previous;
1575
+ }
1576
+ let result;
1577
+ const before = require_issue.indexedKeys(previous, node.keyOf);
1578
+ const after = require_issue.indexedKeys(current, node.keyOf);
1579
+ for (const [key, childDirty] of dirty.children) {
1580
+ const previousIndex = before.index(key);
1581
+ const currentIndex = after.index(key);
1582
+ if (previousIndex < 0 || currentIndex < 0) return replaceValue(node, previous, current);
1583
+ const next = materializeDocumentValue(node.value, previous[previousIndex], current[currentIndex], childDirty);
1584
+ if (next === previous[previousIndex] && previousIndex === currentIndex) continue;
1585
+ result ??= [...previous];
1586
+ result[currentIndex] = next;
1587
+ }
1588
+ return result ?? previous;
1589
+ };
1590
+ const materializeTree = (node, previous, current, dirty) => {
1591
+ if (!require_issue.isRecord(previous.nodes) || !require_issue.isRecord(current.nodes)) return replaceValue(node, previous, current);
1592
+ let result;
1593
+ if (dirty.treeRoot) {
1594
+ const beforePresent = Object.hasOwn(previous, "rootId");
1595
+ const afterPresent = Object.hasOwn(current, "rootId");
1596
+ if (beforePresent !== afterPresent || !Object.is(previous.rootId, current.rootId)) {
1597
+ result = cloneRecord(previous);
1598
+ installMember(result, "rootId", afterPresent, current.rootId);
1599
+ }
1600
+ }
1601
+ let nodes;
1602
+ for (const id of dirty.treeNodes) {
1603
+ const beforePresent = Object.hasOwn(previous.nodes, id);
1604
+ const afterPresent = Object.hasOwn(current.nodes, id);
1605
+ const before = beforePresent ? previous.nodes[id] : void 0;
1606
+ const after = afterPresent ? current.nodes[id] : void 0;
1607
+ if (beforePresent === afterPresent && require_access.equalTreeNode(before, after)) continue;
1608
+ nodes ??= cloneRecord(previous.nodes);
1609
+ installMember(nodes, id, afterPresent, after && require_access.copyTreeNode(after));
1610
+ }
1611
+ if (nodes) {
1612
+ result ??= cloneRecord(previous);
1613
+ installMember(result, "nodes", true, nodes);
1614
+ }
1615
+ return result ?? previous;
1616
+ };
1617
+ const materializeDocumentValue = (node, previous, current, dirty) => {
1618
+ if (!hasDocumentDirty(dirty)) return previous;
1619
+ if (dirty.replace || previous === void 0 || current === void 0 || node.kind === "field") return replaceValue(node, previous, current);
1620
+ if (node.kind === "object" || node.kind === "variant") {
1621
+ if (!require_issue.isRecord(previous) || !require_issue.isRecord(current)) return replaceValue(node, previous, current);
1622
+ return materializeObject(node, previous, current, dirty);
1623
+ }
1624
+ if (node.kind === "map") {
1625
+ if (!require_issue.isRecord(previous) || !require_issue.isRecord(current)) return replaceValue(node, previous, current);
1626
+ return materializeMap(node, previous, current, dirty);
1627
+ }
1628
+ if (node.kind === "table") {
1629
+ if (!require_issue.isRecord(previous) || !require_issue.isRecord(current)) return replaceValue(node, previous, current);
1630
+ return materializeTable(node, previous, current, dirty);
1631
+ }
1632
+ if (node.kind === "list") {
1633
+ if (!Array.isArray(previous) || !Array.isArray(current)) return replaceValue(node, previous, current);
1634
+ return materializeList(node, previous, current, dirty);
1635
+ }
1636
+ if (!require_issue.isRecord(previous) || !require_issue.isRecord(current)) return replaceValue(node, previous, current);
1637
+ return materializeTree(node, previous, current, dirty);
1638
+ };
1639
+ //#endregion
1433
1640
  //#region core/src/projection/source.ts
1434
1641
  const sourceError = (source, cause) => new require_advanced.ProjectionError("source", source.name, [source.outputs[0].revision()], cause);
1435
- const createValueBoundary = (scheduler, name, initial, equality) => {
1642
+ const createValueBoundary = (scheduler, name, initial, equality, prepare, clearSource) => {
1436
1643
  const state = createValueOutput();
1437
1644
  let boundary;
1438
- let latest = initial;
1439
1645
  let pendingReset = false;
1440
1646
  let pendingCause;
1441
1647
  let contextCause;
@@ -1477,7 +1683,8 @@ const createValueBoundary = (scheduler, name, initial, equality) => {
1477
1683
  contextCause = cause;
1478
1684
  let active = true;
1479
1685
  try {
1480
- state.begin(() => active, pendingReset).output.set(latest);
1686
+ const evaluation = state.begin(() => active, pendingReset);
1687
+ evaluation.output.set(prepare(evaluation.previous));
1481
1688
  const changed = state.seal(pendingReset, equality);
1482
1689
  recovering = false;
1483
1690
  return {
@@ -1490,11 +1697,13 @@ const createValueBoundary = (scheduler, name, initial, equality) => {
1490
1697
  },
1491
1698
  publish: state.publish,
1492
1699
  clear: () => {
1700
+ const failed = boundary.fault !== void 0;
1493
1701
  state.clear();
1494
1702
  pendingReset = false;
1495
1703
  pendingCause = void 0;
1496
1704
  contextCause = void 0;
1497
1705
  recovering = false;
1706
+ clearSource(failed);
1498
1707
  },
1499
1708
  release: () => {
1500
1709
  cleanup?.();
@@ -1530,9 +1739,6 @@ const createValueBoundary = (scheduler, name, initial, equality) => {
1530
1739
  return {
1531
1740
  producer: boundary,
1532
1741
  output,
1533
- setLatest: (value) => {
1534
- latest = value;
1535
- },
1536
1742
  mark,
1537
1743
  fail,
1538
1744
  detach: (next) => {
@@ -1540,7 +1746,7 @@ const createValueBoundary = (scheduler, name, initial, equality) => {
1540
1746
  }
1541
1747
  };
1542
1748
  };
1543
- const createCollectionBoundary = (scheduler, name, readLatest, equality) => {
1749
+ const createCollectionBoundary = (scheduler, name, readLatest, equality, clearSource) => {
1544
1750
  const state = require_advanced.createCollectionOutput();
1545
1751
  let boundary;
1546
1752
  let pendingReset = false;
@@ -1587,7 +1793,7 @@ const createCollectionBoundary = (scheduler, name, readLatest, equality) => {
1587
1793
  contextCause = cause;
1588
1794
  let active = true;
1589
1795
  try {
1590
- const changed = require_advanced.stageCollectionRead(state, readLatest(() => active), () => active, {
1796
+ const changed = require_advanced.stageCollectionRead(state, readLatest(() => active, state.current(() => void 0)), () => active, {
1591
1797
  reset: pendingReset,
1592
1798
  ...fullScan ? {} : { candidates },
1593
1799
  orderMayChange,
@@ -1604,6 +1810,7 @@ const createCollectionBoundary = (scheduler, name, readLatest, equality) => {
1604
1810
  },
1605
1811
  publish: state.publish,
1606
1812
  clear: () => {
1813
+ const failed = boundary.fault !== void 0;
1607
1814
  state.clear();
1608
1815
  pendingReset = false;
1609
1816
  pendingCause = void 0;
@@ -1612,6 +1819,7 @@ const createCollectionBoundary = (scheduler, name, readLatest, equality) => {
1612
1819
  fullScan = false;
1613
1820
  orderMayChange = false;
1614
1821
  candidates.clear();
1822
+ clearSource(failed);
1615
1823
  },
1616
1824
  release: () => {
1617
1825
  cleanup?.();
@@ -1623,7 +1831,7 @@ const createCollectionBoundary = (scheduler, name, readLatest, equality) => {
1623
1831
  scheduler.initialize(() => {
1624
1832
  let active = true;
1625
1833
  try {
1626
- require_advanced.stageCollectionRead(state, readLatest(() => active), () => active, {
1834
+ require_advanced.stageCollectionRead(state, readLatest(() => active, state.current(() => void 0)), () => active, {
1627
1835
  reset: true,
1628
1836
  isEqual: equality
1629
1837
  });
@@ -1659,6 +1867,109 @@ const createCollectionBoundary = (scheduler, name, readLatest, equality) => {
1659
1867
  }
1660
1868
  };
1661
1869
  };
1870
+ const documentRootTarget = Object.freeze({
1871
+ kind: "value",
1872
+ at: Object.freeze([])
1873
+ });
1874
+ const createCollectionPending = () => ({
1875
+ reset: false,
1876
+ order: false,
1877
+ entries: /* @__PURE__ */ new Map()
1878
+ });
1879
+ const resetCollectionPending = (pending) => {
1880
+ pending.reset = true;
1881
+ pending.order = false;
1882
+ pending.entries.clear();
1883
+ };
1884
+ const clearCollectionPending = (pending) => {
1885
+ pending.reset = false;
1886
+ pending.order = false;
1887
+ pending.entries.clear();
1888
+ };
1889
+ const dirtyEntry = (pending, key) => {
1890
+ let dirty = pending.entries.get(key);
1891
+ if (!dirty) {
1892
+ dirty = createDocumentDirty();
1893
+ pending.entries.set(key, dirty);
1894
+ }
1895
+ return dirty;
1896
+ };
1897
+ const mergeValueChanges = (selector, dirty, changes) => {
1898
+ if (selector.tree) return;
1899
+ const at = selector.address;
1900
+ for (const change of changes.changes) {
1901
+ if (change.kind === "reset") {
1902
+ markDocumentReplace(dirty, []);
1903
+ return;
1904
+ }
1905
+ if (change.kind === "members") {
1906
+ for (const member of change.members) {
1907
+ const changed = [...change.at, member.key];
1908
+ if (require_issue.contains(changed, at)) markDocumentReplace(dirty, []);
1909
+ else if (require_issue.contains(at, changed)) markDocumentReplace(dirty, changed.slice(at.length));
1910
+ }
1911
+ if (change.order && require_issue.contains(at, change.at)) markDocumentOrder(dirty, change.at.slice(at.length));
1912
+ continue;
1913
+ }
1914
+ if (require_issue.contains(at, change.at)) markDocumentTree(dirty, change.at.slice(at.length), change.before !== change.after, change.nodes.map((node) => node.id));
1915
+ }
1916
+ };
1917
+ const mergeCollectionChanges = (selector, pending, changes) => {
1918
+ if (pending.reset) return;
1919
+ const at = selector.address;
1920
+ for (const change of changes.changes) {
1921
+ if (change.kind === "reset") {
1922
+ resetCollectionPending(pending);
1923
+ return;
1924
+ }
1925
+ if (selector.tree?.kind === "nodes") {
1926
+ if (change.kind === "members") {
1927
+ for (const member of change.members) if (require_issue.contains([...change.at, member.key], at)) {
1928
+ resetCollectionPending(pending);
1929
+ return;
1930
+ }
1931
+ } else if (change.at.length === at.length && require_issue.contains(change.at, at)) for (const node of change.nodes) {
1932
+ markDocumentReplace(dirtyEntry(pending, node.id), []);
1933
+ pending.order ||= node.kind !== "updated";
1934
+ }
1935
+ else if (require_issue.contains(change.at, at)) {
1936
+ resetCollectionPending(pending);
1937
+ return;
1938
+ }
1939
+ continue;
1940
+ }
1941
+ if (change.kind === "members") {
1942
+ for (const member of change.members) {
1943
+ const changed = [...change.at, member.key];
1944
+ if (require_issue.contains(changed, at)) {
1945
+ resetCollectionPending(pending);
1946
+ return;
1947
+ }
1948
+ if (!require_issue.contains(at, changed)) continue;
1949
+ const relative = changed.slice(at.length);
1950
+ if (!relative.length) {
1951
+ resetCollectionPending(pending);
1952
+ return;
1953
+ }
1954
+ markDocumentReplace(dirtyEntry(pending, relative[0]), relative.slice(1));
1955
+ if (relative.length === 1 && member.kind !== "updated") pending.order = true;
1956
+ }
1957
+ if (change.order && require_issue.contains(at, change.at)) {
1958
+ const relative = change.at.slice(at.length);
1959
+ if (!relative.length) pending.order = true;
1960
+ else markDocumentOrder(dirtyEntry(pending, relative[0]), relative.slice(1));
1961
+ }
1962
+ continue;
1963
+ }
1964
+ if (!require_issue.contains(at, change.at)) continue;
1965
+ const relative = change.at.slice(at.length);
1966
+ if (!relative.length) {
1967
+ resetCollectionPending(pending);
1968
+ return;
1969
+ }
1970
+ markDocumentTree(dirtyEntry(pending, relative[0]), relative.slice(1), change.before !== change.after, change.nodes.map((node) => node.id));
1971
+ }
1972
+ };
1662
1973
  const createSourceRegistry = (scheduler) => {
1663
1974
  const documents = /* @__PURE__ */ new Map();
1664
1975
  const readables = /* @__PURE__ */ new Map();
@@ -1670,6 +1981,8 @@ const createSourceRegistry = (scheduler) => {
1670
1981
  if (cached) return cached;
1671
1982
  if (state.disposed) throw new Error("Document has been disposed.");
1672
1983
  const bindings = /* @__PURE__ */ new Set();
1984
+ const index = new require_access.SubscriptionIndex(state.schema);
1985
+ const candidates = /* @__PURE__ */ new Set();
1673
1986
  const guard = (locked) => {
1674
1987
  state.projectionLocks = (state.projectionLocks ?? 0) + (locked ? 1 : -1);
1675
1988
  };
@@ -1680,11 +1993,13 @@ const createSourceRegistry = (scheduler) => {
1680
1993
  add(binding) {
1681
1994
  if (closed) throw new Error("Document projection connection is closed.");
1682
1995
  bindings.add(binding);
1996
+ index.add(binding.target, binding);
1683
1997
  let active = true;
1684
1998
  return () => {
1685
1999
  if (!active) return;
1686
2000
  active = false;
1687
2001
  bindings.delete(binding);
2002
+ index.delete(binding.target, binding);
1688
2003
  if (!bindings.size) connection.close();
1689
2004
  };
1690
2005
  },
@@ -1693,13 +2008,17 @@ const createSourceRegistry = (scheduler) => {
1693
2008
  closed = true;
1694
2009
  detach();
1695
2010
  bindings.clear();
2011
+ candidates.clear();
2012
+ index.clear();
1696
2013
  scheduler.guards.delete(guard);
1697
2014
  documents.delete(state);
1698
2015
  }
1699
2016
  };
1700
2017
  detach = require_notification.attachProjection(runtime, {
1701
2018
  capture: (commit) => {
1702
- for (const binding of bindings) if (binding.matches(commit)) binding.capture(commit);
2019
+ candidates.clear();
2020
+ index.collect(commit.changes, (binding) => candidates.add(binding));
2021
+ candidates.forEach((binding) => binding.capture(commit));
1703
2022
  },
1704
2023
  settle: scheduler.settle,
1705
2024
  flush: scheduler.flush,
@@ -1714,14 +2033,15 @@ const createSourceRegistry = (scheduler) => {
1714
2033
  const valueInput = (definition) => {
1715
2034
  if (definition.source.kind !== "value-input") throw new Error("Invalid value input source.");
1716
2035
  const source = definition.source;
1717
- const boundary = createValueBoundary(scheduler, "projection input", source.initial, source.equality);
2036
+ let latest = source.initial;
2037
+ const boundary = createValueBoundary(scheduler, "projection input", source.initial, source.equality, () => latest, () => void 0);
1718
2038
  return {
1719
2039
  ...boundary,
1720
2040
  write: {
1721
2041
  kind: "value",
1722
2042
  set(value) {
1723
2043
  scheduler.assertIdle();
1724
- boundary.setLatest(value);
2044
+ latest = value;
1725
2045
  boundary.mark();
1726
2046
  scheduler.run();
1727
2047
  }
@@ -1731,7 +2051,7 @@ const createSourceRegistry = (scheduler) => {
1731
2051
  const collectionInput = (definition) => {
1732
2052
  if (definition.source.kind !== "collection-input") throw new Error("Invalid collection input source.");
1733
2053
  const values = new Map(definition.source.initial);
1734
- const boundary = createCollectionBoundary(scheduler, "projection collection input", () => require_advanced.mapRead(values), definition.output.equality);
2054
+ const boundary = createCollectionBoundary(scheduler, "projection collection input", () => require_advanced.mapRead(values), definition.output.equality, () => void 0);
1735
2055
  return {
1736
2056
  ...boundary,
1737
2057
  write: {
@@ -1807,87 +2127,131 @@ const createSourceRegistry = (scheduler) => {
1807
2127
  }
1808
2128
  };
1809
2129
  };
1810
- const documentValue = (definition) => {
1811
- if (definition.source.kind !== "document-value") throw new Error("Invalid document value source.");
2130
+ const documentSource = (definition) => {
2131
+ if (definition.source.kind !== "document") throw new Error("Invalid document source.");
1812
2132
  const { document, selector } = definition.source;
1813
2133
  const state = require_access.accessOf(document);
1814
- const address = selector?.address ?? Object.freeze([]);
1815
- const schemaNode = () => require_issue.nodeAt(state.schema, address, state.document);
1816
- const read = () => {
2134
+ const schemaNode = () => require_issue.nodeAt(state.schema, selector.address, state.document);
2135
+ const currentValue = () => require_issue.read(state.document, selector.address, state.schema);
2136
+ const disposed = () => {
1817
2137
  if (state.disposed) throw new Error("Document has been disposed.");
1818
- const node = schemaNode();
1819
- if (!node) return void 0;
1820
- return require_access.copyValue(node, selector ? require_issue.read(state.document, address, state.schema) : state.document);
1821
2138
  };
1822
- const boundary = createValueBoundary(scheduler, "document source", read(), (left, right) => {
1823
- const node = schemaNode();
1824
- return node ? require_access.equalValue(node, left, right) : Object.is(left, right);
1825
- });
1826
- const remove = documentConnection(document).add({
1827
- matches: (commit) => !selector || affectsTarget(commit.impact, selector),
1828
- capture: (commit) => {
1829
- try {
1830
- boundary.setLatest(read());
1831
- boundary.mark({ reset: commit.impact.kind === "reset" });
1832
- } catch (cause) {
1833
- boundary.fail(cause);
2139
+ if (selector.kind === "value") {
2140
+ const dirty = createDocumentDirty();
2141
+ const read = (previous) => {
2142
+ disposed();
2143
+ const node = schemaNode();
2144
+ const current = currentValue();
2145
+ if (selector.tree?.kind === "root") return node?.kind === "tree" && require_issue.isRecord(current) && typeof current.rootId === "string" ? current.rootId : void 0;
2146
+ if (selector.tree?.kind === "node") {
2147
+ if (node?.kind !== "tree" || !require_issue.isRecord(current) || !require_issue.isRecord(current.nodes)) return void 0;
2148
+ const entry = Object.hasOwn(current.nodes, selector.tree.id) ? current.nodes[selector.tree.id] : void 0;
2149
+ if (require_access.equalTreeNode(previous, entry)) return previous;
2150
+ return entry ? require_access.copyTreeNode(entry) : void 0;
1834
2151
  }
1835
- },
1836
- dispose: () => boundary.fail(/* @__PURE__ */ new Error("Document has been disposed."))
1837
- });
1838
- boundary.detach(remove);
1839
- return boundary;
1840
- };
1841
- const documentCollection = (definition) => {
1842
- if (definition.source.kind !== "document-collection") throw new Error("Invalid document collection source.");
1843
- const { document, selector } = definition.source;
1844
- const state = require_access.accessOf(document);
1845
- const read = (active) => {
1846
- if (state.disposed) throw new Error("Document has been disposed.");
1847
- const raw = require_access.collectionAccess({
1848
- state,
1849
- active
1850
- }, selector.address);
2152
+ if (!node) return void 0;
2153
+ return previous === void 0 ? require_access.copyValue(node, current) : materializeDocumentValue(node, previous, current, dirty);
2154
+ };
2155
+ const initial = read();
2156
+ let boundary;
2157
+ boundary = createValueBoundary(scheduler, "document source", initial, Object.is, (previous) => read(previous), (failed) => {
2158
+ if (failed) markDocumentReplace(dirty, []);
2159
+ else clearDocumentDirty(dirty);
2160
+ });
2161
+ const remove = documentConnection(document).add({
2162
+ target: selector,
2163
+ capture: (commit) => {
2164
+ try {
2165
+ mergeValueChanges(selector, dirty, commit.changes);
2166
+ boundary.mark({ reset: commit.changes.changes.some((change) => change.kind === "reset") });
2167
+ } catch (cause) {
2168
+ boundary.fail(cause);
2169
+ }
2170
+ },
2171
+ dispose: () => boundary.fail(/* @__PURE__ */ new Error("Document has been disposed."))
2172
+ });
2173
+ boundary.detach(remove);
2174
+ return boundary;
2175
+ }
2176
+ const pending = createCollectionPending();
2177
+ const read = (active, previous) => {
2178
+ disposed();
2179
+ const node = schemaNode();
2180
+ const value = currentValue();
2181
+ const treeNodes = selector.tree?.kind === "nodes";
2182
+ const entryNode = !treeNodes && node ? require_advanced.collectionEntryNode(node) : void 0;
1851
2183
  const snapshots = /* @__PURE__ */ new Map();
2184
+ const replacement = createDocumentDirty();
2185
+ if (pending.reset) markDocumentReplace(replacement, []);
2186
+ const ids = () => {
2187
+ require_advanced.assertScope(active);
2188
+ if (treeNodes) return node?.kind === "tree" && require_issue.isRecord(value) && require_issue.isRecord(value.nodes) ? Object.freeze(Object.keys(value.nodes)) : Object.freeze([]);
2189
+ if (node?.kind === "map" && require_issue.isRecord(value)) return Object.freeze(Object.keys(value));
2190
+ if (node?.kind === "table" && require_issue.isRecord(value) && Array.isArray(value.ids)) return Object.freeze([...value.ids]);
2191
+ if (node?.kind === "list" && Array.isArray(value)) return Object.freeze(require_issue.toArray(require_issue.indexedKeys(value, node.keyOf)));
2192
+ return Object.freeze([]);
2193
+ };
2194
+ const has = (key) => {
2195
+ require_advanced.assertScope(active);
2196
+ if (treeNodes) return Boolean(node?.kind === "tree" && require_issue.isRecord(value) && require_issue.isRecord(value.nodes) && Object.hasOwn(value.nodes, key));
2197
+ if (node?.kind === "map" && require_issue.isRecord(value)) return Object.hasOwn(value, key);
2198
+ if (node?.kind === "table" && require_issue.isRecord(value) && require_issue.isRecord(value.byId)) return Object.hasOwn(value.byId, key);
2199
+ if (node?.kind === "list" && Array.isArray(value)) return require_issue.indexedKeys(value, node.keyOf).index(key) >= 0;
2200
+ return false;
2201
+ };
2202
+ const raw = (key) => {
2203
+ if (treeNodes) {
2204
+ if (node?.kind !== "tree" || !require_issue.isRecord(value) || !require_issue.isRecord(value.nodes)) return void 0;
2205
+ return Object.hasOwn(value.nodes, key) ? value.nodes[key] : void 0;
2206
+ }
2207
+ if (node?.kind === "map" && require_issue.isRecord(value)) return Object.hasOwn(value, key) ? value[key] : void 0;
2208
+ if (node?.kind === "table" && require_issue.isRecord(value) && require_issue.isRecord(value.byId)) return Object.hasOwn(value.byId, key) ? value.byId[key] : void 0;
2209
+ if (node?.kind === "list" && Array.isArray(value)) {
2210
+ const index = require_issue.indexedKeys(value, node.keyOf).index(key);
2211
+ return index < 0 ? void 0 : value[index];
2212
+ }
2213
+ };
1852
2214
  return Object.freeze({
1853
2215
  get: (key) => {
1854
2216
  require_advanced.assertScope(active);
1855
- if (!snapshots.has(key)) snapshots.set(key, require_access.snapshot(raw.get(key)));
2217
+ if (!snapshots.has(key)) if (!has(key)) snapshots.set(key, void 0);
2218
+ else {
2219
+ const current = raw(key);
2220
+ if (treeNodes) {
2221
+ const entry = current;
2222
+ const before = previous.has(key) ? previous.get(key) : void 0;
2223
+ snapshots.set(key, require_access.equalTreeNode(before, entry) ? before : require_access.copyTreeNode(entry));
2224
+ } else if (!entryNode) snapshots.set(key, current);
2225
+ else if (!previous.has(key)) snapshots.set(key, require_access.copyValue(entryNode, current));
2226
+ else {
2227
+ const dirty = pending.entries.get(key) ?? (pending.reset ? replacement : void 0);
2228
+ snapshots.set(key, dirty ? materializeDocumentValue(entryNode, previous.get(key), current, dirty) : previous.get(key));
2229
+ }
2230
+ }
1856
2231
  return snapshots.get(key);
1857
2232
  },
1858
- has: (key) => {
1859
- require_advanced.assertScope(active);
1860
- return raw.has(key);
1861
- },
1862
- ids: () => {
1863
- require_advanced.assertScope(active);
1864
- return raw.ids();
1865
- }
2233
+ has,
2234
+ ids
1866
2235
  });
1867
2236
  };
1868
- const collectionNode = () => require_issue.nodeAt(state.schema, selector.address, state.document);
1869
- const boundary = createCollectionBoundary(scheduler, "document collection source", read, (left, right) => {
1870
- const node = collectionNode();
1871
- const entry = node && require_advanced.collectionEntryNode(node);
1872
- return entry ? require_access.equalValue(entry, left, right) : Object.is(left, right);
2237
+ let boundary;
2238
+ boundary = createCollectionBoundary(scheduler, "document collection source", read, Object.is, (failed) => {
2239
+ if (failed) resetCollectionPending(pending);
2240
+ else clearCollectionPending(pending);
1873
2241
  });
1874
2242
  const remove = documentConnection(document).add({
1875
- matches: (commit) => affectsTarget(commit.impact, selector),
2243
+ target: selector,
1876
2244
  capture: (commit) => {
1877
- const impact = collectionImpact(commit.impact, selector);
1878
- if (impact.kind === "reset") {
1879
- boundary.mark({ reset: true });
1880
- return;
2245
+ try {
2246
+ mergeCollectionChanges(selector, pending, commit.changes);
2247
+ boundary.mark({
2248
+ reset: pending.reset,
2249
+ ...pending.reset ? {} : { candidates: pending.entries.keys() },
2250
+ orderMayChange: pending.order
2251
+ });
2252
+ } catch (cause) {
2253
+ boundary.fail(cause);
1881
2254
  }
1882
- const candidates = new Set([
1883
- ...impact.added,
1884
- ...impact.updated,
1885
- ...impact.removed
1886
- ]);
1887
- boundary.mark({
1888
- candidates,
1889
- orderMayChange: Boolean(impact.added.size || impact.removed.size || impact.orderChanged)
1890
- });
1891
2255
  },
1892
2256
  dispose: () => boundary.fail(/* @__PURE__ */ new Error("Document has been disposed."))
1893
2257
  });
@@ -1897,13 +2261,12 @@ const createSourceRegistry = (scheduler) => {
1897
2261
  const readable = (definition) => {
1898
2262
  if (definition.source.kind !== "readable") throw new Error("Invalid Readable source.");
1899
2263
  const { readable, equality } = definition.source;
1900
- let initial = readable.current();
1901
- const boundary = createValueBoundary(scheduler, "external readable", initial, equality);
2264
+ let latest = readable.current();
2265
+ const boundary = createValueBoundary(scheduler, "external readable", latest, equality, () => latest, () => void 0);
1902
2266
  const member = {
1903
2267
  boundary,
1904
2268
  receive(value, metadata) {
1905
- initial = value;
1906
- boundary.setLatest(value);
2269
+ latest = value;
1907
2270
  boundary.mark(metadata);
1908
2271
  }
1909
2272
  };
@@ -1935,7 +2298,7 @@ const createSourceRegistry = (scheduler) => {
1935
2298
  };
1936
2299
  const owner = require_notification.documentReadableOwner(readable);
1937
2300
  if (owner) detachDocument = documentConnection(owner).add({
1938
- matches: () => true,
2301
+ target: documentRootTarget,
1939
2302
  capture: () => receive(false),
1940
2303
  dispose: () => {
1941
2304
  members.forEach((next) => next.boundary.fail(/* @__PURE__ */ new Error("Document has been disposed.")));
@@ -1955,11 +2318,12 @@ const createSourceRegistry = (scheduler) => {
1955
2318
  const externalValue = (definition) => {
1956
2319
  if (definition.source.kind !== "external-value") throw new Error("Invalid external value source.");
1957
2320
  const { source, equality } = definition.source;
1958
- const boundary = createValueBoundary(scheduler, "external source", source.current(), equality);
2321
+ let latest = source.current();
2322
+ const boundary = createValueBoundary(scheduler, "external source", latest, equality, () => latest, () => void 0);
1959
2323
  const member = {
1960
2324
  boundary,
1961
2325
  receive(value, metadata) {
1962
- boundary.setLatest(value);
2326
+ latest = value;
1963
2327
  boundary.mark(metadata);
1964
2328
  }
1965
2329
  };
@@ -2013,7 +2377,7 @@ const createSourceRegistry = (scheduler) => {
2013
2377
  has: (key) => current.has(key),
2014
2378
  ids: () => current.ids()
2015
2379
  });
2016
- }, definition.output.equality);
2380
+ }, definition.output.equality, () => void 0);
2017
2381
  let connection = externalCollections.get(source);
2018
2382
  if (!connection) {
2019
2383
  const members = /* @__PURE__ */ new Set();
@@ -2076,8 +2440,7 @@ const createSourceRegistry = (scheduler) => {
2076
2440
  switch (definition.source.kind) {
2077
2441
  case "value-input": return valueInput(definition);
2078
2442
  case "collection-input": return collectionInput(definition);
2079
- case "document-value": return documentValue(definition);
2080
- case "document-collection": return documentCollection(definition);
2443
+ case "document": return documentSource(definition);
2081
2444
  case "readable": return readable(definition);
2082
2445
  case "external-value": return externalValue(definition);
2083
2446
  case "external-collection": return externalCollection(definition);