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

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 (67) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/dist/cargo/index.js +1 -1
  3. package/dist/chunk-66TQOPFM.js +37 -0
  4. package/dist/chunk-66TQOPFM.js.map +1 -0
  5. package/dist/{chunk-H7XCIM3Z.js → chunk-AJQY44CE.js} +43 -16
  6. package/dist/chunk-AJQY44CE.js.map +1 -0
  7. package/dist/{chunk-E5OHKSBD.js → chunk-BMELYFHU.js} +2 -2
  8. package/dist/chunk-BWXGSSFX.js +1589 -0
  9. package/dist/chunk-BWXGSSFX.js.map +1 -0
  10. package/dist/{chunk-HN4FNA4X.js → chunk-COTPDJR5.js} +8 -8
  11. package/dist/{chunk-E3EBMC4G.js → chunk-E2MYJGSG.js} +2 -2
  12. package/dist/{chunk-JJR2JIN4.js → chunk-FFBYRWDJ.js} +2 -2
  13. package/dist/{chunk-WQF3QABE.js → chunk-IHFXR2VQ.js} +9 -79
  14. package/dist/chunk-IHFXR2VQ.js.map +1 -0
  15. package/dist/chunk-MGOXJIBV.js +176 -0
  16. package/dist/chunk-MGOXJIBV.js.map +1 -0
  17. package/dist/{chunk-KL7AS3HV.js → chunk-PDD75NUZ.js} +5 -2
  18. package/dist/chunk-PDD75NUZ.js.map +1 -0
  19. package/dist/chunk-RTBJ5IOO.js +87 -0
  20. package/dist/chunk-RTBJ5IOO.js.map +1 -0
  21. package/dist/{chunk-7NTBVFGD.js → chunk-SXCYYMVS.js} +2 -2
  22. package/dist/{chunk-THNJ3IKU.js → chunk-ULUMAZ5S.js} +2 -2
  23. package/dist/{chunk-NO272T7Q.js → chunk-V4PXLYWM.js} +2 -31
  24. package/dist/chunk-V4PXLYWM.js.map +1 -0
  25. package/dist/{chunk-SWVNZQVR.js → chunk-YPXNAP72.js} +2 -169
  26. package/dist/chunk-YPXNAP72.js.map +1 -0
  27. package/dist/{chunk-XMF3GKUR.js → chunk-ZVCC36XQ.js} +50 -870
  28. package/dist/chunk-ZVCC36XQ.js.map +1 -0
  29. package/dist/{collection-facade-MGGHQ3HU.js → collection-facade-4ACKIDDY.js} +4 -3
  30. package/dist/derivations/index.js +6 -2
  31. package/dist/{dispatch-XEBHUGBV.js → dispatch-MSTR5VBI.js} +10 -5
  32. package/dist/dispatch-MSTR5VBI.js.map +1 -0
  33. package/dist/{dispatch-44J4TL72.js → dispatch-PDP5TA73.js} +5 -5
  34. package/dist/{executor-KSPGNVDO.js → executor-YDDC5XGY.js} +4 -3
  35. package/dist/index.js +25 -21
  36. package/dist/index.js.map +1 -1
  37. package/dist/lazy/index.js +3 -2
  38. package/dist/materialized-views/index.js +4 -3
  39. package/dist/{noydb-JJXPICIC.js → noydb-2C6QQJ5S.js} +12 -9
  40. package/dist/pod/index.js +12 -9
  41. package/dist/{registry-BZQIVNNO.js → registry-D2YXKRYC.js} +7 -3
  42. package/dist/search/index.js +1 -1
  43. package/dist/{stale-KSPG6LFX.js → stale-2CHKZTMK.js} +2 -2
  44. package/dist/with-formula/derivations/registry.d.ts +6 -7
  45. package/dist/with-shape/introspection/describe.d.ts +29 -9
  46. package/package.json +3 -3
  47. package/dist/chunk-7BE7ZDVQ.js +0 -722
  48. package/dist/chunk-7BE7ZDVQ.js.map +0 -1
  49. package/dist/chunk-H7XCIM3Z.js.map +0 -1
  50. package/dist/chunk-KL7AS3HV.js.map +0 -1
  51. package/dist/chunk-NO272T7Q.js.map +0 -1
  52. package/dist/chunk-SWVNZQVR.js.map +0 -1
  53. package/dist/chunk-WQF3QABE.js.map +0 -1
  54. package/dist/chunk-XMF3GKUR.js.map +0 -1
  55. package/dist/dispatch-XEBHUGBV.js.map +0 -1
  56. /package/dist/{chunk-E5OHKSBD.js.map → chunk-BMELYFHU.js.map} +0 -0
  57. /package/dist/{chunk-HN4FNA4X.js.map → chunk-COTPDJR5.js.map} +0 -0
  58. /package/dist/{chunk-E3EBMC4G.js.map → chunk-E2MYJGSG.js.map} +0 -0
  59. /package/dist/{chunk-JJR2JIN4.js.map → chunk-FFBYRWDJ.js.map} +0 -0
  60. /package/dist/{chunk-7NTBVFGD.js.map → chunk-SXCYYMVS.js.map} +0 -0
  61. /package/dist/{chunk-THNJ3IKU.js.map → chunk-ULUMAZ5S.js.map} +0 -0
  62. /package/dist/{collection-facade-MGGHQ3HU.js.map → collection-facade-4ACKIDDY.js.map} +0 -0
  63. /package/dist/{dispatch-44J4TL72.js.map → dispatch-PDP5TA73.js.map} +0 -0
  64. /package/dist/{executor-KSPGNVDO.js.map → executor-YDDC5XGY.js.map} +0 -0
  65. /package/dist/{noydb-JJXPICIC.js.map → noydb-2C6QQJ5S.js.map} +0 -0
  66. /package/dist/{registry-BZQIVNNO.js.map → registry-D2YXKRYC.js.map} +0 -0
  67. /package/dist/{stale-KSPG6LFX.js.map → stale-2CHKZTMK.js.map} +0 -0
@@ -1,722 +0,0 @@
1
- import {
2
- jsonSchemaToFields
3
- } from "./chunk-VYYM3MEN.js";
4
- import {
5
- derivePersistedSchema,
6
- isZod4Schema
7
- } from "./chunk-URHRIAV6.js";
8
- import {
9
- loadPersistedSchema
10
- } from "./chunk-WWNYSV7S.js";
11
- import {
12
- isStaticDictDescriptor
13
- } from "./chunk-TRGTKX5E.js";
14
- import {
15
- DerivationCycleError,
16
- MaterializedViewCycleError
17
- } from "./chunk-7O3Y4PPD.js";
18
-
19
- // src/with-shape/introspection/field-meta.ts
20
- var FieldMetaUnknownFieldError = class extends Error {
21
- constructor(collection, key) {
22
- super(`fieldMeta for collection "${collection}" references unknown field "${key}". Declare it in the schema/config or remove the fieldMeta entry.`);
23
- this.collection = collection;
24
- this.key = key;
25
- this.name = "FieldMetaUnknownFieldError";
26
- }
27
- collection;
28
- key;
29
- };
30
- function validateFieldMetaKeys(collection, fieldMeta, knownFields) {
31
- for (const key of Object.keys(fieldMeta)) {
32
- if (!knownFields.has(key)) throw new FieldMetaUnknownFieldError(collection, key);
33
- }
34
- }
35
- function humanizeFieldKey(key) {
36
- 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(" ");
37
- }
38
- function resolveFieldMeta(key, inputs) {
39
- const { channel, zodMeta, inferred } = inputs;
40
- const pick = (k) => channel?.[k] ?? zodMeta?.[k] ?? inferred?.[k];
41
- const description = pick("description");
42
- const semanticType = pick("semanticType");
43
- const unit = pick("unit");
44
- const sensitivity = pick("sensitivity");
45
- const aggregate = pick("aggregate");
46
- const aliases = pick("aliases");
47
- const displayFor = pick("displayFor");
48
- const widget = pick("widget");
49
- const group = pick("group");
50
- const order = pick("order");
51
- return {
52
- label: pick("label") ?? humanizeFieldKey(key),
53
- ...description !== void 0 ? { description } : {},
54
- ...semanticType !== void 0 ? { semanticType } : {},
55
- ...unit !== void 0 ? { unit } : {},
56
- ...sensitivity !== void 0 ? { sensitivity } : {},
57
- ...aggregate !== void 0 ? { aggregate } : {},
58
- ...aliases !== void 0 ? { aliases } : {},
59
- ...displayFor !== void 0 ? { displayFor } : {},
60
- ...widget !== void 0 ? { widget } : {},
61
- ...group !== void 0 ? { group } : {},
62
- ...order !== void 0 ? { order } : {}
63
- };
64
- }
65
-
66
- // src/with-shape/introspection/describe.ts
67
- var ZOD_META_KEYS = /* @__PURE__ */ new Set([
68
- "label",
69
- "description",
70
- "unit",
71
- "semanticType",
72
- "sensitivity",
73
- "aggregate",
74
- "aliases",
75
- "displayFor",
76
- "group",
77
- "order"
78
- ]);
79
- function schemaFieldKeys(schema) {
80
- let s = schema;
81
- for (let depth = 0; depth < 10; depth++) {
82
- if (s === null || typeof s !== "object") return void 0;
83
- const shape = s.shape;
84
- if (shape !== null && typeof shape === "object") {
85
- const keys = Object.keys(shape);
86
- return keys.length > 0 ? keys : void 0;
87
- }
88
- const def = s._def;
89
- if (def?.schema !== void 0 && def.effect?.type === "refinement") {
90
- s = def.schema;
91
- continue;
92
- }
93
- return void 0;
94
- }
95
- return void 0;
96
- }
97
- async function deriveZodFields(schema) {
98
- const envelope = await derivePersistedSchema(schema);
99
- if (!envelope.jsonSchema) return {};
100
- const isZod4 = isZod4Schema(schema);
101
- const jsonSchema = envelope.jsonSchema;
102
- const fieldDescriptors = jsonSchemaToFields(jsonSchema, "live-validator");
103
- const propertiesRaw = jsonSchema["properties"];
104
- const result = {};
105
- for (const [key, descriptor] of Object.entries(fieldDescriptors)) {
106
- let meta;
107
- if (isZod4 && propertiesRaw) {
108
- const prop = propertiesRaw[key];
109
- if (prop) {
110
- const extracted = {};
111
- let hasAny = false;
112
- for (const mk of ZOD_META_KEYS) {
113
- if (mk in prop) {
114
- extracted[mk] = prop[mk];
115
- hasAny = true;
116
- }
117
- }
118
- if (hasAny) meta = extracted;
119
- }
120
- }
121
- result[key] = {
122
- type: descriptor.type,
123
- optional: descriptor.optional === true,
124
- ...descriptor.constraints !== void 0 ? { constraints: descriptor.constraints } : {},
125
- ...meta !== void 0 ? { meta } : {}
126
- };
127
- }
128
- return result;
129
- }
130
- async function resolveDescribeFieldIds(store, vaultName, collectionName, getDEK) {
131
- let dek;
132
- try {
133
- dek = await getDEK(collectionName);
134
- } catch {
135
- return {};
136
- }
137
- const persisted = await loadPersistedSchema(store, vaultName, collectionName, dek);
138
- return persisted?.fieldIds !== void 0 ? { fieldIds: persisted.fieldIds } : {};
139
- }
140
- function deriveWidget(opts) {
141
- if (opts.resolvedWidget !== void 0) return opts.resolvedWidget;
142
- switch (opts.semanticType) {
143
- case "date":
144
- case "datetime":
145
- return "date";
146
- case "currency":
147
- return "money";
148
- case "entity":
149
- return "ref-select";
150
- case "url":
151
- return "url";
152
- case "email":
153
- return "email";
154
- case "percent":
155
- return "number";
156
- }
157
- if (opts.dict !== void 0 || opts.lookup !== void 0) return "select";
158
- if (opts.blob !== void 0) return "file";
159
- if (opts.type === "boolean") return "checkbox";
160
- if (opts.type === "number") return "number";
161
- return "text";
162
- }
163
- function buildDescription(input) {
164
- const { collection, fieldMeta, moneyFields, dictKeyFields, lookupFields, computed, refs, zodFields, schema, dictLabels, meta, i18nFields, classified, taint, fieldIds } = input;
165
- const lookupFragments = input.viaFragments?.["lookup"]?.lookupFields;
166
- const blobFragments = input.viaFragments?.["blob"]?.blobFields;
167
- const validatorKeys = zodFields !== void 0 && Object.keys(zodFields).length > 0 ? Object.keys(zodFields) : schemaFieldKeys(schema);
168
- const canEnumerateFields = validatorKeys !== void 0;
169
- if (canEnumerateFields && fieldMeta !== void 0) {
170
- const knownFields = /* @__PURE__ */ new Set([
171
- ...Object.keys(moneyFields ?? {}),
172
- ...Object.keys(dictKeyFields ?? {}),
173
- ...Object.keys(refs),
174
- ...Object.keys(computed ?? {}),
175
- ...validatorKeys ?? [],
176
- ...Object.keys(i18nFields ?? {}),
177
- ...Object.keys(lookupFields ?? {}),
178
- ...Object.keys(blobFragments ?? {}),
179
- ...Object.keys(classified ?? {})
180
- ]);
181
- validateFieldMetaKeys(collection, fieldMeta, knownFields);
182
- }
183
- const allKeys = /* @__PURE__ */ new Set([
184
- ...Object.keys(moneyFields ?? {}),
185
- ...Object.keys(dictKeyFields ?? {}),
186
- ...Object.keys(lookupFields ?? {}),
187
- ...Object.keys(refs),
188
- ...Object.keys(computed ?? {}),
189
- ...Object.keys(fieldMeta ?? {}),
190
- ...Object.keys(zodFields ?? {}),
191
- ...Object.keys(i18nFields ?? {}),
192
- ...Object.keys(classified ?? {}),
193
- ...Object.keys(blobFragments ?? {})
194
- ]);
195
- const fields = [];
196
- for (const key of [...allKeys].sort()) {
197
- const zod = zodFields?.[key];
198
- const money = moneyFields?.[key];
199
- const dict = dictKeyFields?.[key];
200
- const lookupDesc = lookupFields?.[key];
201
- const refDesc = refs[key];
202
- const isComputed = computed !== void 0 && key in computed;
203
- const i18nDesc = i18nFields?.[key];
204
- const cls = classified?.[key];
205
- const blobFragmentEntry = blobFragments?.[key];
206
- const taintPosture = taint?.postures.get(key);
207
- let type = zod?.type ?? "unknown";
208
- const inferred = {};
209
- let moneyBlock;
210
- let dictBlock;
211
- let refBlock;
212
- let lookupBlock;
213
- let blobBlock;
214
- if (money) {
215
- type = "number";
216
- inferred.semanticType = "currency";
217
- inferred.aggregate = "sum";
218
- const currency = money.soleCurrency();
219
- const scale = currency !== void 0 ? money.scaleFor(currency) : void 0;
220
- moneyBlock = {
221
- mode: money.mode,
222
- ...currency !== void 0 ? { currency } : {},
223
- ...scale !== void 0 ? { scale } : {},
224
- ...money.rounding !== void 0 ? { rounding: money.rounding } : {}
225
- };
226
- } else if (refDesc) {
227
- type = refDesc.isArray ? "array" : "string";
228
- inferred.semanticType = "entity";
229
- refBlock = {
230
- target: refDesc.target,
231
- mode: refDesc.mode,
232
- ...refDesc.isArray ? { isArray: true } : {}
233
- };
234
- } else if (dict) {
235
- type = "enum";
236
- if (isStaticDictDescriptor(dict)) {
237
- const displayLocale = dict.displayLocale;
238
- const values = dict.keys.map((k) => {
239
- const localeMap = dict.table[k];
240
- const label = displayLocale !== void 0 ? localeMap?.[displayLocale] ?? void 0 : void 0;
241
- return label !== void 0 ? { value: k, label } : { value: k };
242
- });
243
- dictBlock = { name: dict.name, static: true, values };
244
- } else {
245
- const labelMap = dictLabels?.[dict.name];
246
- const labelMapHasEntries = labelMap !== void 0 && Object.keys(labelMap).length > 0;
247
- if (labelMapHasEntries) {
248
- const values = Object.entries(labelMap).map(([value, label]) => ({ value, label }));
249
- dictBlock = { name: dict.name, static: false, values };
250
- } else if (dict.keys !== void 0) {
251
- const values = dict.keys.map((k) => {
252
- const label = dict.labels?.[k];
253
- return label !== void 0 ? { value: k, label } : { value: k };
254
- });
255
- dictBlock = { name: dict.name, static: false, values };
256
- } else {
257
- dictBlock = { name: dict.name, static: false };
258
- }
259
- }
260
- } else if (lookupDesc) {
261
- type = "enum";
262
- const lookupLabelMap = dictLabels?.[lookupDesc.dimension];
263
- const lookupLabelMapHasEntries = lookupLabelMap !== void 0 && Object.keys(lookupLabelMap).length > 0;
264
- if (lookupDesc.table !== void 0) {
265
- const displayLocale = lookupDesc.displayLocale;
266
- const table = lookupDesc.table;
267
- const values = (lookupDesc.keys ?? Object.keys(table)).map((k) => {
268
- const localeMap = table[k];
269
- const label = displayLocale !== void 0 ? localeMap?.[displayLocale] ?? void 0 : void 0;
270
- return label !== void 0 ? { value: k, label } : { value: k };
271
- });
272
- dictBlock = { name: lookupDesc.dimension, static: true, values };
273
- } else if (lookupLabelMapHasEntries) {
274
- const values = Object.entries(lookupLabelMap).map(([value, label]) => ({ value, label }));
275
- dictBlock = { name: lookupDesc.dimension, static: false, values };
276
- } else if (lookupDesc.keys !== void 0) {
277
- const values = lookupDesc.keys.map((k) => {
278
- const label = lookupDesc.labels?.[k];
279
- return label !== void 0 ? { value: k, label } : { value: k };
280
- });
281
- dictBlock = { name: lookupDesc.dimension, static: false, values };
282
- } else {
283
- dictBlock = { name: lookupDesc.dimension, static: false };
284
- }
285
- } else if (i18nDesc) {
286
- type = "string";
287
- } else if (isComputed) {
288
- } else if (blobFragmentEntry !== void 0) {
289
- type = "blob";
290
- blobBlock = { ...blobFragmentEntry, queryable: "none" };
291
- }
292
- const lookupFragmentEntry = lookupFragments?.[key];
293
- if (lookupFragmentEntry !== void 0) {
294
- lookupBlock = {
295
- ...lookupFragmentEntry.dimension !== void 0 ? { dimension: lookupFragmentEntry.dimension } : {},
296
- backing: lookupFragmentEntry.backing,
297
- vocabulary: lookupFragmentEntry.vocabulary,
298
- key: lookupFragmentEntry.key,
299
- onDelete: lookupFragmentEntry.onDelete,
300
- ...lookupFragmentEntry.altKeys !== void 0 ? { altKeys: lookupFragmentEntry.altKeys } : {},
301
- ...lookupFragmentEntry.present !== void 0 ? { present: lookupFragmentEntry.present } : {},
302
- ...lookupFragmentEntry.sortBy !== void 0 ? { sortBy: lookupFragmentEntry.sortBy } : {},
303
- ...lookupFragmentEntry.keys !== void 0 ? { keys: lookupFragmentEntry.keys } : {}
304
- };
305
- }
306
- if (cls !== void 0) inferred.sensitivity = cls.sensitivity;
307
- const channelEntry = fieldMeta?.[key];
308
- const zodMeta = zod?.meta;
309
- const resolved = resolveFieldMeta(key, {
310
- ...channelEntry !== void 0 ? { channel: channelEntry } : {},
311
- ...zodMeta !== void 0 ? { zodMeta } : {},
312
- inferred
313
- });
314
- let i18nBlock;
315
- if (i18nDesc !== void 0) {
316
- const locales = i18nDesc.options.languages;
317
- const densify = i18nDesc.options.densifyOnWrite;
318
- i18nBlock = {
319
- ...locales !== void 0 ? { locales } : {},
320
- ...densify !== void 0 ? { densify } : {}
321
- };
322
- }
323
- const widget = deriveWidget({
324
- type,
325
- ...resolved.semanticType !== void 0 ? { semanticType: resolved.semanticType } : {},
326
- ...dictBlock !== void 0 ? { dict: dictBlock } : {},
327
- ...lookupBlock !== void 0 ? { lookup: lookupBlock } : {},
328
- ...blobBlock !== void 0 ? { blob: blobBlock } : {},
329
- ...resolved.widget !== void 0 ? { resolvedWidget: resolved.widget } : {}
330
- });
331
- const editable = !isComputed && key !== "id" && blobBlock === void 0;
332
- const field = {
333
- key,
334
- ...fieldIds?.[key] !== void 0 ? { id: fieldIds[key] } : {},
335
- type,
336
- optional: zod?.optional ?? false,
337
- ...zod?.constraints !== void 0 ? { constraints: zod.constraints } : {},
338
- label: resolved.label,
339
- ...resolved.description !== void 0 ? { description: resolved.description } : {},
340
- ...resolved.group !== void 0 ? { group: resolved.group } : {},
341
- ...resolved.order !== void 0 ? { order: resolved.order } : {},
342
- ...resolved.semanticType !== void 0 ? { semanticType: resolved.semanticType } : {},
343
- ...resolved.unit !== void 0 ? { unit: resolved.unit } : {},
344
- ...resolved.sensitivity !== void 0 ? { sensitivity: resolved.sensitivity } : {},
345
- ...resolved.aggregate !== void 0 ? { aggregate: resolved.aggregate } : {},
346
- ...resolved.aliases !== void 0 ? { aliases: resolved.aliases } : {},
347
- ...resolved.displayFor !== void 0 ? { displayFor: resolved.displayFor } : {},
348
- ...refBlock !== void 0 ? { ref: refBlock } : {},
349
- ...moneyBlock !== void 0 ? { money: moneyBlock } : {},
350
- ...dictBlock !== void 0 ? { dict: dictBlock } : {},
351
- ...lookupBlock !== void 0 ? { lookup: lookupBlock } : {},
352
- ...blobBlock !== void 0 ? { blob: blobBlock } : {},
353
- ...isComputed ? { computed: true } : {},
354
- ...i18nBlock !== void 0 ? { i18n: i18nBlock } : {},
355
- widget,
356
- editable,
357
- ...cls !== void 0 ? {
358
- classified: {
359
- preset: cls.preset,
360
- storage: cls.storage,
361
- list: cls.list.kind === "omit" ? "omit" : cls.list.kind === "mask" ? { mask: cls.list.pattern } : { rider: cls.list.rider },
362
- ...cls.equatable === true ? { equatable: true } : {}
363
- }
364
- } : {},
365
- ...taintPosture !== void 0 ? { taint: { posture: taintPosture, forcedBy: taint?.provenance?.get(key) ?? [] } } : {}
366
- };
367
- fields.push(field);
368
- }
369
- const collectionMeta = {
370
- ...meta,
371
- label: meta?.label ?? humanizeFieldKey(collection)
372
- };
373
- return {
374
- collection,
375
- fields,
376
- meta: collectionMeta
377
- };
378
- }
379
-
380
- // src/kernel/via/graph.ts
381
- var DEFAULT_POSTURE = { encryptedAtRest: "envelope", queryable: "full", exportable: true, forgettable: false };
382
- var QUERYABLE_RANK = {
383
- none: 0,
384
- "det-exact": 1,
385
- ordered: 2,
386
- full: 3
387
- };
388
- function foldPosture(a, b) {
389
- return {
390
- encryptedAtRest: a.encryptedAtRest === "sealed" || b.encryptedAtRest === "sealed" ? "sealed" : "envelope",
391
- queryable: QUERYABLE_RANK[a.queryable] <= QUERYABLE_RANK[b.queryable] ? a.queryable : b.queryable,
392
- exportable: a.exportable && b.exportable,
393
- forgettable: a.forgettable || b.forgettable
394
- };
395
- }
396
- function foldWildcardSecurity(base, contributor) {
397
- return {
398
- encryptedAtRest: base.encryptedAtRest === "sealed" || contributor.encryptedAtRest === "sealed" ? "sealed" : "envelope",
399
- queryable: base.queryable,
400
- exportable: base.exportable && contributor.exportable,
401
- forgettable: base.forgettable || contributor.forgettable
402
- };
403
- }
404
- var FOLDED_KINDS = /* @__PURE__ */ new Set(["derivation", "rollup", "mv", "overlay"]);
405
- function isDefaultPosture(p) {
406
- return p.encryptedAtRest === DEFAULT_POSTURE.encryptedAtRest && p.queryable === DEFAULT_POSTURE.queryable && p.exportable === DEFAULT_POSTURE.exportable && p.forgettable === DEFAULT_POSTURE.forgettable;
407
- }
408
- var SEP = "\0";
409
- var EMPTY_SET = /* @__PURE__ */ new Set();
410
- function nodeId(ref) {
411
- return `${ref.collection}${SEP}${ref.field}`;
412
- }
413
- function displayNodeId(id) {
414
- const sep = id.indexOf(SEP);
415
- return `${id.slice(0, sep)}.${id.slice(sep + 1)}`;
416
- }
417
- var ViaGraph = class {
418
- /** Declared source-field postures (registerField), keyed by node id. */
419
- _posture = /* @__PURE__ */ new Map();
420
- /** Every derived target's registration, keyed by the target's node id. */
421
- _in = /* @__PURE__ */ new Map();
422
- /** source node id -> derived edges that depend on it (dispatch/erasure), each carrying
423
- * its own registration's `kind` (#678 — see {@link OutEdge}). */
424
- _out = /* @__PURE__ */ new Map();
425
- /** Memoized effective posture per derived target node id. */
426
- _effectiveCache = /* @__PURE__ */ new Map();
427
- /** Memoized whole-collection security-axes fold for `'*'` wildcard LEAF nodes (#642),
428
- * keyed by collection name — see {@link _wildcardContribution}. Cleared alongside
429
- * `_effectiveCache` on every `registerField`/`registerDerived` (a later-registered
430
- * field must re-fold on the next read — registration ordering is free). */
431
- _wildcardCache = /* @__PURE__ */ new Map();
432
- /** Collections with at least one classified field (#638 Task 2 fix wave 2,
433
- * Finding I1 — the reconcile path's combined-state leak guard memory). */
434
- _classifiedCollections = /* @__PURE__ */ new Set();
435
- /** Computed field names declared with no `deps` entry, per collection
436
- * (Finding I1 — such a field registers no edge when no classified field is
437
- * present yet, so a LATER, separate reconcile call attaching classifiedFields
438
- * still needs to see it regardless of declaration order). */
439
- _depslessComputed = /* @__PURE__ */ new Map();
440
- /** Declare a source field's posture (money/i18n/classified/plain). Plain fields
441
- * default to `DEFAULT_POSTURE`; a later declaration for the same node wins-first (idempotent). */
442
- registerField(collection, field, posture) {
443
- const id = nodeId({ collection, field });
444
- if (this._posture.has(id)) return;
445
- this._posture.set(id, posture);
446
- this._effectiveCache.clear();
447
- this._wildcardCache.clear();
448
- }
449
- /** A derived target depends on `sources` (may be cross-collection). `kind`/`grain`
450
- * drive dispatch + erasure semantics; sources drive taint. Re-registering the same
451
- * target replaces `_in` but does not prune stale `_out` edges — callers must
452
- * register each target at most once per graph lifetime. `onDelete`/`keyField` (#650 Task 5)
453
- * are meaningful only for `kind === 'ref'` edges — {@link referencingEdgesOf} reads them back. */
454
- registerDerived(target, sources, kind, grain, onDelete, keyField) {
455
- const id = nodeId(target);
456
- this._in.set(id, {
457
- target,
458
- sources,
459
- kind,
460
- grain,
461
- ...onDelete !== void 0 ? { onDelete } : {},
462
- ...keyField !== void 0 ? { keyField } : {}
463
- });
464
- for (const source of sources) {
465
- const sourceId = nodeId(source);
466
- const outEdge = { target, kind };
467
- const dependents = this._out.get(sourceId);
468
- if (dependents) dependents.push(outEdge);
469
- else this._out.set(sourceId, [outEdge]);
470
- }
471
- this._effectiveCache.clear();
472
- this._wildcardCache.clear();
473
- }
474
- /** Whether `target` already has a registered in-edge — lets a caller skip
475
- * re-registering the same target (#638 Task 2 fix wave 2, Finding I2i:
476
- * `registerDerived`'s at-most-once contract must hold across repeated
477
- * identical `vault.collection()` calls, not just within a single one). */
478
- hasDerived(target) {
479
- return this._in.has(nodeId(target));
480
- }
481
- /** Mark/query a collection as having declared at least one classified field. */
482
- markClassified(collection) {
483
- this._classifiedCollections.add(collection);
484
- }
485
- isClassified(collection) {
486
- return this._classifiedCollections.has(collection);
487
- }
488
- /** Mark/query a collection's depsless (no declared `deps`) computed
489
- * field names — see `_depslessComputed`'s doc comment above. */
490
- markDepslessComputed(collection, field) {
491
- let set = this._depslessComputed.get(collection);
492
- if (!set) {
493
- set = /* @__PURE__ */ new Set();
494
- this._depslessComputed.set(collection, set);
495
- }
496
- set.add(field);
497
- }
498
- depslessComputedFields(collection) {
499
- return this._depslessComputed.get(collection) ?? EMPTY_SET;
500
- }
501
- /** Every field name the graph already has memory of for `collection` — from an
502
- * EARLIER, separate `vault.collection()` call (registered postures, derived
503
- * targets, depsless-computed names) — regardless of which via feature declared
504
- * it. #645 — `via/graph-wiring.ts`'s reconcile-path `knownFields` universe
505
- * (`collectKnownFieldNames`) is scoped to THIS call's own options only, so a
506
- * computed field attached in a LATER call whose `deps` correctly names a field
507
- * declared in an EARLIER call was spuriously refused as "unknown"; this method
508
- * lets that call site union in the graph's cross-call memory. Excludes the `'*'`
509
- * wildcard target (an overlay/derivation whole-record fold node, never a real
510
- * record field — see {@link registerDerived}'s doc comment). */
511
- knownFieldNames(collection) {
512
- const out = /* @__PURE__ */ new Set();
513
- const prefix = `${collection}${SEP}`;
514
- for (const id of this._posture.keys()) {
515
- if (id.startsWith(prefix)) out.add(id.slice(prefix.length));
516
- }
517
- for (const edge of this._in.values()) {
518
- if (edge.target.collection === collection && edge.target.field !== "*") out.add(edge.target.field);
519
- }
520
- const depsless = this._depslessComputed.get(collection);
521
- if (depsless) for (const field of depsless) out.add(field);
522
- return out;
523
- }
524
- /** Reject cycles at declare time (vault open). Throws `DerivationCycleError` for a
525
- * derivation/rollup/computed cycle, `MaterializedViewCycleError` for an MV cycle —
526
- * same classes + message shape the registries throw today (behavior lock). */
527
- assertAcyclic() {
528
- const visited = /* @__PURE__ */ new Set();
529
- const stack = [];
530
- const notRefEdge = (entry) => entry.kind !== "ref";
531
- const neighboursOf = (id) => {
532
- const own = (this._out.get(id) ?? []).filter(notRefEdge).map((entry) => entry.target);
533
- const sep = id.indexOf(SEP);
534
- if (id.slice(sep + 1) === "*") return own;
535
- const wildcard = (this._out.get(`${id.slice(0, sep)}${SEP}*`) ?? []).filter(notRefEdge).map((entry) => entry.target);
536
- if (wildcard.length === 0) return own;
537
- return [...own, ...wildcard];
538
- };
539
- const visit = (id) => {
540
- const idx = stack.indexOf(id);
541
- if (idx !== -1) {
542
- const cycle = stack.slice(idx).concat(id);
543
- const isMv = cycle.some((cycleId) => this._in.get(cycleId)?.kind === "mv");
544
- const path = cycle.map(displayNodeId);
545
- if (isMv) throw new MaterializedViewCycleError(path);
546
- throw new DerivationCycleError(path);
547
- }
548
- if (visited.has(id)) return;
549
- stack.push(id);
550
- for (const dependent of neighboursOf(id)) visit(nodeId(dependent));
551
- stack.pop();
552
- visited.add(id);
553
- };
554
- for (const id of this._out.keys()) visit(id);
555
- }
556
- /** A leaf (non-derived) node's own posture contribution: its declared posture,
557
- * or `DEFAULT_POSTURE` if never declared via `registerField`. */
558
- _declaredPosture(id) {
559
- return this._posture.get(id) ?? DEFAULT_POSTURE;
560
- }
561
- /** A node's posture contribution when folded into a dependent: recurse if it is itself
562
- * derived; else its declared/default posture — UNLESS it is a `'*'` LEAF node consumed
563
- * by a folded formula kind (#642, `derivation|rollup|mv|overlay`), in which case it
564
- * contributes its collection's whole-record security fold ({@link _wildcardContribution}).
565
- * `kind` is the CONSUMING edge's kind, threaded from {@link _computeEffective}. `'ref'`
566
- * edges (and the provenance-only untyped call, `kind` left `undefined`) keep `'*'` =
567
- * identity — the phase-D lookup reliance (`via/lookup/registry.ts:392-397`) that a
568
- * referencing field must not seal just because its dimension collection has a classified
569
- * column. */
570
- _contribution(id, kind) {
571
- const edge = this._in.get(id);
572
- if (edge) return this._computeEffective(id, edge);
573
- if (kind !== void 0 && FOLDED_KINDS.has(kind) && id.endsWith(`${SEP}*`)) {
574
- return this._wildcardContribution(id.slice(0, -2));
575
- }
576
- return this._declaredPosture(id);
577
- }
578
- /** Lazy fold (#642) of a collection's REGISTERED field postures on the security axes only
579
- * ({@link foldWildcardSecurity} — sealed-wins encryptedAtRest, AND exportable, OR
580
- * forgettable; queryable stays at DEFAULT_POSTURE's 'full', never folded), seeded at
581
- * DEFAULT_POSTURE. This is the collection-level posture a `'*'` LEAF node contributes to a
582
- * folded-kind formula edge (derivation/rollup/mv/overlay) — see {@link _contribution}. A
583
- * plain (unregistered) field contributes nothing (the identity), so the fold is strictly
584
- * more conservative than deps-based taint and never hits the KNOWN-LIMIT wall (it names no
585
- * fields — seam map §1d). Memoized per collection in `_wildcardCache`. */
586
- _wildcardContribution(collection) {
587
- const cached = this._wildcardCache.get(collection);
588
- if (cached) return cached;
589
- let result = DEFAULT_POSTURE;
590
- const prefix = `${collection}${SEP}`;
591
- for (const [id, posture] of this._posture) {
592
- if (!id.startsWith(prefix) || id === `${prefix}*`) continue;
593
- result = foldWildcardSecurity(result, posture);
594
- }
595
- this._wildcardCache.set(collection, result);
596
- return result;
597
- }
598
- _computeEffective(id, edge) {
599
- const cached = this._effectiveCache.get(id);
600
- if (cached) return cached;
601
- let result = DEFAULT_POSTURE;
602
- for (const source of edge.sources) {
603
- result = foldPosture(result, this._contribution(nodeId(source), edge.kind));
604
- }
605
- if (edge.grain === "virtual" && result.queryable !== "none") {
606
- result = { ...result, queryable: "none" };
607
- }
608
- this._effectiveCache.set(id, result);
609
- return result;
610
- }
611
- /** Strictest source posture on every axis, per §2. `undefined` when `target` has no
612
- * in-edges (not a derived field). Transitive: folds through chained derivations. */
613
- effectivePosture(target) {
614
- const id = nodeId(target);
615
- const edge = this._in.get(id);
616
- if (!edge) return void 0;
617
- return this._computeEffective(id, edge);
618
- }
619
- /** Per-collection { field → effectivePosture } overlay the pipeline consumes (Task 3). */
620
- taintedPostures(collection) {
621
- const out = /* @__PURE__ */ new Map();
622
- for (const edge of this._in.values()) {
623
- if (edge.target.collection !== collection) continue;
624
- out.set(edge.target.field, this._computeEffective(nodeId(edge.target), edge));
625
- }
626
- return out;
627
- }
628
- /** Materialized (`grain !== 'virtual'`) derived fields on `collection` whose effective
629
- * encryptedAtRest resolves to 'sealed' — the taint-seal set (Task 3). #638 Task 7
630
- * makes the `grain !== 'virtual'` filter meaningful: a `computed(fn, { mode: 'virtual' })`
631
- * field is never stored (rides the `present` phase, seam map Part 4's money-Formatted/
632
- * i18n-Label precedent), so it is EXCLUDED here even when its effective `encryptedAtRest`
633
- * folds to `'sealed'` — there is no envelope slot to seal. It still surfaces in
634
- * {@link taintedPostures} (query refusal via `postureFor`'s `queryable` clamp above, and
635
- * export refusal via `exportable`) — only the AT-REST SEALING ACTION is skipped. */
636
- taintSealedFields(collection) {
637
- const out = /* @__PURE__ */ new Set();
638
- for (const edge of this._in.values()) {
639
- if (edge.target.collection !== collection || edge.grain === "virtual") continue;
640
- const posture = this._computeEffective(nodeId(edge.target), edge);
641
- if (posture.encryptedAtRest === "sealed") out.add(edge.target.field);
642
- }
643
- return out;
644
- }
645
- /** Fields on `collection` whose registered edge is `grain === 'virtual'` (#638 Task 7) —
646
- * `via/graph-wiring.ts#applyTaintOverlay` intersects this with `exportable === false`
647
- * postures to know which virtual fields need PRESENT-TIME (not just export-time)
648
- * redaction, since a virtual field's value is only ever materialized inside `present()`. */
649
- virtualFields(collection) {
650
- const out = /* @__PURE__ */ new Set();
651
- for (const edge of this._in.values()) {
652
- if (edge.target.collection === collection && edge.grain === "virtual") out.add(edge.target.field);
653
- }
654
- return out;
655
- }
656
- /** Per-collection { field → immediate source field names that forced its
657
- * effective posture away from `DEFAULT_POSTURE` } — `describe()`'s
658
- * provenance (Task 3). Only the DIRECT declared sources are named (not the
659
- * ultimate origin several hops up a transitive chain); a source absent
660
- * from the result contributed nothing restrictive. */
661
- taintProvenance(collection) {
662
- const out = /* @__PURE__ */ new Map();
663
- for (const edge of this._in.values()) {
664
- if (edge.target.collection !== collection) continue;
665
- const forcedBy = edge.sources.filter((source) => !isDefaultPosture(this._contribution(nodeId(source)))).map((source) => source.field);
666
- if (forcedBy.length > 0) out.set(edge.target.field, forcedBy);
667
- }
668
- return out;
669
- }
670
- _targetsDependingOn(collection) {
671
- const out = [];
672
- for (const edge of this._in.values()) {
673
- if (edge.sources.some((source) => source.collection === collection)) {
674
- out.push({ target: edge.target, kind: edge.kind, grain: edge.grain });
675
- }
676
- }
677
- return out;
678
- }
679
- /** Dispatch (Task 4): every derived target triggered by a write to `collection`. Excludes
680
- * `'ref'` edges (#650 Task 5 review, folded Minor) — a `'ref'` edge is consulted only by the
681
- * delete/forget-time restrict/cascade/nullify path ({@link referencingEdgesOf}), never by the
682
- * sync/cutover/restore dispatch wave (`runGraphDispatchWave`); counting it here defeated that
683
- * wave's zero-cost early-continue, costing every write to a referenced backing collection an
684
- * unconditional decrypt + two no-op dispatch passes. {@link derivedArtifactsOf} (erasure
685
- * fanout) still includes `'ref'` edges — the forget path genuinely needs them. */
686
- dependentsOf(collection) {
687
- return this._targetsDependingOn(collection).filter((edge) => edge.kind !== "ref");
688
- }
689
- /** Erasure (Task 6): derived artifacts of a forgotten record whose source is `collection`. */
690
- derivedArtifactsOf(collection) {
691
- return this._targetsDependingOn(collection);
692
- }
693
- /** Referencing edges pointing AT a backing dimension (delete/forget-time restrict/cascade/
694
- * nullify, #650 Task 5) — an O(1) reverse lookup via the existing `_out` map (keyed at the
695
- * dimension's wildcard `field:'*'` node, the same convention every whole-collection source
696
- * already uses), NEVER a scan across collections or records. `backing` is the collection name
697
- * a lookup field's edge was registered against (a reserved dimension's `_dict_<name>`/
698
- * `_lookup_<name>` collection name, or a matrix dimension's own collection name). */
699
- referencingEdgesOf(backing) {
700
- const targets = this._out.get(nodeId({ collection: backing, field: "*" }));
701
- if (!targets) return [];
702
- const out = [];
703
- for (const entry of targets) {
704
- if (entry.kind !== "ref") continue;
705
- const edge = this._in.get(nodeId(entry.target));
706
- if (edge?.onDelete !== void 0) {
707
- out.push({ referencing: entry.target, onDelete: edge.onDelete, keyField: edge.keyField ?? "id" });
708
- }
709
- }
710
- return out;
711
- }
712
- };
713
-
714
- export {
715
- schemaFieldKeys,
716
- deriveZodFields,
717
- resolveDescribeFieldIds,
718
- buildDescription,
719
- DEFAULT_POSTURE,
720
- ViaGraph
721
- };
722
- //# sourceMappingURL=chunk-7BE7ZDVQ.js.map