@noy-db/hub 0.7.0-pre.11 → 0.7.0-pre.12

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 (62) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/as/index.js +3 -2
  3. package/dist/as/index.js.map +1 -1
  4. package/dist/{backup-VASRVLDZ.js → backup-R6A4VZRX.js} +4 -4
  5. package/dist/cargo/index.js +2 -2
  6. package/dist/{chunk-UB5CRTFF.js → chunk-7BE7ZDVQ.js} +379 -1
  7. package/dist/chunk-7BE7ZDVQ.js.map +1 -0
  8. package/dist/{chunk-ESVREVWN.js → chunk-7NTBVFGD.js} +2 -2
  9. package/dist/{chunk-T6PSWLAR.js → chunk-BUE2D7PX.js} +25 -2
  10. package/dist/chunk-BUE2D7PX.js.map +1 -0
  11. package/dist/{chunk-S5AMPTNE.js → chunk-E5OHKSBD.js} +2 -2
  12. package/dist/{chunk-OEA5NVSU.js → chunk-H7XCIM3Z.js} +59 -6
  13. package/dist/chunk-H7XCIM3Z.js.map +1 -0
  14. package/dist/chunk-KL7AS3HV.js +84 -0
  15. package/dist/chunk-KL7AS3HV.js.map +1 -0
  16. package/dist/chunk-RXLYKVTF.js +17 -0
  17. package/dist/chunk-RXLYKVTF.js.map +1 -0
  18. package/dist/chunk-TFMM5DBB.js +20 -0
  19. package/dist/chunk-TFMM5DBB.js.map +1 -0
  20. package/dist/chunk-TPHAGLUH.js +30 -0
  21. package/dist/chunk-TPHAGLUH.js.map +1 -0
  22. package/dist/{chunk-A5WZEPXJ.js → chunk-VGICZPVE.js} +5 -3
  23. package/dist/{chunk-A5WZEPXJ.js.map → chunk-VGICZPVE.js.map} +1 -1
  24. package/dist/{chunk-KHKKD62N.js → chunk-VYYM3MEN.js} +2 -16
  25. package/dist/chunk-VYYM3MEN.js.map +1 -0
  26. package/dist/{chunk-I6DGKPTY.js → chunk-XMF3GKUR.js} +60 -412
  27. package/dist/chunk-XMF3GKUR.js.map +1 -0
  28. package/dist/derivations/index.js +17 -6
  29. package/dist/dispatch-XEBHUGBV.js +250 -0
  30. package/dist/dispatch-XEBHUGBV.js.map +1 -0
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +19 -19
  33. package/dist/introspection/index.js +3 -2
  34. package/dist/kernel/collection.d.ts +11 -6
  35. package/dist/kernel/match-pairs.d.ts +30 -0
  36. package/dist/{noydb-QJFZAH34.js → noydb-JJXPICIC.js} +9 -7
  37. package/dist/pod/index.js +9 -7
  38. package/dist/registry-BZQIVNNO.js +29 -0
  39. package/dist/{walk-G3CZIL4L.js → walk-P3E6QSNC.js} +4 -3
  40. package/dist/with-formula/derivations/dispatch.d.ts +16 -1
  41. package/dist/with-formula/derivations/registry.d.ts +15 -0
  42. package/dist/with-formula/derivations/trigger-match.d.ts +52 -0
  43. package/dist/with-formula/derivations/types.d.ts +23 -0
  44. package/dist/with-shape/introspection/behaviors.d.ts +7 -0
  45. package/dist/with-shape/introspection/describe.d.ts +10 -0
  46. package/package.json +3 -3
  47. package/dist/chunk-I6DGKPTY.js.map +0 -1
  48. package/dist/chunk-KHKKD62N.js.map +0 -1
  49. package/dist/chunk-OEA5NVSU.js.map +0 -1
  50. package/dist/chunk-T6PSWLAR.js.map +0 -1
  51. package/dist/chunk-UB5CRTFF.js.map +0 -1
  52. package/dist/chunk-YPMW26SL.js +0 -81
  53. package/dist/chunk-YPMW26SL.js.map +0 -1
  54. package/dist/dispatch-IM52HDXT.js +0 -194
  55. package/dist/dispatch-IM52HDXT.js.map +0 -1
  56. package/dist/registry-FZXPQRAB.js +0 -18
  57. /package/dist/{backup-VASRVLDZ.js.map → backup-R6A4VZRX.js.map} +0 -0
  58. /package/dist/{chunk-ESVREVWN.js.map → chunk-7NTBVFGD.js.map} +0 -0
  59. /package/dist/{chunk-S5AMPTNE.js.map → chunk-E5OHKSBD.js.map} +0 -0
  60. /package/dist/{noydb-QJFZAH34.js.map → noydb-JJXPICIC.js.map} +0 -0
  61. /package/dist/{registry-FZXPQRAB.js.map → registry-BZQIVNNO.js.map} +0 -0
  62. /package/dist/{walk-G3CZIL4L.js.map → walk-P3E6QSNC.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveStaleOnRead
3
- } from "./chunk-YPMW26SL.js";
3
+ } from "./chunk-KL7AS3HV.js";
4
4
  import {
5
5
  isManifestReservedCollection
6
6
  } from "./chunk-EPFF7LOX.js";
@@ -57,16 +57,8 @@ import {
57
57
  runDrainBarrier
58
58
  } from "./chunk-VTFVLCUH.js";
59
59
  import {
60
- fallbackDerivationName,
61
- jsonSchemaToFields
62
- } from "./chunk-KHKKD62N.js";
63
- import {
64
- derivePersistedSchema,
65
- isZod4Schema
66
- } from "./chunk-URHRIAV6.js";
67
- import {
68
- loadPersistedSchema
69
- } from "./chunk-WWNYSV7S.js";
60
+ fallbackDerivationName
61
+ } from "./chunk-RXLYKVTF.js";
70
62
  import {
71
63
  NO_SEQUENCE,
72
64
  SEQUENCE_COLLECTION,
@@ -79,8 +71,17 @@ import {
79
71
  } from "./chunk-Y4MJQ2UG.js";
80
72
  import {
81
73
  DEFAULT_POSTURE,
82
- ViaGraph
83
- } from "./chunk-UB5CRTFF.js";
74
+ ViaGraph,
75
+ buildDescription,
76
+ deriveZodFields,
77
+ resolveDescribeFieldIds
78
+ } from "./chunk-7BE7ZDVQ.js";
79
+ import {
80
+ findMatchingIdsByPairs
81
+ } from "./chunk-TFMM5DBB.js";
82
+ import {
83
+ derivePersistedSchema
84
+ } from "./chunk-URHRIAV6.js";
84
85
  import {
85
86
  buildLookupAltIndex,
86
87
  buildLookupSnapshotRows,
@@ -1575,356 +1576,6 @@ function buildUniqueConstraintSet(collectionName, indexes, mode) {
1575
1576
  return new UniqueConstraintSet(collectionName, uniqueDefs);
1576
1577
  }
1577
1578
 
1578
- // src/with-shape/introspection/field-meta.ts
1579
- var FieldMetaUnknownFieldError = class extends Error {
1580
- constructor(collection, key) {
1581
- super(`fieldMeta for collection "${collection}" references unknown field "${key}". Declare it in the schema/config or remove the fieldMeta entry.`);
1582
- this.collection = collection;
1583
- this.key = key;
1584
- this.name = "FieldMetaUnknownFieldError";
1585
- }
1586
- collection;
1587
- key;
1588
- };
1589
- function validateFieldMetaKeys(collection, fieldMeta, knownFields) {
1590
- for (const key of Object.keys(fieldMeta)) {
1591
- if (!knownFields.has(key)) throw new FieldMetaUnknownFieldError(collection, key);
1592
- }
1593
- }
1594
- function humanizeFieldKey(key) {
1595
- return key.replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim().split(/\s+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
1596
- }
1597
- function resolveFieldMeta(key, inputs) {
1598
- const { channel, zodMeta, inferred } = inputs;
1599
- const pick = (k) => channel?.[k] ?? zodMeta?.[k] ?? inferred?.[k];
1600
- const description = pick("description");
1601
- const semanticType = pick("semanticType");
1602
- const unit = pick("unit");
1603
- const sensitivity = pick("sensitivity");
1604
- const aggregate = pick("aggregate");
1605
- const aliases = pick("aliases");
1606
- const displayFor = pick("displayFor");
1607
- const widget = pick("widget");
1608
- const group = pick("group");
1609
- const order = pick("order");
1610
- return {
1611
- label: pick("label") ?? humanizeFieldKey(key),
1612
- ...description !== void 0 ? { description } : {},
1613
- ...semanticType !== void 0 ? { semanticType } : {},
1614
- ...unit !== void 0 ? { unit } : {},
1615
- ...sensitivity !== void 0 ? { sensitivity } : {},
1616
- ...aggregate !== void 0 ? { aggregate } : {},
1617
- ...aliases !== void 0 ? { aliases } : {},
1618
- ...displayFor !== void 0 ? { displayFor } : {},
1619
- ...widget !== void 0 ? { widget } : {},
1620
- ...group !== void 0 ? { group } : {},
1621
- ...order !== void 0 ? { order } : {}
1622
- };
1623
- }
1624
-
1625
- // src/with-shape/introspection/describe.ts
1626
- var ZOD_META_KEYS = /* @__PURE__ */ new Set([
1627
- "label",
1628
- "description",
1629
- "unit",
1630
- "semanticType",
1631
- "sensitivity",
1632
- "aggregate",
1633
- "aliases",
1634
- "displayFor",
1635
- "group",
1636
- "order"
1637
- ]);
1638
- function schemaFieldKeys(schema) {
1639
- if (schema === null || typeof schema !== "object") return void 0;
1640
- const shape = schema.shape;
1641
- if (shape === null || typeof shape !== "object") return void 0;
1642
- const keys = Object.keys(shape);
1643
- return keys.length > 0 ? keys : void 0;
1644
- }
1645
- async function deriveZodFields(schema) {
1646
- const envelope = await derivePersistedSchema(schema);
1647
- if (!envelope.jsonSchema) return {};
1648
- const isZod4 = isZod4Schema(schema);
1649
- const jsonSchema = envelope.jsonSchema;
1650
- const fieldDescriptors = jsonSchemaToFields(jsonSchema, "live-validator");
1651
- const propertiesRaw = jsonSchema["properties"];
1652
- const result = {};
1653
- for (const [key, descriptor] of Object.entries(fieldDescriptors)) {
1654
- let meta;
1655
- if (isZod4 && propertiesRaw) {
1656
- const prop = propertiesRaw[key];
1657
- if (prop) {
1658
- const extracted = {};
1659
- let hasAny = false;
1660
- for (const mk of ZOD_META_KEYS) {
1661
- if (mk in prop) {
1662
- extracted[mk] = prop[mk];
1663
- hasAny = true;
1664
- }
1665
- }
1666
- if (hasAny) meta = extracted;
1667
- }
1668
- }
1669
- result[key] = {
1670
- type: descriptor.type,
1671
- optional: descriptor.optional === true,
1672
- ...descriptor.constraints !== void 0 ? { constraints: descriptor.constraints } : {},
1673
- ...meta !== void 0 ? { meta } : {}
1674
- };
1675
- }
1676
- return result;
1677
- }
1678
- async function resolveDescribeFieldIds(store, vaultName, collectionName, getDEK) {
1679
- let dek;
1680
- try {
1681
- dek = await getDEK(collectionName);
1682
- } catch {
1683
- return {};
1684
- }
1685
- const persisted = await loadPersistedSchema(store, vaultName, collectionName, dek);
1686
- return persisted?.fieldIds !== void 0 ? { fieldIds: persisted.fieldIds } : {};
1687
- }
1688
- function deriveWidget(opts) {
1689
- if (opts.resolvedWidget !== void 0) return opts.resolvedWidget;
1690
- switch (opts.semanticType) {
1691
- case "date":
1692
- case "datetime":
1693
- return "date";
1694
- case "currency":
1695
- return "money";
1696
- case "entity":
1697
- return "ref-select";
1698
- case "url":
1699
- return "url";
1700
- case "email":
1701
- return "email";
1702
- case "percent":
1703
- return "number";
1704
- }
1705
- if (opts.dict !== void 0 || opts.lookup !== void 0) return "select";
1706
- if (opts.blob !== void 0) return "file";
1707
- if (opts.type === "boolean") return "checkbox";
1708
- if (opts.type === "number") return "number";
1709
- return "text";
1710
- }
1711
- function buildDescription(input) {
1712
- const { collection, fieldMeta, moneyFields, dictKeyFields, lookupFields, computed, refs, zodFields, schema, dictLabels, meta, i18nFields, classified, taint, fieldIds } = input;
1713
- const lookupFragments = input.viaFragments?.["lookup"]?.lookupFields;
1714
- const blobFragments = input.viaFragments?.["blob"]?.blobFields;
1715
- const validatorKeys = zodFields !== void 0 && Object.keys(zodFields).length > 0 ? Object.keys(zodFields) : schemaFieldKeys(schema);
1716
- const canEnumerateFields = validatorKeys !== void 0;
1717
- if (canEnumerateFields && fieldMeta !== void 0) {
1718
- const knownFields = /* @__PURE__ */ new Set([
1719
- ...Object.keys(moneyFields ?? {}),
1720
- ...Object.keys(dictKeyFields ?? {}),
1721
- ...Object.keys(refs),
1722
- ...Object.keys(computed ?? {}),
1723
- ...validatorKeys ?? [],
1724
- ...Object.keys(i18nFields ?? {}),
1725
- ...Object.keys(lookupFields ?? {}),
1726
- ...Object.keys(blobFragments ?? {}),
1727
- ...Object.keys(classified ?? {})
1728
- ]);
1729
- validateFieldMetaKeys(collection, fieldMeta, knownFields);
1730
- }
1731
- const allKeys = /* @__PURE__ */ new Set([
1732
- ...Object.keys(moneyFields ?? {}),
1733
- ...Object.keys(dictKeyFields ?? {}),
1734
- ...Object.keys(lookupFields ?? {}),
1735
- ...Object.keys(refs),
1736
- ...Object.keys(computed ?? {}),
1737
- ...Object.keys(fieldMeta ?? {}),
1738
- ...Object.keys(zodFields ?? {}),
1739
- ...Object.keys(i18nFields ?? {}),
1740
- ...Object.keys(classified ?? {}),
1741
- ...Object.keys(blobFragments ?? {})
1742
- ]);
1743
- const fields = [];
1744
- for (const key of [...allKeys].sort()) {
1745
- const zod = zodFields?.[key];
1746
- const money = moneyFields?.[key];
1747
- const dict = dictKeyFields?.[key];
1748
- const lookupDesc = lookupFields?.[key];
1749
- const refDesc = refs[key];
1750
- const isComputed = computed !== void 0 && key in computed;
1751
- const i18nDesc = i18nFields?.[key];
1752
- const cls = classified?.[key];
1753
- const blobFragmentEntry = blobFragments?.[key];
1754
- const taintPosture = taint?.postures.get(key);
1755
- let type = zod?.type ?? "unknown";
1756
- const inferred = {};
1757
- let moneyBlock;
1758
- let dictBlock;
1759
- let refBlock;
1760
- let lookupBlock;
1761
- let blobBlock;
1762
- if (money) {
1763
- type = "number";
1764
- inferred.semanticType = "currency";
1765
- inferred.aggregate = "sum";
1766
- const currency = money.soleCurrency();
1767
- const scale = currency !== void 0 ? money.scaleFor(currency) : void 0;
1768
- moneyBlock = {
1769
- mode: money.mode,
1770
- ...currency !== void 0 ? { currency } : {},
1771
- ...scale !== void 0 ? { scale } : {},
1772
- ...money.rounding !== void 0 ? { rounding: money.rounding } : {}
1773
- };
1774
- } else if (refDesc) {
1775
- type = refDesc.isArray ? "array" : "string";
1776
- inferred.semanticType = "entity";
1777
- refBlock = {
1778
- target: refDesc.target,
1779
- mode: refDesc.mode,
1780
- ...refDesc.isArray ? { isArray: true } : {}
1781
- };
1782
- } else if (dict) {
1783
- type = "enum";
1784
- if (isStaticDictDescriptor(dict)) {
1785
- const displayLocale = dict.displayLocale;
1786
- const values = dict.keys.map((k) => {
1787
- const localeMap = dict.table[k];
1788
- const label = displayLocale !== void 0 ? localeMap?.[displayLocale] ?? void 0 : void 0;
1789
- return label !== void 0 ? { value: k, label } : { value: k };
1790
- });
1791
- dictBlock = { name: dict.name, static: true, values };
1792
- } else {
1793
- const labelMap = dictLabels?.[dict.name];
1794
- const labelMapHasEntries = labelMap !== void 0 && Object.keys(labelMap).length > 0;
1795
- if (labelMapHasEntries) {
1796
- const values = Object.entries(labelMap).map(([value, label]) => ({ value, label }));
1797
- dictBlock = { name: dict.name, static: false, values };
1798
- } else if (dict.keys !== void 0) {
1799
- const values = dict.keys.map((k) => {
1800
- const label = dict.labels?.[k];
1801
- return label !== void 0 ? { value: k, label } : { value: k };
1802
- });
1803
- dictBlock = { name: dict.name, static: false, values };
1804
- } else {
1805
- dictBlock = { name: dict.name, static: false };
1806
- }
1807
- }
1808
- } else if (lookupDesc) {
1809
- type = "enum";
1810
- const lookupLabelMap = dictLabels?.[lookupDesc.dimension];
1811
- const lookupLabelMapHasEntries = lookupLabelMap !== void 0 && Object.keys(lookupLabelMap).length > 0;
1812
- if (lookupDesc.table !== void 0) {
1813
- const displayLocale = lookupDesc.displayLocale;
1814
- const table = lookupDesc.table;
1815
- const values = (lookupDesc.keys ?? Object.keys(table)).map((k) => {
1816
- const localeMap = table[k];
1817
- const label = displayLocale !== void 0 ? localeMap?.[displayLocale] ?? void 0 : void 0;
1818
- return label !== void 0 ? { value: k, label } : { value: k };
1819
- });
1820
- dictBlock = { name: lookupDesc.dimension, static: true, values };
1821
- } else if (lookupLabelMapHasEntries) {
1822
- const values = Object.entries(lookupLabelMap).map(([value, label]) => ({ value, label }));
1823
- dictBlock = { name: lookupDesc.dimension, static: false, values };
1824
- } else if (lookupDesc.keys !== void 0) {
1825
- const values = lookupDesc.keys.map((k) => {
1826
- const label = lookupDesc.labels?.[k];
1827
- return label !== void 0 ? { value: k, label } : { value: k };
1828
- });
1829
- dictBlock = { name: lookupDesc.dimension, static: false, values };
1830
- } else {
1831
- dictBlock = { name: lookupDesc.dimension, static: false };
1832
- }
1833
- } else if (i18nDesc) {
1834
- type = "string";
1835
- } else if (isComputed) {
1836
- } else if (blobFragmentEntry !== void 0) {
1837
- type = "blob";
1838
- blobBlock = { ...blobFragmentEntry, queryable: "none" };
1839
- }
1840
- const lookupFragmentEntry = lookupFragments?.[key];
1841
- if (lookupFragmentEntry !== void 0) {
1842
- lookupBlock = {
1843
- ...lookupFragmentEntry.dimension !== void 0 ? { dimension: lookupFragmentEntry.dimension } : {},
1844
- backing: lookupFragmentEntry.backing,
1845
- vocabulary: lookupFragmentEntry.vocabulary,
1846
- key: lookupFragmentEntry.key,
1847
- onDelete: lookupFragmentEntry.onDelete,
1848
- ...lookupFragmentEntry.altKeys !== void 0 ? { altKeys: lookupFragmentEntry.altKeys } : {},
1849
- ...lookupFragmentEntry.present !== void 0 ? { present: lookupFragmentEntry.present } : {},
1850
- ...lookupFragmentEntry.sortBy !== void 0 ? { sortBy: lookupFragmentEntry.sortBy } : {},
1851
- ...lookupFragmentEntry.keys !== void 0 ? { keys: lookupFragmentEntry.keys } : {}
1852
- };
1853
- }
1854
- if (cls !== void 0) inferred.sensitivity = cls.sensitivity;
1855
- const channelEntry = fieldMeta?.[key];
1856
- const zodMeta = zod?.meta;
1857
- const resolved = resolveFieldMeta(key, {
1858
- ...channelEntry !== void 0 ? { channel: channelEntry } : {},
1859
- ...zodMeta !== void 0 ? { zodMeta } : {},
1860
- inferred
1861
- });
1862
- let i18nBlock;
1863
- if (i18nDesc !== void 0) {
1864
- const locales = i18nDesc.options.languages;
1865
- const densify = i18nDesc.options.densifyOnWrite;
1866
- i18nBlock = {
1867
- ...locales !== void 0 ? { locales } : {},
1868
- ...densify !== void 0 ? { densify } : {}
1869
- };
1870
- }
1871
- const widget = deriveWidget({
1872
- type,
1873
- ...resolved.semanticType !== void 0 ? { semanticType: resolved.semanticType } : {},
1874
- ...dictBlock !== void 0 ? { dict: dictBlock } : {},
1875
- ...lookupBlock !== void 0 ? { lookup: lookupBlock } : {},
1876
- ...blobBlock !== void 0 ? { blob: blobBlock } : {},
1877
- ...resolved.widget !== void 0 ? { resolvedWidget: resolved.widget } : {}
1878
- });
1879
- const editable = !isComputed && key !== "id" && blobBlock === void 0;
1880
- const field = {
1881
- key,
1882
- ...fieldIds?.[key] !== void 0 ? { id: fieldIds[key] } : {},
1883
- type,
1884
- optional: zod?.optional ?? false,
1885
- ...zod?.constraints !== void 0 ? { constraints: zod.constraints } : {},
1886
- label: resolved.label,
1887
- ...resolved.description !== void 0 ? { description: resolved.description } : {},
1888
- ...resolved.group !== void 0 ? { group: resolved.group } : {},
1889
- ...resolved.order !== void 0 ? { order: resolved.order } : {},
1890
- ...resolved.semanticType !== void 0 ? { semanticType: resolved.semanticType } : {},
1891
- ...resolved.unit !== void 0 ? { unit: resolved.unit } : {},
1892
- ...resolved.sensitivity !== void 0 ? { sensitivity: resolved.sensitivity } : {},
1893
- ...resolved.aggregate !== void 0 ? { aggregate: resolved.aggregate } : {},
1894
- ...resolved.aliases !== void 0 ? { aliases: resolved.aliases } : {},
1895
- ...resolved.displayFor !== void 0 ? { displayFor: resolved.displayFor } : {},
1896
- ...refBlock !== void 0 ? { ref: refBlock } : {},
1897
- ...moneyBlock !== void 0 ? { money: moneyBlock } : {},
1898
- ...dictBlock !== void 0 ? { dict: dictBlock } : {},
1899
- ...lookupBlock !== void 0 ? { lookup: lookupBlock } : {},
1900
- ...blobBlock !== void 0 ? { blob: blobBlock } : {},
1901
- ...isComputed ? { computed: true } : {},
1902
- ...i18nBlock !== void 0 ? { i18n: i18nBlock } : {},
1903
- widget,
1904
- editable,
1905
- ...cls !== void 0 ? {
1906
- classified: {
1907
- preset: cls.preset,
1908
- storage: cls.storage,
1909
- list: cls.list.kind === "omit" ? "omit" : cls.list.kind === "mask" ? { mask: cls.list.pattern } : { rider: cls.list.rider },
1910
- ...cls.equatable === true ? { equatable: true } : {}
1911
- }
1912
- } : {},
1913
- ...taintPosture !== void 0 ? { taint: { posture: taintPosture, forcedBy: taint?.provenance?.get(key) ?? [] } } : {}
1914
- };
1915
- fields.push(field);
1916
- }
1917
- const collectionMeta = {
1918
- ...meta,
1919
- label: meta?.label ?? humanizeFieldKey(collection)
1920
- };
1921
- return {
1922
- collection,
1923
- fields,
1924
- meta: collectionMeta
1925
- };
1926
- }
1927
-
1928
1579
  // src/kernel/put-many-atomic.ts
1929
1580
  var toRevertLeg = ({ op, priorEnvelope }) => ({
1930
1581
  vaultName: op.vaultName,
@@ -3841,7 +3492,8 @@ var Collection = class {
3841
3492
  this.indexes?.upsert(id, indexed, prior ? prior.record : null);
3842
3493
  this.uniqueConstraints?.upsert(id, indexed, prior?.record);
3843
3494
  }
3844
- await this._onRecordMutated(id, "put", "local-write", { record: event, version });
3495
+ const priorForTrigger = prior ? prior.record : null;
3496
+ await this._onRecordMutated(id, "put", "local-write", { record: event, version, prior: priorForTrigger });
3845
3497
  }
3846
3498
  /**
3847
3499
  * The pre-envelope stages both write paths share (#904): permission + tier
@@ -4079,34 +3731,23 @@ var Collection = class {
4079
3731
  const record = await this.codec.decryptRecord({ collection: this.name, id }, env, {});
4080
3732
  return record === null ? null : { record, version: env._v };
4081
3733
  }
4082
- /**
4083
- * @internal Ids of records whose top-level `field` equals `value`.
4084
- * Uses the FK index when the field is indexed (O(matches)); otherwise a
4085
- * linear scan (O(N) — fine for small child sets; index the FK to scale).
4086
- */
3734
+ /** @internal Ids of records whose top-level `field` equals `value` — delegates to the composite scan. */
4087
3735
  async _findMatchingIds(field, value) {
4088
- const hit = this.getIndexes()?.lookupEqual(field, value);
4089
- if (hit) return [...hit];
4090
- const target = String(value);
4091
- const matches = (rec) => {
4092
- const fv = rec[field];
4093
- return (typeof fv === "string" || typeof fv === "number") && String(fv) === target;
4094
- };
4095
- if (!this.lazy) {
4096
- await this.ensureHydrated();
4097
- const out2 = [];
4098
- for (const [rid, e] of this.cache) {
4099
- if (matches(e.record)) out2.push(rid);
4100
- }
4101
- return out2;
4102
- }
4103
- const ids = await this.adapter.list(this.vault, this.name);
4104
- const out = [];
4105
- for (const rid of ids) {
4106
- const raw = await this._getStoredRecord(rid);
4107
- if (raw !== null && matches(raw)) out.push(rid);
4108
- }
4109
- return out;
3736
+ if (typeof value !== "string" && typeof value !== "number") return [];
3737
+ return this._findMatchingCompositeIds([{ field, value: String(value) }]);
3738
+ }
3739
+ /** @internal — conjunction fan-out for composite triggerBy (#1249). First indexed pair narrows,
3740
+ * filtered by the OTHER pairs only; zero reads when the index alone decides membership. */
3741
+ async _findMatchingCompositeIds(pairs) {
3742
+ if (!this.lazy) await this.ensureHydrated();
3743
+ const i = pairs.findIndex((p) => this.getIndexes()?.lookupEqual(p.field, p.value));
3744
+ const hit = i < 0 ? null : this.getIndexes().lookupEqual(pairs[i].field, pairs[i].value);
3745
+ const residual = i < 0 ? pairs : pairs.filter((_, j) => j !== i);
3746
+ return findMatchingIdsByPairs(residual, {
3747
+ indexCandidates: hit ? [...hit] : null,
3748
+ listIds: async () => this.lazy ? this.adapter.list(this.vault, this.name) : [...this.cache.keys()],
3749
+ getRecord: async (id) => this.lazy ? await this._getStoredRecord(id) : this.cache.get(id)?.record ?? null
3750
+ });
4110
3751
  }
4111
3752
  /** @internal — ctx for `putDerivedOutput`'s frozen-period skip+audit (#638 Task 5). */
4112
3753
  /** What `with-formula/materialized-views/dispatch.ts` needs from this collection (#842). */
@@ -4189,18 +3830,22 @@ var Collection = class {
4189
3830
  if (spec) await this.recomputeRollup(spec, intent.parentId, { collection: this.name, id: "<sync-delete>" }, wave);
4190
3831
  }
4191
3832
  }
3833
+ /** Extras added onto {@link #derivationDeleteCtx} — shared by `dispatchDerivations` and `dispatchTriggerDerivationsOnDelete` (#1249). */
3834
+ #derivationDispatchCtx() {
3835
+ return { ...this.#derivationDeleteCtx(this.derivationSource), via: this.via, recomputeRollup: this.recomputeRollup.bind(this), dispatchCtx: this.#dispatchCtx.bind(this), trackPut: this.#trackPut.bind(this) };
3836
+ }
4192
3837
  /** @internal `wave` (#638 Task 4) — threaded to `recomputeRollup` for the sync/cutover/restore
4193
3838
  * dispatch wave's per-target dedup; `undefined` on the local-write path (byte-identical). */
4194
- async dispatchDerivations(id, record, version, wave) {
3839
+ async dispatchDerivations(id, record, version, wave, prior) {
4195
3840
  if (this.derivationSource === void 0) return;
4196
- const { dispatchDerivations } = await import("./dispatch-IM52HDXT.js");
4197
- return dispatchDerivations({
4198
- ...this.#derivationDeleteCtx(this.derivationSource),
4199
- via: this.via,
4200
- recomputeRollup: (spec, parentId, source, w) => this.recomputeRollup(spec, parentId, source, w),
4201
- dispatchCtx: (source) => this.#dispatchCtx(source),
4202
- trackPut: (txCtx, collectionName, rid, prior) => this.#trackPut(txCtx, collectionName, rid, prior)
4203
- }, id, record, version, wave);
3841
+ const { dispatchDerivations } = await import("./dispatch-XEBHUGBV.js");
3842
+ return dispatchDerivations(this.#derivationDispatchCtx(), id, record, version, wave, prior);
3843
+ }
3844
+ /** @internal — trigger fan-out for a deleted parent (#1249); see dispatch.ts. */
3845
+ async dispatchTriggerDerivationsOnDelete(id, deleted) {
3846
+ if (this.derivationSource === void 0) return;
3847
+ const { dispatchTriggerDerivationsOnDelete } = await import("./dispatch-XEBHUGBV.js");
3848
+ return dispatchTriggerDerivationsOnDelete(this.#derivationDispatchCtx(), id, deleted);
4204
3849
  }
4205
3850
  /**
4206
3851
  * Delete a record by ID. Runs inside the hub's write-queue tracker
@@ -4438,7 +4083,10 @@ var Collection = class {
4438
4083
  if (!internal) {
4439
4084
  await this.dispatchMaterializedViewsOnDelete(id);
4440
4085
  await this.dispatchArrayDerivationsOnDelete(id);
4441
- if (existing) await this.dispatchRollupsOnDelete(id, existing.record);
4086
+ if (existing) {
4087
+ await this.dispatchRollupsOnDelete(id, existing.record);
4088
+ await this.dispatchTriggerDerivationsOnDelete(id, existing.record);
4089
+ }
4442
4090
  }
4443
4091
  return true;
4444
4092
  }
@@ -4508,7 +4156,7 @@ var Collection = class {
4508
4156
  */
4509
4157
  async dispatchArrayDerivationsOnDelete(id, eraseRecordShapeToo = false) {
4510
4158
  if (this.derivationSource === void 0) return 0;
4511
- const { dispatchArrayDerivationsOnDelete } = await import("./dispatch-IM52HDXT.js");
4159
+ const { dispatchArrayDerivationsOnDelete } = await import("./dispatch-XEBHUGBV.js");
4512
4160
  return dispatchArrayDerivationsOnDelete(this.#derivationDeleteCtx(this.derivationSource), id, eraseRecordShapeToo);
4513
4161
  }
4514
4162
  /**
@@ -5206,7 +4854,7 @@ var Collection = class {
5206
4854
  this.emitter.emit("change", { vault: this.vault, collection: this.name, id, action: "put" });
5207
4855
  this.searchIndexStore?.markDirty();
5208
4856
  await this.onAccess?.("put", id);
5209
- await this.dispatchDerivations(id, record, version);
4857
+ await this.dispatchDerivations(id, record, version, void 0, ctx.prior);
5210
4858
  await this.dispatchMaterializedViews(id, record);
5211
4859
  return;
5212
4860
  }
@@ -8973,7 +8621,7 @@ var Vault = class {
8973
8621
  // Vaults without derivations skip this so `Collection.put`'s
8974
8622
  // `if (this.derivationSource)` branch no-ops without touching the
8975
8623
  // derivation service code.
8976
- ...this.derivationRegistry !== null ? {
8624
+ ...this.derivationRegistry !== null ? (this.derivationRegistry.validateFieldsFor(collectionName, options?.schema, Object.keys({ ...options?.fieldMeta, ...options?.moneyFields, ...options?.dictKeyFields, ...options?.refs, ...options?.computed, ...options?.i18nFields, ...options?.lookupFields, ...options?.blobFields, ...options?.classifiedFields })), {
8977
8625
  derivationSource: {
8978
8626
  registry: () => this.derivationRegistry,
8979
8627
  getCollection: (name) => this.collection(name),
@@ -8983,7 +8631,7 @@ var Vault = class {
8983
8631
  setActiveTxContext: (ctx) => this.noydb._setActiveTxContext(ctx),
8984
8632
  clearActiveTxContext: (ctx) => this.noydb._clearActiveTxContext(ctx)
8985
8633
  }
8986
- } : {},
8634
+ }) : {},
8987
8635
  ...this.materializedViewRegistry !== null ? {
8988
8636
  materializedViewSource: {
8989
8637
  registry: () => this.materializedViewRegistry,
@@ -10256,7 +9904,7 @@ var Vault = class {
10256
9904
  async _initDerivations(handles) {
10257
9905
  if (handles.length === 0) return;
10258
9906
  const [{ DerivationRegistry }, { ReadOnlyVaultFacade }] = await Promise.all([
10259
- import("./registry-FZXPQRAB.js"),
9907
+ import("./registry-BZQIVNNO.js"),
10260
9908
  import("./read-only-facade-CHCKSEPD.js")
10261
9909
  ]);
10262
9910
  const registry = new DerivationRegistry();
@@ -10925,7 +10573,7 @@ var Vault = class {
10925
10573
  * @see design-history/2026-05-22-schema-dump-design.md
10926
10574
  */
10927
10575
  async dumpSchema(opts = {}) {
10928
- const { dumpVaultSchema } = await import("./walk-G3CZIL4L.js");
10576
+ const { dumpVaultSchema } = await import("./walk-P3E6QSNC.js");
10929
10577
  return dumpVaultSchema(this, opts);
10930
10578
  }
10931
10579
  /**
@@ -11053,7 +10701,7 @@ var Vault = class {
11053
10701
  * both modes round-trip cleanly.
11054
10702
  */
11055
10703
  async dump() {
11056
- const { dumpVault } = await import("./backup-VASRVLDZ.js");
10704
+ const { dumpVault } = await import("./backup-R6A4VZRX.js");
11057
10705
  return dumpVault(this.backupContext());
11058
10706
  }
11059
10707
  /**
@@ -11105,7 +10753,7 @@ var Vault = class {
11105
10753
  * — there's no chain to verify against.
11106
10754
  */
11107
10755
  async load(backupJson) {
11108
- const { loadVault } = await import("./backup-VASRVLDZ.js");
10756
+ const { loadVault } = await import("./backup-R6A4VZRX.js");
11109
10757
  return loadVault(this.backupContext(), backupJson);
11110
10758
  }
11111
10759
  /**
@@ -11137,7 +10785,7 @@ var Vault = class {
11137
10785
  * way to detect tampering of an in-place vault.
11138
10786
  */
11139
10787
  async verifyBackupIntegrity() {
11140
- const { verifyBackupIntegrity } = await import("./backup-VASRVLDZ.js");
10788
+ const { verifyBackupIntegrity } = await import("./backup-R6A4VZRX.js");
11141
10789
  return verifyBackupIntegrity(this.backupContext());
11142
10790
  }
11143
10791
  /**
@@ -11367,7 +11015,7 @@ var Vault = class {
11367
11015
  * is the live validator object, not a serialization of it).
11368
11016
  */
11369
11017
  async exportJSON(opts = {}) {
11370
- const { exportVaultJSON } = await import("./backup-VASRVLDZ.js");
11018
+ const { exportVaultJSON } = await import("./backup-R6A4VZRX.js");
11371
11019
  return exportVaultJSON(this.backupContext(), opts);
11372
11020
  }
11373
11021
  };
@@ -14702,4 +14350,4 @@ export {
14702
14350
  Noydb,
14703
14351
  createNoydb
14704
14352
  };
14705
- //# sourceMappingURL=chunk-I6DGKPTY.js.map
14353
+ //# sourceMappingURL=chunk-XMF3GKUR.js.map