@noy-db/hub 0.2.0-pre.29 → 0.2.0-pre.30

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 (170) hide show
  1. package/dist/aggregate/index.js +1 -0
  2. package/dist/aggregate/index.js.map +1 -1
  3. package/dist/attestation/index.d.cts +1 -1
  4. package/dist/attestation/index.d.ts +1 -1
  5. package/dist/attestation/index.js +4 -3
  6. package/dist/attestation/index.js.map +1 -1
  7. package/dist/blobs/index.d.cts +3 -3
  8. package/dist/blobs/index.d.ts +3 -3
  9. package/dist/blobs/index.js +2 -1
  10. package/dist/blobs/index.js.map +1 -1
  11. package/dist/bundle/index.cjs +16825 -893
  12. package/dist/bundle/index.cjs.map +1 -1
  13. package/dist/bundle/index.d.cts +3 -3
  14. package/dist/bundle/index.d.ts +3 -3
  15. package/dist/bundle/index.js +2 -1
  16. package/dist/bundle/index.js.map +1 -1
  17. package/dist/{chunk-DJO4OYCJ.js → chunk-33EQCZXE.js} +2 -2
  18. package/dist/{chunk-ZDW22N3E.js → chunk-BVKLJBJJ.js} +694 -191
  19. package/dist/chunk-BVKLJBJJ.js.map +1 -0
  20. package/dist/{chunk-REHF3HSJ.js → chunk-K4JID2ZE.js} +16 -3
  21. package/dist/chunk-K4JID2ZE.js.map +1 -0
  22. package/dist/{chunk-553CK4E2.js → chunk-OCYFFBZS.js} +2 -2
  23. package/dist/chunk-PZ5AY32C.js +10 -0
  24. package/dist/{chunk-45QJXLLS.js → chunk-Y6YUWZTS.js} +2 -2
  25. package/dist/{chunk-6BSYMFYS.js → chunk-ZK66B5EY.js} +2 -2
  26. package/dist/{chunk-BITB3T5Z.js → chunk-ZPJSQPQH.js} +2 -2
  27. package/dist/consent/index.d.cts +2 -2
  28. package/dist/consent/index.d.ts +2 -2
  29. package/dist/consent/index.js +1 -0
  30. package/dist/consent/index.js.map +1 -1
  31. package/dist/crdt/index.js +1 -0
  32. package/dist/crdt/index.js.map +1 -1
  33. package/dist/{crypto-G6XU2V2Y.js → crypto-OSIV2IIW.js} +2 -1
  34. package/dist/{decrypt-partition-DDSArPPW.d.cts → decrypt-partition-C0iDpbSd.d.cts} +1 -1
  35. package/dist/{decrypt-partition-5Gt0EcTc.d.ts → decrypt-partition-Mhjh6nnG.d.ts} +1 -1
  36. package/dist/{delegation-ZEH4LKEM.js → delegation-BQTRJATI.js} +2 -1
  37. package/dist/derivations/index.d.cts +3 -3
  38. package/dist/derivations/index.d.ts +3 -3
  39. package/dist/derivations/index.js +1 -0
  40. package/dist/{dev-unlock-CIkHrcRm.d.cts → dev-unlock-0Z6yxfS7.d.cts} +1 -1
  41. package/dist/{dev-unlock-BF9IhLPn.d.ts → dev-unlock-DJ3IhgY9.d.ts} +1 -1
  42. package/dist/{executor-DWVP4BSJ.js → executor-KYSKFJ2R.js} +2 -1
  43. package/dist/{executor-HO3SIRSF.js → executor-M7W3NEKR.js} +2 -1
  44. package/dist/{executor-HB2YMIYC.js → executor-VDTDGWO6.js} +2 -1
  45. package/dist/{fanout-sidecar-BMT7I6FI.js → fanout-sidecar-AZALISHB.js} +2 -1
  46. package/dist/{fanout-sidecar-BMT7I6FI.js.map → fanout-sidecar-AZALISHB.js.map} +1 -1
  47. package/dist/forget/index.js +1 -0
  48. package/dist/guards/index.d.cts +3 -3
  49. package/dist/guards/index.d.ts +3 -3
  50. package/dist/guards/index.js +1 -0
  51. package/dist/{hash-Jl0qarQx.d.ts → hash-DLwkYf1d.d.ts} +1 -1
  52. package/dist/{hash-DfhndFcd.d.cts → hash-Db8ncXGr.d.cts} +1 -1
  53. package/dist/history/index.d.cts +3 -3
  54. package/dist/history/index.d.ts +3 -3
  55. package/dist/history/index.js +1 -0
  56. package/dist/history/index.js.map +1 -1
  57. package/dist/i18n/index.cjs +15 -2
  58. package/dist/i18n/index.cjs.map +1 -1
  59. package/dist/i18n/index.d.cts +2 -2
  60. package/dist/i18n/index.d.ts +2 -2
  61. package/dist/i18n/index.js +2 -1
  62. package/dist/i18n/index.js.map +1 -1
  63. package/dist/{index-DcxTv3zx.d.ts → index-CMRIx_zx.d.ts} +1 -1
  64. package/dist/{index-DPG2nFmT.d.cts → index-xJEPkvMb.d.cts} +1 -1
  65. package/dist/index.cjs +16956 -1011
  66. package/dist/index.cjs.map +1 -1
  67. package/dist/index.d.cts +19 -16
  68. package/dist/index.d.ts +19 -16
  69. package/dist/index.js +8 -7
  70. package/dist/index.js.map +1 -1
  71. package/dist/indexing/index.js +1 -0
  72. package/dist/indexing/index.js.map +1 -1
  73. package/dist/{issue-FZRTVGRE.js → issue-DPHRF2TI.js} +2 -1
  74. package/dist/kernel/index.cjs.map +1 -1
  75. package/dist/kernel/index.d.cts +2 -2
  76. package/dist/kernel/index.d.ts +2 -2
  77. package/dist/kernel/index.js +1 -0
  78. package/dist/{ledger-PMTR2Q62.js → ledger-CI7GSMLB.js} +2 -1
  79. package/dist/materialized-views/index.d.cts +3 -3
  80. package/dist/materialized-views/index.d.ts +3 -3
  81. package/dist/materialized-views/index.js +2 -1
  82. package/dist/{mime-magic-BOI-I5dq.d.ts → mime-magic-CacDBwYp.d.ts} +1 -1
  83. package/dist/{mime-magic-C0TM7FtF.d.cts → mime-magic-sdMzsfVK.d.cts} +1 -1
  84. package/dist/{noydb-Y3ZLZNXA.js → noydb-5MIBD77B.js} +6 -5
  85. package/dist/overlay-views/index.d.cts +3 -3
  86. package/dist/overlay-views/index.d.ts +3 -3
  87. package/dist/overlay-views/index.js +1 -0
  88. package/dist/periods/index.d.cts +2 -2
  89. package/dist/periods/index.d.ts +2 -2
  90. package/dist/periods/index.js +2 -1
  91. package/dist/{public-envelope-S2S2VR3F.js → public-envelope-MFMBFJLZ.js} +2 -1
  92. package/dist/query/index.js +1 -0
  93. package/dist/{read-only-facade-EX6WZZBP.js → read-only-facade-3OQRZ3VS.js} +2 -1
  94. package/dist/{registry-DKEXOJVO.js → registry-IX5WKK4F.js} +2 -1
  95. package/dist/{registry-53A55ZZE.js → registry-LMHO5265.js} +2 -1
  96. package/dist/{registry-IEU6ATO7.js → registry-TXCKWH26.js} +2 -1
  97. package/dist/{registry-FKL4SLU4.js → registry-VFEDQSYV.js} +2 -1
  98. package/dist/{revoke-AOCAVR56.js → revoke-5PUOZPJJ.js} +2 -1
  99. package/dist/sealed-record/index.js +1 -0
  100. package/dist/sealed-record/index.js.map +1 -1
  101. package/dist/session/index.d.cts +3 -3
  102. package/dist/session/index.d.ts +3 -3
  103. package/dist/session/index.js +1 -0
  104. package/dist/session/index.js.map +1 -1
  105. package/dist/shadow/index.d.cts +2 -2
  106. package/dist/shadow/index.d.ts +2 -2
  107. package/dist/shadow/index.js +1 -0
  108. package/dist/shadow/index.js.map +1 -1
  109. package/dist/{signer-JMK6W2Y6.js → signer-UB5TQOZ6.js} +2 -1
  110. package/dist/snapshots/index.d.cts +2 -2
  111. package/dist/snapshots/index.d.ts +2 -2
  112. package/dist/snapshots/index.js +1 -0
  113. package/dist/snapshots/index.js.map +1 -1
  114. package/dist/{stale-IIIGOHBW.js → stale-J3TUF5C5.js} +3 -2
  115. package/dist/store/index.d.cts +2 -2
  116. package/dist/store/index.d.ts +2 -2
  117. package/dist/store/index.js +1 -0
  118. package/dist/sync/index.d.cts +1 -1
  119. package/dist/sync/index.d.ts +1 -1
  120. package/dist/sync/index.js +1 -0
  121. package/dist/sync/index.js.map +1 -1
  122. package/dist/team/index.d.cts +2 -2
  123. package/dist/team/index.d.ts +2 -2
  124. package/dist/team/index.js +1 -0
  125. package/dist/{transition-guard-BixCDmBI.d.ts → transition-guard-J04-jime.d.ts} +1 -1
  126. package/dist/{transition-guard-DnAlUf9R.d.cts → transition-guard-tWZIsaXe.d.cts} +1 -1
  127. package/dist/tx/index.d.cts +2 -2
  128. package/dist/tx/index.d.ts +2 -2
  129. package/dist/tx/index.js +3 -2
  130. package/dist/tx/index.js.map +1 -1
  131. package/dist/{types-Ba1vQ3AY.d.cts → types-CdVfiQgt.d.cts} +444 -161
  132. package/dist/{types-CUmZYJwN.d.ts → types-DHn9lEP0.d.ts} +444 -161
  133. package/dist/{ulid-COREQ2RQ.js → ulid-KEPZMD2N.js} +2 -1
  134. package/dist/ulid-KEPZMD2N.js.map +1 -0
  135. package/dist/util/index.js +1 -0
  136. package/dist/util/index.js.map +1 -1
  137. package/dist/{with-materialized-view-Bjx6VYPc.d.ts → with-materialized-view-DNfzC5lH.d.ts} +1 -1
  138. package/dist/{with-materialized-view-Z_aHLln6.d.cts → with-materialized-view-DfgPcvi9.d.cts} +1 -1
  139. package/dist/{with-overlayed-view-pTOFgHRq.d.cts → with-overlayed-view-Cvfkx1lg.d.cts} +1 -1
  140. package/dist/{with-overlayed-view-B8PkL179.d.ts → with-overlayed-view-qk3lbhOd.d.ts} +1 -1
  141. package/dist/{with-rollup-Cd3t01Mz.d.ts → with-rollup-Dd3_ZG4b.d.ts} +1 -1
  142. package/dist/{with-rollup-D9qQoffP.d.cts → with-rollup-nIxo7h9z.d.cts} +1 -1
  143. package/dist/zod-HAJM7LMS.js +14763 -0
  144. package/dist/zod-HAJM7LMS.js.map +1 -0
  145. package/package.json +4 -4
  146. package/dist/chunk-REHF3HSJ.js.map +0 -1
  147. package/dist/chunk-ZDW22N3E.js.map +0 -1
  148. /package/dist/{chunk-DJO4OYCJ.js.map → chunk-33EQCZXE.js.map} +0 -0
  149. /package/dist/{chunk-553CK4E2.js.map → chunk-OCYFFBZS.js.map} +0 -0
  150. /package/dist/{crypto-G6XU2V2Y.js.map → chunk-PZ5AY32C.js.map} +0 -0
  151. /package/dist/{chunk-45QJXLLS.js.map → chunk-Y6YUWZTS.js.map} +0 -0
  152. /package/dist/{chunk-6BSYMFYS.js.map → chunk-ZK66B5EY.js.map} +0 -0
  153. /package/dist/{chunk-BITB3T5Z.js.map → chunk-ZPJSQPQH.js.map} +0 -0
  154. /package/dist/{delegation-ZEH4LKEM.js.map → crypto-OSIV2IIW.js.map} +0 -0
  155. /package/dist/{executor-DWVP4BSJ.js.map → delegation-BQTRJATI.js.map} +0 -0
  156. /package/dist/{executor-HB2YMIYC.js.map → executor-KYSKFJ2R.js.map} +0 -0
  157. /package/dist/{executor-HO3SIRSF.js.map → executor-M7W3NEKR.js.map} +0 -0
  158. /package/dist/{issue-FZRTVGRE.js.map → executor-VDTDGWO6.js.map} +0 -0
  159. /package/dist/{ledger-PMTR2Q62.js.map → issue-DPHRF2TI.js.map} +0 -0
  160. /package/dist/{noydb-Y3ZLZNXA.js.map → ledger-CI7GSMLB.js.map} +0 -0
  161. /package/dist/{public-envelope-S2S2VR3F.js.map → noydb-5MIBD77B.js.map} +0 -0
  162. /package/dist/{read-only-facade-EX6WZZBP.js.map → public-envelope-MFMBFJLZ.js.map} +0 -0
  163. /package/dist/{registry-53A55ZZE.js.map → read-only-facade-3OQRZ3VS.js.map} +0 -0
  164. /package/dist/{registry-DKEXOJVO.js.map → registry-IX5WKK4F.js.map} +0 -0
  165. /package/dist/{registry-FKL4SLU4.js.map → registry-LMHO5265.js.map} +0 -0
  166. /package/dist/{registry-IEU6ATO7.js.map → registry-TXCKWH26.js.map} +0 -0
  167. /package/dist/{revoke-AOCAVR56.js.map → registry-VFEDQSYV.js.map} +0 -0
  168. /package/dist/{signer-JMK6W2Y6.js.map → revoke-5PUOZPJJ.js.map} +0 -0
  169. /package/dist/{stale-IIIGOHBW.js.map → signer-UB5TQOZ6.js.map} +0 -0
  170. /package/dist/{ulid-COREQ2RQ.js.map → stale-J3TUF5C5.js.map} +0 -0
@@ -10,7 +10,7 @@ import {
10
10
  import {
11
11
  TxContext,
12
12
  revertExecuted
13
- } from "./chunk-BITB3T5Z.js";
13
+ } from "./chunk-ZPJSQPQH.js";
14
14
  import {
15
15
  OverlayedCollection
16
16
  } from "./chunk-MPIZQGFA.js";
@@ -67,11 +67,11 @@ import {
67
67
  } from "./chunk-LXKBG52H.js";
68
68
  import {
69
69
  PERIODS_COLLECTION
70
- } from "./chunk-553CK4E2.js";
70
+ } from "./chunk-OCYFFBZS.js";
71
71
  import {
72
72
  isDictCollectionName,
73
73
  isStaticDictDescriptor
74
- } from "./chunk-REHF3HSJ.js";
74
+ } from "./chunk-K4JID2ZE.js";
75
75
  import {
76
76
  getAtPath,
77
77
  resolvePolicy,
@@ -470,6 +470,89 @@ function formatPath(path) {
470
470
  ).join(".");
471
471
  }
472
472
 
473
+ // src/persisted-schemas/canonicalize.ts
474
+ function canonicalize(value) {
475
+ if (value === null || typeof value !== "object") {
476
+ return JSON.stringify(value);
477
+ }
478
+ if (Array.isArray(value)) {
479
+ return "[" + value.map(canonicalize).join(",") + "]";
480
+ }
481
+ const obj = value;
482
+ const keys = Object.keys(obj).sort();
483
+ const parts = keys.map((k) => JSON.stringify(k) + ":" + canonicalize(obj[k]));
484
+ return "{" + parts.join(",") + "}";
485
+ }
486
+
487
+ // src/persisted-schemas/derive.ts
488
+ function isZodSchema(value) {
489
+ if (value === null || typeof value !== "object") return false;
490
+ const std = value["~standard"];
491
+ if (std && typeof std === "object" && std.vendor === "zod") return true;
492
+ const def = value._def;
493
+ if (!def || typeof def !== "object") return false;
494
+ return typeof def.typeName === "string" && def.typeName.startsWith("Zod");
495
+ }
496
+ function detectKind(validator) {
497
+ if (isZodSchema(validator)) return "Zod";
498
+ return "Unknown";
499
+ }
500
+ function isZod4Schema(value) {
501
+ if (value === null || typeof value !== "object") return false;
502
+ return "_zod" in value;
503
+ }
504
+ async function loadZodToJsonSchemaConverter() {
505
+ try {
506
+ const mod = await import("zod-to-json-schema");
507
+ if (!mod.zodToJsonSchema) {
508
+ throw new Error("zod-to-json-schema export missing");
509
+ }
510
+ return mod.zodToJsonSchema;
511
+ } catch (err) {
512
+ throw new Error(
513
+ `persistJsonSchema requires the optional peer-dep \`zod-to-json-schema\`. Install it: \`pnpm add zod-to-json-schema\` (or npm/yarn equivalent). Original error: ${err instanceof Error ? err.message : String(err)}`
514
+ );
515
+ }
516
+ }
517
+ async function loadZodV4Converter() {
518
+ try {
519
+ const mod = await import("./zod-HAJM7LMS.js");
520
+ if (typeof mod.toJSONSchema !== "function") {
521
+ throw new Error("zod.toJSONSchema not available (zod v4 required)");
522
+ }
523
+ return mod.toJSONSchema;
524
+ } catch (err) {
525
+ throw new Error(
526
+ `persistJsonSchema with a Zod v4 schema requires zod@4 with toJSONSchema. Original error: ${err instanceof Error ? err.message : String(err)}`
527
+ );
528
+ }
529
+ }
530
+ async function derivePersistedSchema(validator) {
531
+ const kind = detectKind(validator);
532
+ const derivedAt = (/* @__PURE__ */ new Date()).toISOString();
533
+ if (kind === "Zod") {
534
+ let jsonSchema;
535
+ if (isZod4Schema(validator)) {
536
+ const convert = await loadZodV4Converter();
537
+ jsonSchema = convert(validator);
538
+ } else {
539
+ const convert = await loadZodToJsonSchemaConverter();
540
+ jsonSchema = convert(validator);
541
+ }
542
+ const canonical = canonicalize(jsonSchema);
543
+ const hash = await sha256Hex(new TextEncoder().encode(canonical));
544
+ return { _noydb_schema: 1, kind, jsonSchema, hash, derivedAt };
545
+ }
546
+ return {
547
+ _noydb_schema: 1,
548
+ kind,
549
+ jsonSchema: null,
550
+ hash: null,
551
+ reason: `derivation not yet supported for kind=${kind} (v0 supports Zod only)`,
552
+ derivedAt
553
+ };
554
+ }
555
+
473
556
  // src/history/strategy.ts
474
557
  function notEnabled2(op) {
475
558
  return new Error(
@@ -1048,6 +1131,385 @@ function buildUniqueConstraintSet(collectionName, indexes, mode) {
1048
1131
  return new UniqueConstraintSet(collectionName, uniqueDefs);
1049
1132
  }
1050
1133
 
1134
+ // src/introspection/field-meta.ts
1135
+ var FieldMetaUnknownFieldError = class extends Error {
1136
+ constructor(collection, key) {
1137
+ super(`fieldMeta for collection "${collection}" references unknown field "${key}". Declare it in the schema/config or remove the fieldMeta entry.`);
1138
+ this.collection = collection;
1139
+ this.key = key;
1140
+ this.name = "FieldMetaUnknownFieldError";
1141
+ }
1142
+ collection;
1143
+ key;
1144
+ };
1145
+ function validateFieldMetaKeys(collection, fieldMeta, knownFields) {
1146
+ for (const key of Object.keys(fieldMeta)) {
1147
+ if (!knownFields.has(key)) throw new FieldMetaUnknownFieldError(collection, key);
1148
+ }
1149
+ }
1150
+ function humanizeFieldKey(key) {
1151
+ 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(" ");
1152
+ }
1153
+ function resolveFieldMeta(key, inputs) {
1154
+ const { channel, zodMeta, inferred } = inputs;
1155
+ const pick = (k) => channel?.[k] ?? zodMeta?.[k] ?? inferred?.[k];
1156
+ const description = pick("description");
1157
+ const semanticType = pick("semanticType");
1158
+ const unit = pick("unit");
1159
+ const sensitivity = pick("sensitivity");
1160
+ const aggregate = pick("aggregate");
1161
+ const aliases = pick("aliases");
1162
+ const displayFor = pick("displayFor");
1163
+ const widget = pick("widget");
1164
+ return {
1165
+ label: pick("label") ?? humanizeFieldKey(key),
1166
+ ...description !== void 0 ? { description } : {},
1167
+ ...semanticType !== void 0 ? { semanticType } : {},
1168
+ ...unit !== void 0 ? { unit } : {},
1169
+ ...sensitivity !== void 0 ? { sensitivity } : {},
1170
+ ...aggregate !== void 0 ? { aggregate } : {},
1171
+ ...aliases !== void 0 ? { aliases } : {},
1172
+ ...displayFor !== void 0 ? { displayFor } : {},
1173
+ ...widget !== void 0 ? { widget } : {}
1174
+ };
1175
+ }
1176
+
1177
+ // src/introspection/fields.ts
1178
+ function jsonSchemaType(node) {
1179
+ if (Array.isArray(node.type)) {
1180
+ const non = node.type.filter((t) => t !== "null");
1181
+ return non[0] ?? "opaque";
1182
+ }
1183
+ if (node.enum && Array.isArray(node.enum)) return "enum";
1184
+ if (node.const !== void 0) return "enum";
1185
+ if (typeof node.type === "string") return node.type;
1186
+ return "opaque";
1187
+ }
1188
+ function constraintsFor(node) {
1189
+ const out = {};
1190
+ if (node.enum) out.values = node.enum;
1191
+ if (node.const !== void 0) out.values = [node.const];
1192
+ if (node.minLength !== void 0) out.minLength = node.minLength;
1193
+ if (node.maxLength !== void 0) out.maxLength = node.maxLength;
1194
+ if (node.pattern !== void 0) out.pattern = node.pattern;
1195
+ if (node.format !== void 0) out.format = node.format;
1196
+ if (node.minimum !== void 0) out.minimum = node.minimum;
1197
+ if (node.maximum !== void 0) out.maximum = node.maximum;
1198
+ if (node.exclusiveMinimum !== void 0) out.gt = node.exclusiveMinimum;
1199
+ if (node.exclusiveMaximum !== void 0) out.lt = node.exclusiveMaximum;
1200
+ return Object.keys(out).length === 0 ? void 0 : out;
1201
+ }
1202
+ function extractObjectFields(obj, source, refs) {
1203
+ const required = new Set(Array.isArray(obj.required) ? obj.required : []);
1204
+ const fields = {};
1205
+ if (!obj.properties || typeof obj.properties !== "object") return { fields, required };
1206
+ for (const [name, node] of Object.entries(obj.properties)) {
1207
+ const descriptor = {
1208
+ type: jsonSchemaType(node),
1209
+ source,
1210
+ ...required.has(name) ? {} : { optional: true },
1211
+ ...refs?.[name] ? { references: `${refs[name].target}.id` } : {}
1212
+ };
1213
+ const constraints = constraintsFor(node);
1214
+ if (constraints) descriptor.constraints = constraints;
1215
+ fields[name] = descriptor;
1216
+ }
1217
+ return { fields, required };
1218
+ }
1219
+ function mergeUnionMembers(members, source, refs) {
1220
+ if (members.length === 0) return {};
1221
+ const extracted = members.filter((m) => m.properties && typeof m.properties === "object").map((m) => extractObjectFields(m, source, refs));
1222
+ if (extracted.length === 0) return {};
1223
+ const allNames = /* @__PURE__ */ new Set();
1224
+ for (const { fields } of extracted) {
1225
+ for (const name of Object.keys(fields)) allNames.add(name);
1226
+ }
1227
+ const memberCount = extracted.length;
1228
+ const out = {};
1229
+ for (const name of allNames) {
1230
+ const presentIn = extracted.filter(({ fields }) => name in fields);
1231
+ const requiredInAll = presentIn.length === memberCount && presentIn.every(({ required }) => required.has(name));
1232
+ const base = presentIn[0].fields[name];
1233
+ const allValues = [];
1234
+ for (const { fields } of presentIn) {
1235
+ const fd = fields[name];
1236
+ if (fd?.constraints?.values && Array.isArray(fd.constraints.values)) {
1237
+ for (const v of fd.constraints.values) {
1238
+ if (!allValues.includes(v)) allValues.push(v);
1239
+ }
1240
+ }
1241
+ }
1242
+ const mergedConstraints = allValues.length > 0 ? { ...base.constraints ?? {}, values: allValues } : base.constraints;
1243
+ const descriptor = {
1244
+ type: base.type,
1245
+ source,
1246
+ ...requiredInAll ? {} : { optional: true },
1247
+ ...base.references ? { references: base.references } : {}
1248
+ };
1249
+ if (mergedConstraints) {
1250
+ descriptor.constraints = mergedConstraints;
1251
+ }
1252
+ out[name] = descriptor;
1253
+ }
1254
+ return out;
1255
+ }
1256
+ function jsonSchemaToFields(jsonSchema, source, refs) {
1257
+ if (!jsonSchema || typeof jsonSchema !== "object") return {};
1258
+ const root = jsonSchema;
1259
+ const unionMembers = root.anyOf ?? root.oneOf;
1260
+ if (Array.isArray(unionMembers) && unionMembers.length > 0) {
1261
+ return mergeUnionMembers(unionMembers, source, refs);
1262
+ }
1263
+ if (!root.properties || typeof root.properties !== "object") return {};
1264
+ const { fields } = extractObjectFields(root, source, refs);
1265
+ return fields;
1266
+ }
1267
+
1268
+ // src/introspection/describe.ts
1269
+ var ZOD_META_KEYS = /* @__PURE__ */ new Set([
1270
+ "label",
1271
+ "description",
1272
+ "unit",
1273
+ "semanticType",
1274
+ "sensitivity",
1275
+ "aggregate",
1276
+ "aliases",
1277
+ "displayFor"
1278
+ ]);
1279
+ async function deriveZodFields(schema) {
1280
+ const envelope = await derivePersistedSchema(schema);
1281
+ if (!envelope.jsonSchema) return {};
1282
+ const isZod4 = isZod4Schema(schema);
1283
+ const jsonSchema = envelope.jsonSchema;
1284
+ const fieldDescriptors = jsonSchemaToFields(jsonSchema, "live-validator");
1285
+ const propertiesRaw = jsonSchema["properties"];
1286
+ const result = {};
1287
+ for (const [key, descriptor] of Object.entries(fieldDescriptors)) {
1288
+ let meta;
1289
+ if (isZod4 && propertiesRaw) {
1290
+ const prop = propertiesRaw[key];
1291
+ if (prop) {
1292
+ const extracted = {};
1293
+ let hasAny = false;
1294
+ for (const mk of ZOD_META_KEYS) {
1295
+ if (mk in prop) {
1296
+ extracted[mk] = prop[mk];
1297
+ hasAny = true;
1298
+ }
1299
+ }
1300
+ if (hasAny) meta = extracted;
1301
+ }
1302
+ }
1303
+ result[key] = {
1304
+ type: descriptor.type,
1305
+ optional: descriptor.optional === true,
1306
+ ...descriptor.constraints !== void 0 ? { constraints: descriptor.constraints } : {},
1307
+ ...meta !== void 0 ? { meta } : {}
1308
+ };
1309
+ }
1310
+ return result;
1311
+ }
1312
+ function deriveWidget(opts) {
1313
+ if (opts.resolvedWidget !== void 0) return opts.resolvedWidget;
1314
+ switch (opts.semanticType) {
1315
+ case "date":
1316
+ case "datetime":
1317
+ return "date";
1318
+ case "currency":
1319
+ return "money";
1320
+ case "entity":
1321
+ return "ref-select";
1322
+ case "url":
1323
+ return "url";
1324
+ case "email":
1325
+ return "email";
1326
+ case "percent":
1327
+ return "number";
1328
+ }
1329
+ if (opts.dict !== void 0) return "select";
1330
+ if (opts.type === "boolean") return "checkbox";
1331
+ if (opts.type === "number") return "number";
1332
+ return "text";
1333
+ }
1334
+ function buildDescription(input) {
1335
+ const { collection, fieldMeta, moneyFields, dictKeyFields, computed, refs, zodFields, dictLabels, meta, i18nFields } = input;
1336
+ if (zodFields !== void 0 && Object.keys(zodFields).length > 0 && fieldMeta !== void 0) {
1337
+ const knownFields = /* @__PURE__ */ new Set([
1338
+ ...Object.keys(moneyFields ?? {}),
1339
+ ...Object.keys(dictKeyFields ?? {}),
1340
+ ...Object.keys(refs),
1341
+ ...Object.keys(computed ?? {}),
1342
+ ...Object.keys(zodFields),
1343
+ ...Object.keys(i18nFields ?? {})
1344
+ ]);
1345
+ validateFieldMetaKeys(collection, fieldMeta, knownFields);
1346
+ }
1347
+ const allKeys = /* @__PURE__ */ new Set([
1348
+ ...Object.keys(moneyFields ?? {}),
1349
+ ...Object.keys(dictKeyFields ?? {}),
1350
+ ...Object.keys(refs),
1351
+ ...Object.keys(computed ?? {}),
1352
+ ...Object.keys(fieldMeta ?? {}),
1353
+ ...Object.keys(zodFields ?? {}),
1354
+ ...Object.keys(i18nFields ?? {})
1355
+ ]);
1356
+ const fields = [];
1357
+ for (const key of [...allKeys].sort()) {
1358
+ const zod = zodFields?.[key];
1359
+ const money = moneyFields?.[key];
1360
+ const dict = dictKeyFields?.[key];
1361
+ const refDesc = refs[key];
1362
+ const isComputed = computed !== void 0 && key in computed;
1363
+ const i18nDesc = i18nFields?.[key];
1364
+ let type = zod?.type ?? "unknown";
1365
+ const inferred = {};
1366
+ let moneyBlock;
1367
+ let dictBlock;
1368
+ let refBlock;
1369
+ if (money) {
1370
+ type = "number";
1371
+ inferred.semanticType = "currency";
1372
+ inferred.aggregate = "sum";
1373
+ const currency = money.soleCurrency();
1374
+ const scale = currency !== void 0 ? money.scaleFor(currency) : void 0;
1375
+ moneyBlock = {
1376
+ mode: money.mode,
1377
+ ...currency !== void 0 ? { currency } : {},
1378
+ ...scale !== void 0 ? { scale } : {},
1379
+ ...money.rounding !== void 0 ? { rounding: money.rounding } : {}
1380
+ };
1381
+ } else if (refDesc) {
1382
+ type = refDesc.isArray ? "array" : "string";
1383
+ inferred.semanticType = "entity";
1384
+ refBlock = {
1385
+ target: refDesc.target,
1386
+ mode: refDesc.mode,
1387
+ ...refDesc.isArray ? { isArray: true } : {}
1388
+ };
1389
+ } else if (dict) {
1390
+ type = "enum";
1391
+ if (isStaticDictDescriptor(dict)) {
1392
+ const displayLocale = dict.displayLocale;
1393
+ const values = dict.keys.map((k) => {
1394
+ const localeMap = dict.table[k];
1395
+ const label = displayLocale !== void 0 ? localeMap?.[displayLocale] ?? void 0 : void 0;
1396
+ return label !== void 0 ? { value: k, label } : { value: k };
1397
+ });
1398
+ dictBlock = { name: dict.name, static: true, values };
1399
+ } else {
1400
+ const labelMap = dictLabels?.[dict.name];
1401
+ const labelMapHasEntries = labelMap !== void 0 && Object.keys(labelMap).length > 0;
1402
+ if (labelMapHasEntries) {
1403
+ const values = Object.entries(labelMap).map(([value, label]) => ({ value, label }));
1404
+ dictBlock = { name: dict.name, static: false, values };
1405
+ } else if (dict.keys !== void 0) {
1406
+ const values = dict.keys.map((k) => {
1407
+ const label = dict.labels?.[k];
1408
+ return label !== void 0 ? { value: k, label } : { value: k };
1409
+ });
1410
+ dictBlock = { name: dict.name, static: false, values };
1411
+ } else {
1412
+ dictBlock = { name: dict.name, static: false };
1413
+ }
1414
+ }
1415
+ } else if (i18nDesc) {
1416
+ type = "string";
1417
+ } else if (isComputed) {
1418
+ }
1419
+ const channelEntry = fieldMeta?.[key];
1420
+ const zodMeta = zod?.meta;
1421
+ const resolved = resolveFieldMeta(key, {
1422
+ ...channelEntry !== void 0 ? { channel: channelEntry } : {},
1423
+ ...zodMeta !== void 0 ? { zodMeta } : {},
1424
+ inferred
1425
+ });
1426
+ let i18nBlock;
1427
+ if (i18nDesc !== void 0) {
1428
+ const locales = i18nDesc.options.languages;
1429
+ const densify = i18nDesc.options.densifyOnWrite;
1430
+ i18nBlock = {
1431
+ ...locales !== void 0 ? { locales } : {},
1432
+ ...densify !== void 0 ? { densify } : {}
1433
+ };
1434
+ }
1435
+ const widget = deriveWidget({
1436
+ type,
1437
+ ...resolved.semanticType !== void 0 ? { semanticType: resolved.semanticType } : {},
1438
+ ...dictBlock !== void 0 ? { dict: dictBlock } : {},
1439
+ ...resolved.widget !== void 0 ? { resolvedWidget: resolved.widget } : {}
1440
+ });
1441
+ const editable = !isComputed && key !== "id";
1442
+ const field = {
1443
+ key,
1444
+ type,
1445
+ optional: zod?.optional ?? false,
1446
+ label: resolved.label,
1447
+ ...resolved.description !== void 0 ? { description: resolved.description } : {},
1448
+ ...resolved.semanticType !== void 0 ? { semanticType: resolved.semanticType } : {},
1449
+ ...resolved.unit !== void 0 ? { unit: resolved.unit } : {},
1450
+ ...resolved.sensitivity !== void 0 ? { sensitivity: resolved.sensitivity } : {},
1451
+ ...resolved.aggregate !== void 0 ? { aggregate: resolved.aggregate } : {},
1452
+ ...resolved.aliases !== void 0 ? { aliases: resolved.aliases } : {},
1453
+ ...resolved.displayFor !== void 0 ? { displayFor: resolved.displayFor } : {},
1454
+ ...refBlock !== void 0 ? { ref: refBlock } : {},
1455
+ ...moneyBlock !== void 0 ? { money: moneyBlock } : {},
1456
+ ...dictBlock !== void 0 ? { dict: dictBlock } : {},
1457
+ ...isComputed ? { computed: true } : {},
1458
+ ...i18nBlock !== void 0 ? { i18n: i18nBlock } : {},
1459
+ widget,
1460
+ editable
1461
+ };
1462
+ fields.push(field);
1463
+ }
1464
+ const collectionMeta = {
1465
+ ...meta,
1466
+ label: meta?.label ?? humanizeFieldKey(collection)
1467
+ };
1468
+ return {
1469
+ collection,
1470
+ fields,
1471
+ meta: collectionMeta
1472
+ };
1473
+ }
1474
+
1475
+ // src/introspection/json-schema.ts
1476
+ function jsonType(t) {
1477
+ switch (t) {
1478
+ case "number":
1479
+ return "number";
1480
+ case "boolean":
1481
+ return "boolean";
1482
+ case "array":
1483
+ return "array";
1484
+ case "object":
1485
+ return "object";
1486
+ default:
1487
+ return "string";
1488
+ }
1489
+ }
1490
+ function buildJsonSchema(desc, base) {
1491
+ const baseProps = base?.["properties"] ?? {};
1492
+ const properties = {};
1493
+ for (const f of desc.fields) {
1494
+ const prop = { ...baseProps[f.key] ?? { type: jsonType(f.type) } };
1495
+ prop["x-label"] = f.label;
1496
+ if (f.unit !== void 0) prop["x-unit"] = f.unit;
1497
+ if (f.semanticType !== void 0) prop["x-semanticType"] = f.semanticType;
1498
+ if (f.sensitivity !== void 0) prop["x-sensitivity"] = f.sensitivity;
1499
+ if (f.widget !== void 0) prop["x-widget"] = f.widget;
1500
+ if (f.editable === false) prop["x-readonly"] = true;
1501
+ if (f.money !== void 0) prop["x-money"] = f.money;
1502
+ if (f.ref !== void 0) prop["x-ref"] = f.ref.target;
1503
+ if (f.dict?.values) {
1504
+ const labels = {};
1505
+ for (const v of f.dict.values) if (v.label !== void 0) labels[v.value] = v.label;
1506
+ if (Object.keys(labels).length) prop["x-enumLabels"] = labels;
1507
+ }
1508
+ properties[f.key] = prop;
1509
+ }
1510
+ return base != null && typeof base === "object" ? { ...base, properties } : { type: "object", properties };
1511
+ }
1512
+
1051
1513
  // src/cache/lru.ts
1052
1514
  var Lru = class {
1053
1515
  entries = /* @__PURE__ */ new Map();
@@ -1270,7 +1732,7 @@ async function resolveStaleOnRead(accessor, outputCollection, id) {
1270
1732
  }
1271
1733
  const sourceWithId = { ...source, id };
1272
1734
  if (DerivationExecutor === null) {
1273
- ({ DerivationExecutor } = await import("./executor-DWVP4BSJ.js"));
1735
+ ({ DerivationExecutor } = await import("./executor-KYSKFJ2R.js"));
1274
1736
  }
1275
1737
  const ctx = { vault: accessor.getReadOnlyFacade() };
1276
1738
  const result = await DerivationExecutor.run(spec, sourceWithId, 0, strategyHash, ctx);
@@ -1342,6 +1804,8 @@ var Collection = class {
1342
1804
  getDEK;
1343
1805
  onDirty;
1344
1806
  historyConfig;
1807
+ /** True when the caller explicitly provided a `historyConfig` option (vs. inheriting the vault default). */
1808
+ historyConfigExplicit;
1345
1809
  /**
1346
1810
  * tree-shake seam — the strategy that backs `collection.blob(id)`.
1347
1811
  * Defaults to `NO_BLOBS`, a ~10-line stub that throws with an actionable
@@ -1501,6 +1965,21 @@ var Collection = class {
1501
1965
  * fields when a locale is requested.
1502
1966
  */
1503
1967
  dictKeyFields;
1968
+ /**
1969
+ * Consumer-neutral per-field descriptors declared via the `fieldMeta`
1970
+ * collection option. Read by `getFieldMeta()`; merged by `collection.describe()`.
1971
+ */
1972
+ fieldMeta;
1973
+ /**
1974
+ * Collection-level descriptive metadata declared via the `meta` collection
1975
+ * option. Read by `getMeta()`; surfaced in `collection.describe()`.
1976
+ */
1977
+ meta;
1978
+ /**
1979
+ * Outbound ref declarations for this collection (snapshot from vault
1980
+ * refRegistry at construction time). Used by `describe()` (sync, config-only).
1981
+ */
1982
+ _refs;
1504
1983
  /**
1505
1984
  * Money field descriptors keyed by field path. Declared via the
1506
1985
  * `moneyFields` collection option: `put()` quantizes to a scaled-int
@@ -1682,6 +2161,7 @@ var Collection = class {
1682
2161
  this.getDEK = opts.getDEK;
1683
2162
  this.onDirty = opts.onDirty;
1684
2163
  this.historyConfig = opts.historyConfig ?? { enabled: true };
2164
+ this.historyConfigExplicit = opts.historyConfigExplicit ?? false;
1685
2165
  this.schema = opts.schema;
1686
2166
  this.ledger = opts.ledger;
1687
2167
  this.refEnforcer = opts.refEnforcer;
@@ -1701,6 +2181,9 @@ var Collection = class {
1701
2181
  this.embeddings = opts.embeddings;
1702
2182
  this.vectorSet = opts.embeddings ? new VectorSet() : void 0;
1703
2183
  this.dictKeyFields = opts.dictKeyFields;
2184
+ this.fieldMeta = opts.fieldMeta;
2185
+ this.meta = opts.meta;
2186
+ this._refs = opts.declaredRefs ?? {};
1704
2187
  if (opts.moneyFields) validateMoneyFieldPaths(opts.moneyFields);
1705
2188
  this.moneyFields = opts.moneyFields;
1706
2189
  this.computed = opts.computed;
@@ -1838,6 +2321,113 @@ var Collection = class {
1838
2321
  getSchema() {
1839
2322
  return this.schema;
1840
2323
  }
2324
+ /** The declared consumer-neutral field metadata channel (canonical). */
2325
+ getFieldMeta() {
2326
+ return this.fieldMeta;
2327
+ }
2328
+ /** The collection's declared descriptive metadata. */
2329
+ getMeta() {
2330
+ return this.meta;
2331
+ }
2332
+ /**
2333
+ * Aggregate all collection-level configuration options that are actively set
2334
+ * into a {@link CollectionConfig} snapshot. Returns `undefined` when no options
2335
+ * are configured (omitting the `config` block from `dumpSchema()` output).
2336
+ * Consumed by `walk.ts` to populate `CollectionDescriptor.config`.
2337
+ */
2338
+ getConfig() {
2339
+ const i18nFields = this.i18nFields !== void 0 ? Object.keys(this.i18nFields) : void 0;
2340
+ const embeddings = this.embeddings !== void 0 ? {
2341
+ source: this.embeddings.source,
2342
+ dim: this.embeddings.dim,
2343
+ ...this.embeddings.model !== void 0 ? { model: this.embeddings.model } : {}
2344
+ } : void 0;
2345
+ const textIndexes = this.textIndexes !== void 0 && this.textIndexes.length > 0 ? this.textIndexes : void 0;
2346
+ const textIndexPersist = this.searchIndexStore instanceof PersistedIndexStore ? true : void 0;
2347
+ const perRecordKeys = this.perRecordCek ? true : void 0;
2348
+ const provenance = this.provenance ? true : void 0;
2349
+ const tiers = this.tiers !== null ? Array.from(this.tiers) : void 0;
2350
+ const tierMode = this.tiers !== null ? this.tierMode : void 0;
2351
+ const crdt = this.crdtMode !== void 0 ? this.crdtMode : void 0;
2352
+ const history = this.historyConfigExplicit && this.historyConfig.enabled !== false ? true : void 0;
2353
+ const hasAny = i18nFields !== void 0 || embeddings !== void 0 || textIndexes !== void 0 || textIndexPersist !== void 0 || perRecordKeys !== void 0 || provenance !== void 0 || tiers !== void 0 || crdt !== void 0 || history !== void 0;
2354
+ if (!hasAny) return void 0;
2355
+ return {
2356
+ ...i18nFields !== void 0 ? { i18nFields } : {},
2357
+ ...embeddings !== void 0 ? { embeddings } : {},
2358
+ ...textIndexes !== void 0 ? { textIndexes } : {},
2359
+ ...textIndexPersist !== void 0 ? { textIndexPersist } : {},
2360
+ ...perRecordKeys !== void 0 ? { perRecordKeys } : {},
2361
+ ...provenance !== void 0 ? { provenance } : {},
2362
+ ...tiers !== void 0 ? { tiers } : {},
2363
+ ...tierMode !== void 0 ? { tierMode } : {},
2364
+ ...crdt !== void 0 ? { crdt } : {},
2365
+ ...history !== void 0 ? { history } : {}
2366
+ };
2367
+ }
2368
+ describe(opts) {
2369
+ if (opts) {
2370
+ return this.describeAsync(opts);
2371
+ }
2372
+ return buildDescription({
2373
+ collection: this.name,
2374
+ fieldMeta: this.fieldMeta,
2375
+ moneyFields: this.moneyFields,
2376
+ dictKeyFields: this.dictKeyFields,
2377
+ computed: this.computed,
2378
+ refs: this._refs,
2379
+ zodFields: void 0,
2380
+ ...this.meta !== void 0 ? { meta: this.meta } : {},
2381
+ ...this.i18nFields !== void 0 ? { i18nFields: this.i18nFields } : {}
2382
+ });
2383
+ }
2384
+ /**
2385
+ * Async describe implementation (#483 Task 4).
2386
+ * Derives validator-exact types via deriveZodFields (lazy, no static zod import),
2387
+ * optionally resolves dynamic-dict labels from vault.dictionary(name).list(),
2388
+ * then delegates to buildDescription which also runs fieldMeta key-validation.
2389
+ */
2390
+ async describeAsync(opts) {
2391
+ const zodFields = this.schema !== void 0 ? await deriveZodFields(this.schema) : void 0;
2392
+ let dictLabels;
2393
+ if (opts.resolveDictLabels === true && this.dictKeyFields !== void 0) {
2394
+ dictLabels = {};
2395
+ for (const [, desc] of Object.entries(this.dictKeyFields)) {
2396
+ if (!isStaticDictDescriptor(desc) && this.getDictionary !== void 0) {
2397
+ const handle = await this.getDictionary(desc.name);
2398
+ const entries = await handle.list();
2399
+ const valueToLabel = {};
2400
+ for (const entry of entries) {
2401
+ const label = Object.values(entry.labels)[0];
2402
+ if (label !== void 0) valueToLabel[entry.key] = label;
2403
+ }
2404
+ dictLabels[desc.name] = valueToLabel;
2405
+ }
2406
+ }
2407
+ }
2408
+ return buildDescription({
2409
+ collection: this.name,
2410
+ fieldMeta: this.fieldMeta,
2411
+ moneyFields: this.moneyFields,
2412
+ dictKeyFields: this.dictKeyFields,
2413
+ computed: this.computed,
2414
+ refs: this._refs,
2415
+ zodFields,
2416
+ ...dictLabels !== void 0 ? { dictLabels } : {},
2417
+ ...this.meta !== void 0 ? { meta: this.meta } : {},
2418
+ ...this.i18nFields !== void 0 ? { i18nFields: this.i18nFields } : {}
2419
+ });
2420
+ }
2421
+ /** JSON Schema for this collection with describe() metadata as x- extensions. */
2422
+ async toJSONSchema() {
2423
+ const desc = await this.describe({});
2424
+ let base = null;
2425
+ if (this.schema !== void 0) {
2426
+ const env = await derivePersistedSchema(this.schema);
2427
+ base = env.jsonSchema ?? null;
2428
+ }
2429
+ return buildJsonSchema(desc, base);
2430
+ }
1841
2431
  /**
1842
2432
  * @internal — attach money descriptors post-construction. MV dependency
1843
2433
  * analysis auto-creates a source collection (without options) during
@@ -1853,6 +2443,14 @@ var Collection = class {
1853
2443
  _applyComputed(computed) {
1854
2444
  if (this.computed === void 0) this.computed = computed;
1855
2445
  }
2446
+ /** @internal — attach fieldMeta post-construction. See {@link _applyMoneyFields}. First-wins. */
2447
+ _applyFieldMeta(fieldMeta) {
2448
+ if (this.fieldMeta === void 0) this.fieldMeta = fieldMeta;
2449
+ }
2450
+ /** @internal — attach collection-level meta post-construction. See {@link _applyMoneyFields}. First-wins. */
2451
+ _applyMeta(meta) {
2452
+ if (this.meta === void 0) this.meta = meta;
2453
+ }
1856
2454
  /**
1857
2455
  * Get a single record by ID.
1858
2456
  *
@@ -1874,7 +2472,7 @@ var Collection = class {
1874
2472
  }
1875
2473
  }
1876
2474
  if (this.materializedViewSource !== void 0) {
1877
- const { resolveStaleMVOnRead } = await import("./stale-IIIGOHBW.js");
2475
+ const { resolveStaleMVOnRead } = await import("./stale-J3TUF5C5.js");
1878
2476
  await resolveStaleMVOnRead(this.materializedViewSource, this.name);
1879
2477
  }
1880
2478
  let record;
@@ -2400,7 +2998,7 @@ var Collection = class {
2400
2998
  if (mode === "eager") {
2401
2999
  if (executor === null) {
2402
3000
  ;
2403
- ({ MaterializedViewExecutor: executor } = await import("./executor-HB2YMIYC.js"));
3001
+ ({ MaterializedViewExecutor: executor } = await import("./executor-VDTDGWO6.js"));
2404
3002
  }
2405
3003
  await executor.refresh(reg, {
2406
3004
  getCollection: (name) => this.materializedViewSource.getCollection(name),
@@ -2409,7 +3007,7 @@ var Collection = class {
2409
3007
  });
2410
3008
  } else if (mode === "lazy") {
2411
3009
  if (staleHelpers === null) {
2412
- staleHelpers = await import("./stale-IIIGOHBW.js");
3010
+ staleHelpers = await import("./stale-J3TUF5C5.js");
2413
3011
  }
2414
3012
  staleHelpers.markMVStale(registry, reg.spec.name);
2415
3013
  }
@@ -2583,7 +3181,7 @@ var Collection = class {
2583
3181
  continue;
2584
3182
  }
2585
3183
  if (DerivationExecutor === null) {
2586
- ({ DerivationExecutor } = await import("./executor-DWVP4BSJ.js"));
3184
+ ({ DerivationExecutor } = await import("./executor-KYSKFJ2R.js"));
2587
3185
  }
2588
3186
  for (const run of runs) {
2589
3187
  const ctx = { vault: this.derivationSource.getReadOnlyFacade() };
@@ -2602,7 +3200,7 @@ var Collection = class {
2602
3200
  const outputCollection = this.derivationSource.getCollection(outSpec.collection);
2603
3201
  const txCtx = this.derivationSource.getActiveTxContext();
2604
3202
  if (out.kind === "array") {
2605
- const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-BMT7I6FI.js");
3203
+ const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-AZALISHB.js");
2606
3204
  const prior = await loadFanoutSidecar(
2607
3205
  this.adapter,
2608
3206
  this.vault,
@@ -2966,7 +3564,7 @@ var Collection = class {
2966
3564
  for (const [outputKey, outSpec] of Object.entries(spec.outputs)) {
2967
3565
  if (outSpec.shape !== "array") continue;
2968
3566
  if (helpers === null) {
2969
- helpers = await import("./fanout-sidecar-BMT7I6FI.js");
3567
+ helpers = await import("./fanout-sidecar-AZALISHB.js");
2970
3568
  }
2971
3569
  const sidecar = await helpers.loadFanoutSidecar(
2972
3570
  this.adapter,
@@ -3006,7 +3604,7 @@ var Collection = class {
3006
3604
  if (mode === "eager") {
3007
3605
  if (executor === null) {
3008
3606
  ;
3009
- ({ MaterializedViewExecutor: executor } = await import("./executor-HB2YMIYC.js"));
3607
+ ({ MaterializedViewExecutor: executor } = await import("./executor-VDTDGWO6.js"));
3010
3608
  }
3011
3609
  await executor.refresh(reg, {
3012
3610
  getCollection: (name) => this.materializedViewSource.getCollection(name),
@@ -3015,7 +3613,7 @@ var Collection = class {
3015
3613
  });
3016
3614
  } else if (mode === "lazy") {
3017
3615
  if (staleHelpers === null) {
3018
- staleHelpers = await import("./stale-IIIGOHBW.js");
3616
+ staleHelpers = await import("./stale-J3TUF5C5.js");
3019
3617
  }
3020
3618
  staleHelpers.markMVStale(registry, reg.spec.name);
3021
3619
  }
@@ -3038,7 +3636,7 @@ var Collection = class {
3038
3636
  );
3039
3637
  }
3040
3638
  if (this.materializedViewSource !== void 0) {
3041
- const { resolveStaleMVOnRead } = await import("./stale-IIIGOHBW.js");
3639
+ const { resolveStaleMVOnRead } = await import("./stale-J3TUF5C5.js");
3042
3640
  await resolveStaleMVOnRead(this.materializedViewSource, this.name);
3043
3641
  }
3044
3642
  await this.ensureHydrated();
@@ -6527,64 +7125,6 @@ async function listOperationalCollections(vault) {
6527
7125
  return [...keyring.deks.keys()].filter((c) => !c.startsWith("_"));
6528
7126
  }
6529
7127
 
6530
- // src/persisted-schemas/canonicalize.ts
6531
- function canonicalize(value) {
6532
- if (value === null || typeof value !== "object") {
6533
- return JSON.stringify(value);
6534
- }
6535
- if (Array.isArray(value)) {
6536
- return "[" + value.map(canonicalize).join(",") + "]";
6537
- }
6538
- const obj = value;
6539
- const keys = Object.keys(obj).sort();
6540
- const parts = keys.map((k) => JSON.stringify(k) + ":" + canonicalize(obj[k]));
6541
- return "{" + parts.join(",") + "}";
6542
- }
6543
-
6544
- // src/persisted-schemas/derive.ts
6545
- function isZodSchema(value) {
6546
- if (value === null || typeof value !== "object") return false;
6547
- const def = value._def;
6548
- if (!def || typeof def !== "object") return false;
6549
- return typeof def.typeName === "string" && def.typeName.startsWith("Zod");
6550
- }
6551
- function detectKind(validator) {
6552
- if (isZodSchema(validator)) return "Zod";
6553
- return "Unknown";
6554
- }
6555
- async function loadZodConverter() {
6556
- try {
6557
- const mod = await import("zod-to-json-schema");
6558
- if (!mod.zodToJsonSchema) {
6559
- throw new Error("zod-to-json-schema export missing");
6560
- }
6561
- return mod.zodToJsonSchema;
6562
- } catch (err) {
6563
- throw new Error(
6564
- `persistJsonSchema requires the optional peer-dep \`zod-to-json-schema\`. Install it: \`pnpm add zod-to-json-schema\` (or npm/yarn equivalent). Original error: ${err instanceof Error ? err.message : String(err)}`
6565
- );
6566
- }
6567
- }
6568
- async function derivePersistedSchema(validator) {
6569
- const kind = detectKind(validator);
6570
- const derivedAt = (/* @__PURE__ */ new Date()).toISOString();
6571
- if (kind === "Zod") {
6572
- const convert = await loadZodConverter();
6573
- const jsonSchema = convert(validator);
6574
- const canonical = canonicalize(jsonSchema);
6575
- const hash = await sha256Hex(new TextEncoder().encode(canonical));
6576
- return { _noydb_schema: 1, kind, jsonSchema, hash, derivedAt };
6577
- }
6578
- return {
6579
- _noydb_schema: 1,
6580
- kind,
6581
- jsonSchema: null,
6582
- hash: null,
6583
- reason: `derivation not yet supported for kind=${kind} (v0 supports Zod only)`,
6584
- derivedAt
6585
- };
6586
- }
6587
-
6588
7128
  // src/schema-update/delta.ts
6589
7129
  function computeSchemaDelta(stored, fresh, collection) {
6590
7130
  const a = stored;
@@ -6832,97 +7372,6 @@ var FenceWatcher = class {
6832
7372
  }
6833
7373
  };
6834
7374
 
6835
- // src/introspection/fields.ts
6836
- function jsonSchemaType(node) {
6837
- if (Array.isArray(node.type)) {
6838
- const non = node.type.filter((t) => t !== "null");
6839
- return non[0] ?? "opaque";
6840
- }
6841
- if (node.enum && Array.isArray(node.enum)) return "enum";
6842
- if (node.const !== void 0) return "enum";
6843
- if (typeof node.type === "string") return node.type;
6844
- return "opaque";
6845
- }
6846
- function constraintsFor(node) {
6847
- const out = {};
6848
- if (node.enum) out.values = node.enum;
6849
- if (node.const !== void 0) out.values = [node.const];
6850
- if (node.minLength !== void 0) out.minLength = node.minLength;
6851
- if (node.maxLength !== void 0) out.maxLength = node.maxLength;
6852
- if (node.pattern !== void 0) out.pattern = node.pattern;
6853
- if (node.format !== void 0) out.format = node.format;
6854
- if (node.minimum !== void 0) out.minimum = node.minimum;
6855
- if (node.maximum !== void 0) out.maximum = node.maximum;
6856
- if (node.exclusiveMinimum !== void 0) out.gt = node.exclusiveMinimum;
6857
- if (node.exclusiveMaximum !== void 0) out.lt = node.exclusiveMaximum;
6858
- return Object.keys(out).length === 0 ? void 0 : out;
6859
- }
6860
- function extractObjectFields(obj, source, refs) {
6861
- const required = new Set(Array.isArray(obj.required) ? obj.required : []);
6862
- const fields = {};
6863
- if (!obj.properties || typeof obj.properties !== "object") return { fields, required };
6864
- for (const [name, node] of Object.entries(obj.properties)) {
6865
- const descriptor = {
6866
- type: jsonSchemaType(node),
6867
- source,
6868
- ...required.has(name) ? {} : { optional: true },
6869
- ...refs?.[name] ? { references: `${refs[name].target}.id` } : {}
6870
- };
6871
- const constraints = constraintsFor(node);
6872
- if (constraints) descriptor.constraints = constraints;
6873
- fields[name] = descriptor;
6874
- }
6875
- return { fields, required };
6876
- }
6877
- function mergeUnionMembers(members, source, refs) {
6878
- if (members.length === 0) return {};
6879
- const extracted = members.filter((m) => m.properties && typeof m.properties === "object").map((m) => extractObjectFields(m, source, refs));
6880
- if (extracted.length === 0) return {};
6881
- const allNames = /* @__PURE__ */ new Set();
6882
- for (const { fields } of extracted) {
6883
- for (const name of Object.keys(fields)) allNames.add(name);
6884
- }
6885
- const memberCount = extracted.length;
6886
- const out = {};
6887
- for (const name of allNames) {
6888
- const presentIn = extracted.filter(({ fields }) => name in fields);
6889
- const requiredInAll = presentIn.length === memberCount && presentIn.every(({ required }) => required.has(name));
6890
- const base = presentIn[0].fields[name];
6891
- const allValues = [];
6892
- for (const { fields } of presentIn) {
6893
- const fd = fields[name];
6894
- if (fd?.constraints?.values && Array.isArray(fd.constraints.values)) {
6895
- for (const v of fd.constraints.values) {
6896
- if (!allValues.includes(v)) allValues.push(v);
6897
- }
6898
- }
6899
- }
6900
- const mergedConstraints = allValues.length > 0 ? { ...base.constraints ?? {}, values: allValues } : base.constraints;
6901
- const descriptor = {
6902
- type: base.type,
6903
- source,
6904
- ...requiredInAll ? {} : { optional: true },
6905
- ...base.references ? { references: base.references } : {}
6906
- };
6907
- if (mergedConstraints) {
6908
- descriptor.constraints = mergedConstraints;
6909
- }
6910
- out[name] = descriptor;
6911
- }
6912
- return out;
6913
- }
6914
- function jsonSchemaToFields(jsonSchema, source, refs) {
6915
- if (!jsonSchema || typeof jsonSchema !== "object") return {};
6916
- const root = jsonSchema;
6917
- const unionMembers = root.anyOf ?? root.oneOf;
6918
- if (Array.isArray(unionMembers) && unionMembers.length > 0) {
6919
- return mergeUnionMembers(unionMembers, source, refs);
6920
- }
6921
- if (!root.properties || typeof root.properties !== "object") return {};
6922
- const { fields } = extractObjectFields(root, source, refs);
6923
- return fields;
6924
- }
6925
-
6926
7375
  // src/introspection/walk.ts
6927
7376
  var INTERNAL_PREFIX = "_";
6928
7377
  var KNOWN_INTERNAL_NAMES = ["_keyring", "_ledger", "_meta", "_schemas", "_deltas"];
@@ -6955,6 +7404,7 @@ async function dumpVaultSchema(vault, opts) {
6955
7404
  vault: state.name,
6956
7405
  emittedAt: (/* @__PURE__ */ new Date()).toISOString(),
6957
7406
  subsystems: state.subsystems,
7407
+ ...state.vaultMeta !== void 0 ? { meta: state.vaultMeta } : {},
6958
7408
  collections,
6959
7409
  materializedViews,
6960
7410
  overlayViews,
@@ -6990,9 +7440,9 @@ async function describeCollection(state, collectionName, sampleSize, withStats)
6990
7440
  }
6991
7441
  } catch {
6992
7442
  }
7443
+ const liveColl = state.collectionCache.get(collectionName);
6993
7444
  if (!validator) {
6994
- const coll = state.collectionCache.get(collectionName);
6995
- const schema = coll?.getSchema();
7445
+ const schema = liveColl?.getSchema();
6996
7446
  if (schema) {
6997
7447
  try {
6998
7448
  const derived = await derivePersistedSchema(schema);
@@ -7006,11 +7456,26 @@ async function describeCollection(state, collectionName, sampleSize, withStats)
7006
7456
  }
7007
7457
  if (Object.keys(fields).length === 0 && sampleSize > 0) {
7008
7458
  }
7459
+ const collMeta = liveColl?.getMeta();
7460
+ const collConfig = liveColl?.getConfig();
7461
+ const archivePresent = state.hasCollectionArchive?.(collectionName) === true;
7462
+ const schemaUpdateNames = state.getCollectionSchemaUpdateNames?.(collectionName);
7463
+ const hasSchemaUpdate = schemaUpdateNames !== void 0 && schemaUpdateNames.length > 0;
7464
+ let mergedConfig;
7465
+ if (collConfig !== void 0 || archivePresent || hasSchemaUpdate) {
7466
+ mergedConfig = {
7467
+ ...collConfig ?? {},
7468
+ ...archivePresent ? { archive: true } : {},
7469
+ ...hasSchemaUpdate ? { schemaUpdate: schemaUpdateNames } : {}
7470
+ };
7471
+ }
7009
7472
  const descriptor = {
7010
7473
  fields,
7011
7474
  indexes: [],
7012
7475
  refs,
7013
- ...validator ? { validator } : {}
7476
+ ...validator ? { validator } : {},
7477
+ ...collMeta !== void 0 ? { meta: collMeta } : {},
7478
+ ...mergedConfig !== void 0 ? { config: mergedConfig } : {}
7014
7479
  };
7015
7480
  if (withStats) {
7016
7481
  const stats = await statsForCollection(state.adapter, state.name, collectionName);
@@ -7335,6 +7800,12 @@ var Vault = class {
7335
7800
  * `get()`/`list()` calls.
7336
7801
  */
7337
7802
  locale;
7803
+ /**
7804
+ * Vault-level descriptive metadata. Set once at construction via
7805
+ * `openVault(name, { meta })`. First-wins: re-opening a cached vault
7806
+ * with different meta leaves the original untouched.
7807
+ */
7808
+ vaultMeta;
7338
7809
  /**
7339
7810
  * Current consent scope. Set by `withConsent()` and
7340
7811
  * restored in its finally block. When non-null, every collection
@@ -7446,6 +7917,7 @@ var Vault = class {
7446
7917
  this.historyConfig = opts.historyConfig ?? { enabled: true };
7447
7918
  this.reloadKeyring = opts.reloadKeyring;
7448
7919
  this.locale = opts.locale;
7920
+ this.vaultMeta = opts.meta;
7449
7921
  this.translateText = opts.plaintextTranslator;
7450
7922
  this.getDEK = this.makeGetDEK();
7451
7923
  this.user = new UserApi(
@@ -7540,6 +8012,12 @@ var Vault = class {
7540
8012
  if (coll && options?.computed) {
7541
8013
  coll._applyComputed(options.computed);
7542
8014
  }
8015
+ if (coll && options?.fieldMeta) {
8016
+ coll._applyFieldMeta(options.fieldMeta);
8017
+ }
8018
+ if (coll && options?.meta) {
8019
+ coll._applyMeta(options.meta);
8020
+ }
7543
8021
  if (!coll) {
7544
8022
  if (options?.refs) {
7545
8023
  this.refRegistry.register(collectionName, options.refs);
@@ -7621,6 +8099,7 @@ var Vault = class {
7621
8099
  getDEK: this.getDEK,
7622
8100
  onDirty: this.onDirty,
7623
8101
  historyConfig: effectiveHistoryConfig,
8102
+ historyConfigExplicit: options?.historyConfig !== void 0,
7624
8103
  // thread the vault-wide blob strategy into every
7625
8104
  // collection. `undefined` is intentionally preserved so the
7626
8105
  // Collection constructor uses its NO_BLOBS default.
@@ -7727,6 +8206,15 @@ var Vault = class {
7727
8206
  if (options?.i18nFields !== void 0 && this.translateText) {
7728
8207
  collOpts.autoTranslateHook = this.translateText;
7729
8208
  }
8209
+ if (options?.fieldMeta !== void 0) {
8210
+ collOpts.fieldMeta = options.fieldMeta;
8211
+ }
8212
+ if (options?.meta !== void 0) {
8213
+ collOpts.meta = options.meta;
8214
+ }
8215
+ if (options?.refs !== void 0) {
8216
+ collOpts.declaredRefs = this.refRegistry.getOutbound(collectionName);
8217
+ }
7730
8218
  coll = new Collection(collOpts);
7731
8219
  this.collectionCache.set(collectionName, coll);
7732
8220
  if (options?.warmIndexOnOpen === true && options.prefetch !== false) {
@@ -8154,6 +8642,10 @@ var Vault = class {
8154
8642
  getLocale() {
8155
8643
  return this.locale;
8156
8644
  }
8645
+ /** Return the vault-level descriptive metadata (set-once at construction). */
8646
+ getMeta() {
8647
+ return this.vaultMeta;
8648
+ }
8157
8649
  /**
8158
8650
  * The user id of the keyring backing this vault session. Useful for
8159
8651
  * UI affordances ("you are alice"), audit trails, and orchestration
@@ -8398,12 +8890,12 @@ var Vault = class {
8398
8890
  if (!fieldSchema) {
8399
8891
  throw new AttestationError(`issueAttestation: collection '${collectionName}' has no attestation field-schema. Declare it via vault.collection('${collectionName}', { attestation: { fields: [...] } }).`);
8400
8892
  }
8401
- const { issueAttestationCore } = await import("./issue-FZRTVGRE.js");
8893
+ const { issueAttestationCore } = await import("./issue-DPHRF2TI.js");
8402
8894
  const out = await issueAttestationCore(this.makeIssueContext(), { collection: collectionName, id, fieldSchema });
8403
8895
  return { docId: out.docId, qr: out.qr, keyId: out.keyId, publicKeyB64: out.publicKeyB64 };
8404
8896
  }
8405
8897
  async getDocumentSigningPublicKey() {
8406
- const { loadSigner, loadOrCreateSigner } = await import("./signer-JMK6W2Y6.js");
8898
+ const { loadSigner, loadOrCreateSigner } = await import("./signer-UB5TQOZ6.js");
8407
8899
  const existing = await loadSigner(this.adapter, this.name, this.getDEK);
8408
8900
  if (existing) return { keyId: existing.keyId, publicKeyB64: existing.publicKeyB64 };
8409
8901
  if (this.keyring.role !== "owner") {
@@ -8429,19 +8921,19 @@ var Vault = class {
8429
8921
  };
8430
8922
  }
8431
8923
  async revokeAttestation(docId) {
8432
- const { revokeDocCore } = await import("./revoke-AOCAVR56.js");
8924
+ const { revokeDocCore } = await import("./revoke-5PUOZPJJ.js");
8433
8925
  await revokeDocCore(this.makeRevokeContext(), docId);
8434
8926
  }
8435
8927
  async unrevokeAttestation(docId) {
8436
- const { unrevokeDocCore } = await import("./revoke-AOCAVR56.js");
8928
+ const { unrevokeDocCore } = await import("./revoke-5PUOZPJJ.js");
8437
8929
  await unrevokeDocCore(this.makeRevokeContext(), docId);
8438
8930
  }
8439
8931
  async getRevokedDocIds() {
8440
- const { getRevokedDocIdsCore } = await import("./revoke-AOCAVR56.js");
8932
+ const { getRevokedDocIdsCore } = await import("./revoke-5PUOZPJJ.js");
8441
8933
  return getRevokedDocIdsCore(this.makeRevokeContext());
8442
8934
  }
8443
8935
  async publishRevocationList() {
8444
- const { publishRevocationListCore } = await import("./revoke-AOCAVR56.js");
8936
+ const { publishRevocationListCore } = await import("./revoke-5PUOZPJJ.js");
8445
8937
  return publishRevocationListCore(this.makeRevokeContext());
8446
8938
  }
8447
8939
  makeRevokeContext() {
@@ -9084,8 +9576,8 @@ var Vault = class {
9084
9576
  async _initGuards(handles) {
9085
9577
  if (handles.length === 0) return;
9086
9578
  const [{ GuardRegistry }, { ReadOnlyVaultFacade }] = await Promise.all([
9087
- import("./registry-DKEXOJVO.js"),
9088
- import("./read-only-facade-EX6WZZBP.js")
9579
+ import("./registry-IX5WKK4F.js"),
9580
+ import("./read-only-facade-3OQRZ3VS.js")
9089
9581
  ]);
9090
9582
  const registry = new GuardRegistry();
9091
9583
  for (const h of handles) registry.register(h.spec);
@@ -9112,8 +9604,8 @@ var Vault = class {
9112
9604
  async _initDerivations(handles) {
9113
9605
  if (handles.length === 0) return;
9114
9606
  const [{ DerivationRegistry }, { ReadOnlyVaultFacade }] = await Promise.all([
9115
- import("./registry-IEU6ATO7.js"),
9116
- import("./read-only-facade-EX6WZZBP.js")
9607
+ import("./registry-TXCKWH26.js"),
9608
+ import("./read-only-facade-3OQRZ3VS.js")
9117
9609
  ]);
9118
9610
  const registry = new DerivationRegistry();
9119
9611
  for (const h of handles) {
@@ -9143,7 +9635,7 @@ var Vault = class {
9143
9635
  */
9144
9636
  async _initMaterializedViews(handles) {
9145
9637
  if (handles.length === 0) return;
9146
- const { MaterializedViewRegistry } = await import("./registry-53A55ZZE.js");
9638
+ const { MaterializedViewRegistry } = await import("./registry-LMHO5265.js");
9147
9639
  const registry = new MaterializedViewRegistry();
9148
9640
  this.materializedViewRegistry = registry;
9149
9641
  const db = this;
@@ -9167,7 +9659,7 @@ var Vault = class {
9167
9659
  */
9168
9660
  async _initOverlayedViews(handles) {
9169
9661
  if (handles.length === 0) return;
9170
- const { OverlayedViewRegistry } = await import("./registry-FKL4SLU4.js");
9662
+ const { OverlayedViewRegistry } = await import("./registry-VFEDQSYV.js");
9171
9663
  const registry = new OverlayedViewRegistry();
9172
9664
  const mvRegistry = this.materializedViewRegistry;
9173
9665
  const overlayNames = /* @__PURE__ */ new Set();
@@ -9214,13 +9706,13 @@ var Vault = class {
9214
9706
  if (!reg) {
9215
9707
  throw new Error(`refreshView: no MV registered with name "${name}"`);
9216
9708
  }
9217
- const { MaterializedViewExecutor } = await import("./executor-HB2YMIYC.js");
9709
+ const { MaterializedViewExecutor } = await import("./executor-VDTDGWO6.js");
9218
9710
  const result = await MaterializedViewExecutor.refresh(reg, {
9219
9711
  getCollection: (n) => this.collection(n),
9220
9712
  getActiveTxContext: () => this.noydb._activeTxContextOrNull,
9221
9713
  getQueryContext: () => this
9222
9714
  });
9223
- const { clearMVStale } = await import("./stale-IIIGOHBW.js");
9715
+ const { clearMVStale } = await import("./stale-J3TUF5C5.js");
9224
9716
  clearMVStale(registry, name);
9225
9717
  return result;
9226
9718
  }
@@ -9236,10 +9728,10 @@ var Vault = class {
9236
9728
  if (registry === null) return { derived: 0, failed: 0 };
9237
9729
  const strategies = registry.strategiesForSource(sourceCollection);
9238
9730
  if (strategies.length === 0) return { derived: 0, failed: 0 };
9239
- const { DerivationExecutor } = await import("./executor-DWVP4BSJ.js");
9731
+ const { DerivationExecutor } = await import("./executor-KYSKFJ2R.js");
9240
9732
  const sourceColl = this.collection(sourceCollection);
9241
9733
  const records = await sourceColl.list();
9242
- const ctx = { vault: this.derivationFacade ?? new (await import("./read-only-facade-EX6WZZBP.js")).ReadOnlyVaultFacade(this, "derivation") };
9734
+ const ctx = { vault: this.derivationFacade ?? new (await import("./read-only-facade-3OQRZ3VS.js")).ReadOnlyVaultFacade(this, "derivation") };
9243
9735
  let derived = 0;
9244
9736
  let failed = 0;
9245
9737
  for (const record of records) {
@@ -9261,7 +9753,7 @@ var Vault = class {
9261
9753
  if (!outSpec) continue;
9262
9754
  const outputColl = this.collection(outSpec.collection);
9263
9755
  if (out.kind === "array") {
9264
- const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-BMT7I6FI.js");
9756
+ const { loadFanoutSidecar, saveFanoutSidecar } = await import("./fanout-sidecar-AZALISHB.js");
9265
9757
  const prior = await loadFanoutSidecar(this.adapter, this.name, spec.source, id, key);
9266
9758
  const prevKeys = new Set(prior?.keys ?? []);
9267
9759
  const newKeysList = out.entries.map((e) => e.key);
@@ -9483,7 +9975,7 @@ var Vault = class {
9483
9975
  * collection.
9484
9976
  */
9485
9977
  async delegate(opts) {
9486
- const { issueDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-ZEH4LKEM.js");
9978
+ const { issueDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-BQTRJATI.js");
9487
9979
  if (!this.keyring.kek) {
9488
9980
  throw new ValidationError(
9489
9981
  "issueDelegation: keyring.kek is null \u2014 issuing a delegation requires a tier-1 unlock. Re-authenticate at tier 1 (passphrase) first."
@@ -9505,7 +9997,7 @@ var Vault = class {
9505
9997
  * if the id does not exist.
9506
9998
  */
9507
9999
  async revokeDelegation(id) {
9508
- const { revokeDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-ZEH4LKEM.js");
10000
+ const { revokeDelegation, DELEGATIONS_COLLECTION } = await import("./delegation-BQTRJATI.js");
9509
10001
  await revokeDelegation(this.adapter, this.name, id);
9510
10002
  void DELEGATIONS_COLLECTION;
9511
10003
  }
@@ -9895,9 +10387,18 @@ var Vault = class {
9895
10387
  materializedViews: this.materializedViewRegistry !== null,
9896
10388
  overlayViews: this.overlayedViewRegistry !== null
9897
10389
  },
10390
+ ...this.vaultMeta !== void 0 ? { vaultMeta: this.vaultMeta } : {},
9898
10391
  mvRegistry: this.materializedViewRegistry,
9899
10392
  overlayRegistry: this.overlayedViewRegistry,
9900
- derivationRegistry: this.derivationRegistry
10393
+ derivationRegistry: this.derivationRegistry,
10394
+ // Thread vault-level per-collection registries into the walker so
10395
+ // walk.ts can project archive/schemaUpdate into CollectionDescriptor.config
10396
+ // without coupling the walker to Vault internals.
10397
+ getCollectionSchemaUpdateNames: (col) => {
10398
+ const names = this.#schemaUpdateNames.get(col);
10399
+ return names !== void 0 && names.length > 0 ? names : void 0;
10400
+ },
10401
+ hasCollectionArchive: (col) => this.archiveRegistry.has(col)
9901
10402
  };
9902
10403
  }
9903
10404
  /**
@@ -9949,7 +10450,7 @@ var Vault = class {
9949
10450
  } catch {
9950
10451
  }
9951
10452
  }
9952
- const { generateULID: generateULID2 } = await import("./ulid-COREQ2RQ.js");
10453
+ const { generateULID: generateULID2 } = await import("./ulid-KEPZMD2N.js");
9953
10454
  const handle = generateULID2();
9954
10455
  const envelope = {
9955
10456
  _noydb: NOYDB_FORMAT_VERSION,
@@ -9975,7 +10476,7 @@ var Vault = class {
9975
10476
  * @see docs/subsystems/public-envelope.md
9976
10477
  */
9977
10478
  async getPublicEnvelope(opts = {}) {
9978
- const { readPublicEnvelope: readPublicEnvelope2 } = await import("./public-envelope-S2S2VR3F.js");
10479
+ const { readPublicEnvelope: readPublicEnvelope2 } = await import("./public-envelope-MFMBFJLZ.js");
9979
10480
  return readPublicEnvelope2(this.adapter, this.name, opts);
9980
10481
  }
9981
10482
  /**
@@ -11695,7 +12196,7 @@ var Noydb = class {
11695
12196
  if (!facade) return;
11696
12197
  const ctx = { existing, vault: facade, userId: e.userId, role: e.role };
11697
12198
  await registry.runChecks(e.collection, incoming, ctx);
11698
- const { GuardExecutor } = await import("./executor-HO3SIRSF.js");
12199
+ const { GuardExecutor } = await import("./executor-M7W3NEKR.js");
11699
12200
  for (const g of guards) {
11700
12201
  await GuardExecutor.checkFrozenFields(g, e.docId, existing, incoming, e.computedFieldNames);
11701
12202
  }
@@ -11807,6 +12308,7 @@ var Noydb = class {
11807
12308
  * @param opts.locale Default locale for i18n/dictKey field resolution
11808
12309
  *. Set here to avoid passing `{ locale }`
11809
12310
  * on every individual `get()`/`list()` call.
12311
+ * @param opts.meta Vault descriptive metadata (label, description, etc.). First-wins: applied on first open, ignored on subsequent opens.
11810
12312
  */
11811
12313
  async openVault(name, opts) {
11812
12314
  if (this.closed) throw new ValidationError("Instance is closed");
@@ -11891,6 +12393,7 @@ var Noydb = class {
11891
12393
  ...this.options.numbering !== void 0 ? { numberingConfigs: this.options.numbering } : {},
11892
12394
  forgetStrategy: this.forgetStrategy,
11893
12395
  locale: opts?.locale,
12396
+ ...opts?.meta !== void 0 ? { meta: opts.meta } : {},
11894
12397
  // Thread the translator hook so Collection.put() can invoke it
11895
12398
  plaintextTranslator: this.options.plaintextTranslator ? (text, from, to, field, collection) => this.invokeTranslator(text, from, to, field, collection) : void 0,
11896
12399
  // Refresh callback used by Vault.load() to re-derive
@@ -13865,6 +14368,8 @@ export {
13865
14368
  evalComputedFields,
13866
14369
  validateSchemaInput,
13867
14370
  validateSchemaOutput,
14371
+ isZodSchema,
14372
+ derivePersistedSchema,
13868
14373
  tokenize,
13869
14374
  Lru,
13870
14375
  parseBytes,
@@ -13886,8 +14391,6 @@ export {
13886
14391
  loadDeedMarker,
13887
14392
  isDeedVault,
13888
14393
  liberateVault,
13889
- isZodSchema,
13890
- derivePersistedSchema,
13891
14394
  persistSchemaIfNeeded,
13892
14395
  Vault,
13893
14396
  ELEVATION_AUDIT_COLLECTION,
@@ -13902,4 +14405,4 @@ export {
13902
14405
  Noydb,
13903
14406
  createNoydb
13904
14407
  };
13905
- //# sourceMappingURL=chunk-ZDW22N3E.js.map
14408
+ //# sourceMappingURL=chunk-BVKLJBJJ.js.map