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

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 (143) hide show
  1. package/dist/adapter/index.d.ts +9 -0
  2. package/dist/adapter/index.js +14 -0
  3. package/dist/attestation/index.d.ts +1 -1
  4. package/dist/attestation/index.js +3 -3
  5. package/dist/blobs/index.d.ts +3 -3
  6. package/dist/bundle/index.d.ts +3 -3
  7. package/dist/bundle/index.js +1 -1
  8. package/dist/{chunk-Y6YUWZTS.js → chunk-L5HHBOMS.js} +2 -2
  9. package/dist/{chunk-BVKLJBJJ.js → chunk-W5NVNJDX.js} +2 -1
  10. package/dist/{chunk-BVKLJBJJ.js.map → chunk-W5NVNJDX.js.map} +1 -1
  11. package/dist/consent/index.d.ts +2 -2
  12. package/dist/{decrypt-partition-Mhjh6nnG.d.ts → decrypt-partition-CXS5KopB.d.ts} +1 -1
  13. package/dist/derivations/index.d.ts +3 -3
  14. package/dist/{dev-unlock-DJ3IhgY9.d.ts → dev-unlock-CnHTTVea.d.ts} +1 -1
  15. package/dist/guards/index.d.ts +3 -3
  16. package/dist/{hash-DLwkYf1d.d.ts → hash-oc5paYl0.d.ts} +1 -1
  17. package/dist/history/index.d.ts +3 -3
  18. package/dist/i18n/index.d.ts +2 -2
  19. package/dist/{index-CMRIx_zx.d.ts → index-BmhGztUi.d.ts} +1 -1
  20. package/dist/index.d.ts +11 -11
  21. package/dist/index.js +2 -2
  22. package/dist/kernel/index.d.ts +2 -2
  23. package/dist/materialized-views/index.d.ts +3 -3
  24. package/dist/{mime-magic-CacDBwYp.d.ts → mime-magic-JeLKHRng.d.ts} +1 -1
  25. package/dist/{noydb-5MIBD77B.js → noydb-NAU2DTFP.js} +2 -2
  26. package/dist/noydb-NAU2DTFP.js.map +1 -0
  27. package/dist/overlay-views/index.d.ts +3 -3
  28. package/dist/periods/index.d.ts +2 -2
  29. package/dist/session/index.d.ts +3 -3
  30. package/dist/shadow/index.d.ts +2 -2
  31. package/dist/snapshots/index.d.ts +2 -2
  32. package/dist/store/index.d.ts +2 -2
  33. package/dist/sync/index.d.ts +1 -1
  34. package/dist/team/index.d.ts +2 -2
  35. package/dist/{transition-guard-J04-jime.d.ts → transition-guard-Dy3NioQr.d.ts} +1 -1
  36. package/dist/tx/index.d.ts +2 -2
  37. package/dist/{with-materialized-view-DNfzC5lH.d.ts → with-materialized-view-DIVeez0W.d.ts} +1 -1
  38. package/dist/{with-overlayed-view-qk3lbhOd.d.ts → with-overlayed-view-DVZrc5Hb.d.ts} +1 -1
  39. package/dist/{with-rollup-Dd3_ZG4b.d.ts → with-rollup-CbU-O4wP.d.ts} +1 -1
  40. package/package.json +62 -221
  41. package/dist/aggregate/index.cjs +0 -1144
  42. package/dist/aggregate/index.cjs.map +0 -1
  43. package/dist/aggregate/index.d.cts +0 -39
  44. package/dist/attestation/index.cjs +0 -305
  45. package/dist/attestation/index.cjs.map +0 -1
  46. package/dist/attestation/index.d.cts +0 -54
  47. package/dist/blobs/index.cjs +0 -1967
  48. package/dist/blobs/index.cjs.map +0 -1
  49. package/dist/blobs/index.d.cts +0 -48
  50. package/dist/bundle/index.cjs +0 -41045
  51. package/dist/bundle/index.cjs.map +0 -1
  52. package/dist/bundle/index.d.cts +0 -187
  53. package/dist/consent/index.cjs +0 -204
  54. package/dist/consent/index.cjs.map +0 -1
  55. package/dist/consent/index.d.cts +0 -27
  56. package/dist/crdt/index.cjs +0 -152
  57. package/dist/crdt/index.cjs.map +0 -1
  58. package/dist/crdt/index.d.cts +0 -30
  59. package/dist/decrypt-partition-C0iDpbSd.d.cts +0 -558
  60. package/dist/derivations/index.cjs +0 -469
  61. package/dist/derivations/index.cjs.map +0 -1
  62. package/dist/derivations/index.d.cts +0 -74
  63. package/dist/dev-unlock-0Z6yxfS7.d.cts +0 -263
  64. package/dist/discriminant-BN9REW3o.d.cts +0 -60
  65. package/dist/errors-BAWO5Z5a.d.cts +0 -1500
  66. package/dist/forget/index.cjs +0 -43
  67. package/dist/forget/index.cjs.map +0 -1
  68. package/dist/forget/index.d.cts +0 -1
  69. package/dist/guards/index.cjs +0 -455
  70. package/dist/guards/index.cjs.map +0 -1
  71. package/dist/guards/index.d.cts +0 -39
  72. package/dist/hash-Db8ncXGr.d.cts +0 -63
  73. package/dist/history/index.cjs +0 -1245
  74. package/dist/history/index.cjs.map +0 -1
  75. package/dist/history/index.d.cts +0 -65
  76. package/dist/i18n/index.cjs +0 -1280
  77. package/dist/i18n/index.cjs.map +0 -1
  78. package/dist/i18n/index.d.cts +0 -41
  79. package/dist/index-BMmajblo.d.cts +0 -362
  80. package/dist/index-C1SC1EPe.d.cts +0 -1325
  81. package/dist/index-xJEPkvMb.d.cts +0 -93
  82. package/dist/index.cjs +0 -48100
  83. package/dist/index.cjs.map +0 -1
  84. package/dist/index.d.cts +0 -1050
  85. package/dist/indexing/index.cjs +0 -803
  86. package/dist/indexing/index.cjs.map +0 -1
  87. package/dist/indexing/index.d.cts +0 -36
  88. package/dist/kernel/index.cjs +0 -751
  89. package/dist/kernel/index.cjs.map +0 -1
  90. package/dist/kernel/index.d.cts +0 -11
  91. package/dist/lazy-builder-eYZzLEL1.d.cts +0 -304
  92. package/dist/materialized-views/index.cjs +0 -1518
  93. package/dist/materialized-views/index.cjs.map +0 -1
  94. package/dist/materialized-views/index.d.cts +0 -187
  95. package/dist/mime-magic-sdMzsfVK.d.cts +0 -103
  96. package/dist/overlay-views/index.cjs +0 -399
  97. package/dist/overlay-views/index.cjs.map +0 -1
  98. package/dist/overlay-views/index.d.cts +0 -102
  99. package/dist/periods/index.cjs +0 -1041
  100. package/dist/periods/index.cjs.map +0 -1
  101. package/dist/periods/index.d.cts +0 -24
  102. package/dist/predicate-BmhBSPCH.d.cts +0 -267
  103. package/dist/query/index.cjs +0 -3480
  104. package/dist/query/index.cjs.map +0 -1
  105. package/dist/query/index.d.cts +0 -4
  106. package/dist/sealed-record/index.cjs +0 -139
  107. package/dist/sealed-record/index.cjs.map +0 -1
  108. package/dist/sealed-record/index.d.cts +0 -123
  109. package/dist/session/index.cjs +0 -495
  110. package/dist/session/index.cjs.map +0 -1
  111. package/dist/session/index.d.cts +0 -48
  112. package/dist/shadow/index.cjs +0 -133
  113. package/dist/shadow/index.cjs.map +0 -1
  114. package/dist/shadow/index.d.cts +0 -19
  115. package/dist/snapshots/index.cjs +0 -937
  116. package/dist/snapshots/index.cjs.map +0 -1
  117. package/dist/snapshots/index.d.cts +0 -30
  118. package/dist/store/index.cjs +0 -1091
  119. package/dist/store/index.cjs.map +0 -1
  120. package/dist/store/index.d.cts +0 -501
  121. package/dist/strategy-BSxFXGzb.d.cts +0 -110
  122. package/dist/strategy-mJExw4LQ.d.cts +0 -1069
  123. package/dist/sync/index.cjs +0 -1062
  124. package/dist/sync/index.cjs.map +0 -1
  125. package/dist/sync/index.d.cts +0 -45
  126. package/dist/team/index.cjs +0 -2805
  127. package/dist/team/index.cjs.map +0 -1
  128. package/dist/team/index.d.cts +0 -120
  129. package/dist/transition-guard-tWZIsaXe.d.cts +0 -165
  130. package/dist/tx/index.cjs +0 -614
  131. package/dist/tx/index.cjs.map +0 -1
  132. package/dist/tx/index.d.cts +0 -39
  133. package/dist/types-CdVfiQgt.d.cts +0 -15275
  134. package/dist/ulid-DRH25k3y.d.cts +0 -66
  135. package/dist/util/index.cjs +0 -237
  136. package/dist/util/index.cjs.map +0 -1
  137. package/dist/util/index.d.cts +0 -79
  138. package/dist/with-materialized-view-DfgPcvi9.d.cts +0 -27
  139. package/dist/with-overlayed-view-Cvfkx1lg.d.cts +0 -13
  140. package/dist/with-rollup-nIxo7h9z.d.cts +0 -47
  141. /package/dist/{noydb-5MIBD77B.js.map → adapter/index.js.map} +0 -0
  142. /package/dist/{chunk-Y6YUWZTS.js.map → chunk-L5HHBOMS.js.map} +0 -0
  143. /package/dist/{types-DHn9lEP0.d.ts → index-DHn9lEP0.d.ts} +0 -0
@@ -1,187 +0,0 @@
1
- export { w as withMaterializedView } from '../with-materialized-view-DfgPcvi9.cjs';
2
- import { aN as Collection, bk as TxContext, bl as MVQueryContext, bm as RegisteredMV, bn as MaterializedViewRegistry } from '../types-CdVfiQgt.cjs';
3
- export { bo as MaterializedFromMeta, bp as MaterializedViewOutput, aK as MaterializedViewStrategy, aL as MaterializedViewStrategyHandle, bq as UnionArmJoin, br as UnionSource } from '../types-CdVfiQgt.cjs';
4
- import { Q as Query } from '../index-C1SC1EPe.cjs';
5
- export { z as MaterializedViewConfigError, C as MaterializedViewCycleError, E as MaterializedViewSourceUnknownError, G as MaterializedViewTooLargeError } from '../errors-BAWO5Z5a.cjs';
6
- import '../lazy-builder-eYZzLEL1.cjs';
7
- import '../predicate-BmhBSPCH.cjs';
8
- import '../strategy-mJExw4LQ.cjs';
9
- import '../strategy-BSxFXGzb.cjs';
10
- import '../index-BMmajblo.cjs';
11
- import '@noy-db/attestation';
12
-
13
- /**
14
- * Accessor shape passed in from the owning Vault. Mirrors v1's
15
- * `DerivationStaleAccessor` — provides the per-collection resolver
16
- * and the active TxContext so refresh writes/tombstones register on
17
- * `_executed` for rollback symmetry.
18
- */
19
- interface MVExecutorAccessor {
20
- getCollection(name: string): Collection<any>;
21
- getActiveTxContext(): TxContext | null;
22
- /**
23
- * Vault-shaped accessor passed to the MV's `query()` callback at
24
- * each refresh. Same instance the registry used at registration
25
- * time; threading through the executor lets the refresh path
26
- * re-evaluate the closure against the live vault state.
27
- */
28
- getQueryContext(): MVQueryContext;
29
- }
30
- interface RefreshResult {
31
- /** Rows newly written / overwritten. */
32
- written: number;
33
- /** Rows tombstoned via `_internalDelete` (only when `onEmpty: 'delete'`). */
34
- deleted: number;
35
- /** Failed row writes (non-strict mode). */
36
- failed: number;
37
- }
38
- /**
39
- * Run an MV's `query()` and write the result rows to the output
40
- * collection. Same-DEK encryption: routes through the standard
41
- * `Collection.put` pipeline, so the output collection's DEK is what
42
- * gets used (matches the v2 spec's "same DEK as the left-most source"
43
- * invariant — `Collection.put` looks up the DEK by collection name,
44
- * and the output collection IS the MV's owned collection).
45
- *
46
- * Stamps `_materializedFrom` onto every emitted row.
47
- *
48
- * **Tombstoning:** when `spec.onEmpty: 'delete'` (default), rows
49
- * that existed in a prior refresh but no longer appear in the new
50
- * materialized result are deleted via `Collection._internalDelete` —
51
- * the housekeeping bypass primitive prevents user
52
- * `onDelete` guards on the output collection from firing on these
53
- * system-internal deletes. `onEmpty: 'keep'` opts out (rows from
54
- * prior refreshes linger even when the new result lacks them).
55
- *
56
- * **Cost ceiling:** if the materialized row count exceeds
57
- * `spec.maxRows` (default 100k), throws `MaterializedViewTooLargeError`
58
- * before any writes hit the store — so strict-mode rollback is
59
- * clean.
60
- *
61
- * **Strict mode:** `spec.strict === true` re-throws on any
62
- * row-write failure; the active TxContext registration means the
63
- * source-write rolls back atomically via `revertExecuted`.
64
- *
65
- * @internal
66
- */
67
- declare const MaterializedViewExecutor: {
68
- refresh(reg: RegisteredMV, accessor: MVExecutorAccessor): Promise<RefreshResult>;
69
- };
70
-
71
- /**
72
- * Walks a `Query<T>` plan and returns the set of source collection
73
- * names that any source-write should trigger a refresh on.
74
- *
75
- * Handles:
76
- * - root collection (the one the query was built from)
77
- * - FK join targets (`.join(field, { as })`)
78
- *
79
- * Also handles:
80
- * - cross-join targets (`.crossJoin(target, { as })`) — v3
81
- *
82
- * Deferred:
83
- * - `.wherePredicate(name)` — v2 predicate primitive
84
- * - Overlay-name expansion to {base, overlay}
85
- *
86
- * The set is materialized at MV registration time. The MV registry
87
- * uses it to (a) dispatch `onSourceWrite` only to MVs that actually
88
- * care, and (b) contribute edges to the shared cycle-detection graph.
89
- */
90
- declare function analyzeDependencies(query: Query<any>): Set<string>;
91
- /**
92
- * Convenience: produce a stable string summary of the query plan
93
- * suitable for `queryHash` derivation. Captures everything the
94
- * dependency analyzer reads + the where/orderBy/limit/offset
95
- * structure that affects materialized rows.
96
- *
97
- * `joinContext` is intentionally NOT included — the join-resolution
98
- * function references would defeat hash determinism. The set of join
99
- * TARGETS (collection names) IS included via the plan.joins legs.
100
- */
101
- declare function summarizeQueryPlan(query: Query<any>): string;
102
-
103
- /**
104
- * Deterministic hash of a materialized view strategy's "shape": MV
105
- * name + canonical query-plan summary + sorted dependency-set.
106
- *
107
- * Used to detect strategy drift: a row whose `_materializedFrom.queryHash`
108
- * doesn't match the current strategy is considered stale.
109
- *
110
- * Web Crypto SHA-256 — no extra deps. Mirrors the v1
111
- * `computeStrategyHash` pattern.
112
- */
113
- declare function computeQueryHash(mvName: string,
114
- /**
115
- * Source-collection set the query depends on. Sorted before
116
- * canonicalization so set iteration order doesn't affect the hash.
117
- */
118
- dependencies: ReadonlySet<string>,
119
- /**
120
- * Stringified query-plan summary. The caller produces this from the
121
- * `Query<T>` builder — concretely: a JSON serialization of clauses +
122
- * orderBy + limit + offset + joins. Function bodies inside
123
- * `wherePredicate` are NOT included here (those carry their own
124
- * `predicateHash` to be folded in by a later sub-issue).
125
- */
126
- queryPlanSummary: string): Promise<string>;
127
- /**
128
- * Canonicalize a query plan for hashing. Walks the plan structure
129
- * with sorted keys so insertion order doesn't perturb the result.
130
- * Lives here rather than in `query/builder.ts` to keep that module
131
- * stable across MV-specific evolutions.
132
- *
133
- * @internal exported for testing
134
- */
135
- declare function canonicalizeQueryPlan(plan: unknown): string;
136
-
137
- /**
138
- * Accessor shape passed in from the owning Vault. Provides the
139
- * registry (used as a stable WeakMap key + to look up MVs by output
140
- * collection) and the runtime context the lazy refresh needs.
141
- * Mirrors v1's `DerivationStaleAccessor`.
142
- */
143
- interface MVStaleAccessor {
144
- registry(): MaterializedViewRegistry;
145
- getCollection(name: string): Collection<any>;
146
- getActiveTxContext(): TxContext | null;
147
- getQueryContext(): MVQueryContext;
148
- }
149
- /**
150
- * Mark an MV as stale. Called from `Collection.dispatchMaterializedViews`
151
- * when a source-write fires for a `refresh: 'lazy'` MV.
152
- *
153
- * @internal
154
- */
155
- declare function markMVStale(registry: MaterializedViewRegistry, mvName: string): void;
156
- /**
157
- * Test-only: check whether a given MV name is currently flagged stale
158
- * against a registry. Exported so the regression suite can pin the
159
- * stale-bit lifecycle without touching the internal `WeakMap`.
160
- *
161
- * @internal
162
- */
163
- declare function isMVStale(registry: MaterializedViewRegistry, mvName: string): boolean;
164
- /**
165
- * Called from `Collection.get` (and any reader that materializes the
166
- * MV's output collection). If any MV producing `outputCollection` is
167
- * flagged stale, runs the executor against the live source state
168
- * before returning. No-op when there is no pending work — keeps the
169
- * read fast path negligible.
170
- *
171
- * Dynamic-imports the executor only when a stale flag actually fires
172
- * (the floor-bundle isolation pattern v1 derivations established in
173
- * floor-bundle isolation pattern).
174
- */
175
- declare function resolveStaleMVOnRead(accessor: MVStaleAccessor, outputCollection: string): Promise<void>;
176
- /**
177
- * Drop every stale flag for a registry. Used after a manual
178
- * `vault.refreshView(name)` runs the executor explicitly — the
179
- * post-refresh state matches the registered strategies, so
180
- * lingering stale bits would force a redundant refresh on the next
181
- * read.
182
- *
183
- * @internal
184
- */
185
- declare function clearMVStale(registry: MaterializedViewRegistry, mvName: string): void;
186
-
187
- export { type MVExecutorAccessor, type MVStaleAccessor, MaterializedViewExecutor, MaterializedViewRegistry, type RefreshResult, RegisteredMV, analyzeDependencies, canonicalizeQueryPlan, clearMVStale, computeQueryHash, isMVStale, markMVStale, resolveStaleMVOnRead, summarizeQueryPlan };
@@ -1,103 +0,0 @@
1
- import { V as ObjectProjection } from './types-CdVfiQgt.cjs';
2
-
3
- /**
4
- * Import / bootstrap (reverse projection) — walk an existing bucket/prefix in an
5
- * {@link ObjectProjection} and build a master collection where each record
6
- * anchors one object, restoring the record-anchoring invariant for objects that
7
- * pre-date noy-db (or were written by another system). See as-aws-s3 §3.8.
8
- *
9
- * Idempotent: re-running re-adopts the same objects under the same record ids.
10
- */
11
-
12
- /** Minimal collection surface this utility needs (avoids importing the kernel). */
13
- interface ImportableCollection {
14
- get(id: string): Promise<unknown>;
15
- put(id: string, record: unknown): Promise<unknown>;
16
- blob(id: string): {
17
- adoptExternal(slot: string, ref: {
18
- key: string;
19
- size?: number;
20
- contentType?: string;
21
- public?: boolean;
22
- backlink?: string;
23
- }): Promise<void>;
24
- };
25
- }
26
- interface ImportExternalOptions {
27
- /** Only consider objects under this key prefix. Default `''` (all). */
28
- prefix?: string;
29
- /**
30
- * Derive the record id for an object key. Default: the path segment before
31
- * the last — i.e. `{collection}/{recordId}/{field}` → `recordId`. Return
32
- * `null` to skip the object.
33
- */
34
- deriveRecordId?: (key: string) => string | null;
35
- /** Build the anchor record for a new id. Default `{ id }`. */
36
- makeRecord?: (id: string) => unknown;
37
- }
38
- interface ImportExternalResult {
39
- imported: number;
40
- skipped: number;
41
- recordIds: string[];
42
- }
43
- /**
44
- * Build/extend `collection` from the objects under `prefix` in `objectStore`,
45
- * adopting each as the `field` blob on its derived record.
46
- */
47
- declare function importExternalObjects(args: {
48
- collection: ImportableCollection;
49
- objectStore: ObjectProjection;
50
- field: string;
51
- options?: ImportExternalOptions;
52
- }): Promise<ImportExternalResult>;
53
-
54
- /**
55
- * Lightweight MIME type detection from magic bytes (file signatures).
56
- *
57
- * Designed for the blob store's auto-detection feature. Operates on the first 16 bytes of
58
- * plaintext — no filesystem access, no filename guessing.
59
- *
60
- * ## Detection strategies
61
- *
62
- * 1. **Prefix match** — magic bytes at offset 0 (most formats).
63
- * 2. **Offset match** — magic bytes at a fixed offset > 0 (ISOBMFF: offset 4).
64
- * 3. **Compound match** — two separate byte sequences at different offsets
65
- * (RIFF-based: bytes 0-3 + bytes 8-11).
66
- *
67
- * ## Formats excluded (require offset > 16 bytes)
68
- *
69
- * - TAR (`ustar` at offset 257)
70
- * - ISO 9660 (`CD001` at offset 32769)
71
- *
72
- * @module
73
- */
74
- /**
75
- * Detect MIME type from the first bytes of a file.
76
- *
77
- * @param header - The first 16 bytes (or more) of the plaintext. Passing
78
- * fewer than 16 bytes may miss compound and offset-based matches.
79
- * @returns Detected MIME type, or `'application/octet-stream'` if unknown.
80
- */
81
- declare function detectMimeType(header: Uint8Array): string;
82
- /**
83
- * Detect MIME type and whether the format is already compressed.
84
- *
85
- * Used by `BlobSet.put()` to decide whether to skip gzip compression.
86
- *
87
- * @param header - The first 16 bytes (or more) of the plaintext.
88
- * @returns `{ mime, preCompressed }` or `null` if no match.
89
- */
90
- declare function detectMagic(header: Uint8Array): {
91
- mime: string;
92
- format: string;
93
- preCompressed: boolean;
94
- } | null;
95
- /**
96
- * Check whether a format is already compressed (should skip gzip).
97
- *
98
- * @param mimeType - A MIME type string.
99
- * @returns `true` if the format is known to be pre-compressed.
100
- */
101
- declare function isPreCompressed(mimeType: string): boolean;
102
-
103
- export { type ImportExternalOptions as I, type ImportExternalResult as a, type ImportableCollection as b, detectMimeType as c, detectMagic as d, isPreCompressed as e, importExternalObjects as i };
@@ -1,399 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/overlay-views/index.ts
21
- var overlay_views_exports = {};
22
- __export(overlay_views_exports, {
23
- OverlayBaseIsVirtualError: () => OverlayBaseIsVirtualError,
24
- OverlayCollectionUnavailableError: () => OverlayCollectionUnavailableError,
25
- OverlayIdMismatchError: () => OverlayIdMismatchError,
26
- OverlayNameCollisionError: () => OverlayNameCollisionError,
27
- OverlayedCollection: () => OverlayedCollection,
28
- OverlayedViewRegistry: () => OverlayedViewRegistry,
29
- withOverlayedView: () => withOverlayedView
30
- });
31
- module.exports = __toCommonJS(overlay_views_exports);
32
-
33
- // src/errors.ts
34
- var NoydbError = class extends Error {
35
- /** Machine-readable error code. Stable across library versions. */
36
- code;
37
- constructor(code, message) {
38
- super(message);
39
- this.name = "NoydbError";
40
- this.code = code;
41
- }
42
- };
43
- var ValidationError = class extends NoydbError {
44
- constructor(message = "Validation error") {
45
- super("VALIDATION_ERROR", message);
46
- this.name = "ValidationError";
47
- }
48
- };
49
- var OverlayBaseIsVirtualError = class extends NoydbError {
50
- overlayName;
51
- base;
52
- constructor(overlayName, base) {
53
- super(
54
- "OVERLAY_BASE_IS_VIRTUAL",
55
- `withOverlayedView "${overlayName}": base "${base}" is another overlay's virtual name. Multi-overlay stacking is a v3 feature; base must reference a concrete collection (a real source or an MV output).`
56
- );
57
- this.name = "OverlayBaseIsVirtualError";
58
- this.overlayName = overlayName;
59
- this.base = base;
60
- }
61
- };
62
- var OverlayCollectionUnavailableError = class extends NoydbError {
63
- overlayName;
64
- overlay;
65
- constructor(overlayName, overlay) {
66
- super(
67
- "OVERLAY_COLLECTION_UNAVAILABLE",
68
- `withOverlayedView "${overlayName}": overlay collection "${overlay}" is unavailable. It must be a real vault-known collection that is NOT itself an MV output collection.`
69
- );
70
- this.name = "OverlayCollectionUnavailableError";
71
- this.overlayName = overlayName;
72
- this.overlay = overlay;
73
- }
74
- };
75
- var OverlayNameCollisionError = class extends NoydbError {
76
- overlayName;
77
- constructor(overlayName) {
78
- super(
79
- "OVERLAY_NAME_COLLISION",
80
- `withOverlayedView "${overlayName}": virtual name collides with an MV output or a concrete source collection. Pick a unique name for the virtual collection.`
81
- );
82
- this.name = "OverlayNameCollisionError";
83
- this.overlayName = overlayName;
84
- }
85
- };
86
- var OverlayIdMismatchError = class extends NoydbError {
87
- actual;
88
- expected;
89
- constructor(actual, expected) {
90
- super(
91
- "OVERLAY_ID_MISMATCH",
92
- `Overlay put(id, record): id "${actual}" does not match the base MV's rowKey(record) \u2192 "${expected}". Pass the row directly via .put(record) to derive the id, or fix the id to match the base MV's rowKey output.`
93
- );
94
- this.name = "OverlayIdMismatchError";
95
- this.actual = actual;
96
- this.expected = expected;
97
- }
98
- };
99
-
100
- // src/overlay-views/with-overlayed-view.ts
101
- function withOverlayedView(spec) {
102
- if (!spec.name || spec.name.length === 0) {
103
- throw new ValidationError("withOverlayedView: name is required");
104
- }
105
- if (!spec.base || spec.base.length === 0) {
106
- throw new ValidationError("withOverlayedView: base is required");
107
- }
108
- if (!spec.overlay || spec.overlay.length === 0) {
109
- throw new ValidationError("withOverlayedView: overlay is required");
110
- }
111
- if (spec.base === spec.overlay) {
112
- throw new ValidationError("withOverlayedView: base and overlay must be different collections");
113
- }
114
- if (spec.base === spec.name || spec.overlay === spec.name) {
115
- throw new ValidationError(
116
- "withOverlayedView: virtual name must differ from both base and overlay collection names"
117
- );
118
- }
119
- if (!spec.shadowField || spec.shadowField.length === 0) {
120
- throw new ValidationError("withOverlayedView: shadowField is required");
121
- }
122
- return {
123
- __noydb_strategy: "overlayed-view",
124
- spec
125
- };
126
- }
127
-
128
- // src/overlay-views/registry.ts
129
- var OverlayedViewRegistry = class {
130
- _byName = /* @__PURE__ */ new Map();
131
- /**
132
- * Register an overlay. Validates name uniqueness, base concreteness,
133
- * and overlay availability AGAINST the MV registry — overlays
134
- * declared without the MV registry context skip cross-registry
135
- * checks but still validate self-consistency.
136
- */
137
- register(spec, options) {
138
- const { isOverlayName, isMVOutput, isKnownCollection } = options;
139
- if (isMVOutput?.(spec.name) || isOverlayName?.(spec.name)) {
140
- throw new OverlayNameCollisionError(spec.name);
141
- }
142
- if (isOverlayName?.(spec.base)) {
143
- throw new OverlayBaseIsVirtualError(spec.name, spec.base);
144
- }
145
- if (isMVOutput?.(spec.overlay)) {
146
- throw new OverlayCollectionUnavailableError(spec.name, spec.overlay);
147
- }
148
- void isKnownCollection;
149
- this._byName.set(spec.name, spec);
150
- }
151
- byName(name) {
152
- return this._byName.get(name);
153
- }
154
- /** All overlay virtual names. */
155
- names() {
156
- return new Set(this._byName.keys());
157
- }
158
- isOverlay(name) {
159
- return this._byName.has(name);
160
- }
161
- /**
162
- * All registered overlay strategies as a flat array.
163
- * Each strategy carries `name`, `base`, and `overlay` fields that
164
- * `describeOverlays()` in the introspection walker reads directly.
165
- *
166
- * Used by `dumpSchema()` to populate the `overlayViews` map.
167
- */
168
- all() {
169
- return [...this._byName.values()];
170
- }
171
- /**
172
- * Resolve the `rowKey` function for an overlay's base MV. Returns
173
- * `undefined` if the base isn't an MV (raw source collection) or
174
- * if the MV registry isn't supplied. Used by the virtual-collection
175
- * proxy to derive ids from `put(record)` calls.
176
- */
177
- resolveBaseRowKey(name, mvRegistry) {
178
- const spec = this._byName.get(name);
179
- if (!spec || !mvRegistry) return void 0;
180
- for (const reg of mvRegistry.all()) {
181
- if (reg.outputCollection === spec.base || reg.spec.name === spec.base) {
182
- return (row) => reg.spec.rowKey(row);
183
- }
184
- }
185
- return void 0;
186
- }
187
- };
188
-
189
- // src/overlay-views/virtual-collection.ts
190
- var OverlayedCollection = class {
191
- constructor(spec, baseCollection, overlayCollection, baseRowKey) {
192
- this.spec = spec;
193
- this.baseCollection = baseCollection;
194
- this.overlayCollection = overlayCollection;
195
- this.baseRowKey = baseRowKey;
196
- }
197
- spec;
198
- baseCollection;
199
- overlayCollection;
200
- baseRowKey;
201
- /**
202
- * Convenience accessors for advanced callers that need to bypass the
203
- * virtual layer (bulk imports, direct overlay queries). Mirrors the
204
- * spec's "direct writes to the underlying overlay collection skip
205
- * the validation" escape hatch.
206
- */
207
- overlay = {
208
- rowKey: (row) => {
209
- if (!this.baseRowKey) {
210
- throw new Error(
211
- `Overlay "${this.spec.name}": base "${this.spec.base}" is not an MV \u2014 cannot auto-derive id from the row. Use \`put(id, record)\` instead.`
212
- );
213
- }
214
- return this.baseRowKey(row);
215
- }
216
- };
217
- /** Get the merged row by id. */
218
- async get(id) {
219
- const overlayRow = await this.overlayCollection.get(id);
220
- const baseRow = await this.baseCollection.get(id);
221
- return this.mergeRows(overlayRow, baseRow);
222
- }
223
- /** List union of base + overlay ids, applying the merge per row. */
224
- async list() {
225
- const baseRows = await this.baseCollection.list();
226
- const overlayRows = await this.overlayCollection.list();
227
- const idOf = (row) => {
228
- if (this.baseRowKey) return this.baseRowKey(row);
229
- const idField = row.id;
230
- return typeof idField === "string" ? idField : "";
231
- };
232
- const baseById = /* @__PURE__ */ new Map();
233
- const overlayById = /* @__PURE__ */ new Map();
234
- for (const row of baseRows) {
235
- const id = idOf(row);
236
- if (id) baseById.set(id, row);
237
- }
238
- for (const row of overlayRows) {
239
- const id = idOf(row);
240
- if (id) overlayById.set(id, row);
241
- }
242
- const out = [];
243
- for (const id of /* @__PURE__ */ new Set([...baseById.keys(), ...overlayById.keys()])) {
244
- const merged = this.mergeRows(overlayById.get(id) ?? null, baseById.get(id) ?? null);
245
- if (merged !== null) out.push(merged);
246
- }
247
- return out;
248
- }
249
- /**
250
- * Write to the overlay. Two forms:
251
- * - `put(record)`: id is derived via the base MV's `rowKey(record)`.
252
- * Throws if the base isn't an MV.
253
- * - `put(id, record)`: validates `id === rowKey(record)`; throws
254
- * `OverlayIdMismatchError` on mismatch.
255
- */
256
- async put(idOrRecord, maybeRecord) {
257
- let id;
258
- let record;
259
- if (maybeRecord === void 0) {
260
- record = idOrRecord;
261
- if (!this.baseRowKey) {
262
- throw new Error(
263
- `Overlay "${this.spec.name}".put(record): base "${this.spec.base}" is not an MV. Use put(id, record) explicitly.`
264
- );
265
- }
266
- id = this.baseRowKey(record);
267
- } else {
268
- id = idOrRecord;
269
- record = maybeRecord;
270
- if (this.baseRowKey) {
271
- const expected = this.baseRowKey(record);
272
- if (id !== expected) {
273
- throw new OverlayIdMismatchError(id, expected);
274
- }
275
- }
276
- }
277
- await this.overlayCollection.put(id, record);
278
- }
279
- /**
280
- * Remove the overlay row only. Idempotent (no-op on absent).
281
- * The base row is untouched — if a base row exists for `id`,
282
- * subsequent reads return it.
283
- */
284
- async delete(id) {
285
- await this.overlayCollection.delete(id);
286
- }
287
- /**
288
- * Merge a single id's overlay + base rows into the visible row.
289
- *
290
- * Priority (first match wins):
291
- * 1. Binary shadow win — overlay present AND
292
- * `overlay[shadowField] === shadowValue` → return the overlay row
293
- * entirely. This stays FIRST so the original binary behaviour is
294
- * unchanged whether or not `mergeMode` is configured.
295
- * 2. Field-level merge — overlay present, `mergeMode` configured,
296
- * and a rule whose `whenStatus` equals `overlay[shadowField]`.
297
- * The matched rule pulls its `overlayFields` (those present on
298
- * the overlay row) on top of the base row. With no base row, the
299
- * overlay row is returned as-is.
300
- * 3. Fallback — return the base row (possibly `null`). An
301
- * overlay-only row that qualifies under neither (1) nor (2) and
302
- * has no base is therefore NOT surfaced.
303
- */
304
- mergeRows(overlayRow, baseRow) {
305
- const shadowField = this.spec.shadowField;
306
- if (overlayRow !== null && overlayRow[shadowField] === this.spec.shadowValue) {
307
- return overlayRow;
308
- }
309
- if (overlayRow !== null && this.spec.mergeMode) {
310
- const status = overlayRow[shadowField];
311
- const rule = this.spec.mergeMode.rules.find((r) => r.whenStatus === status);
312
- if (rule) {
313
- if (baseRow === null) return overlayRow;
314
- const overlaySrc = overlayRow;
315
- const picked = {};
316
- for (const field of rule.overlayFields) {
317
- if (field in overlaySrc) picked[field] = overlaySrc[field];
318
- }
319
- return { ...baseRow, ...picked };
320
- }
321
- }
322
- return baseRow;
323
- }
324
- // ─── Throw-stubs for the unimplemented Collection<T> surface ───────
325
- //
326
- // `Vault.collection(name)` widens the return type to `Collection<T>`
327
- // for the overlay intercept, but `OverlayedCollection` doesn't
328
- // implement the full surface. These stubs catch the common
329
- // reactive / chainable APIs with a clear "not yet implemented"
330
- // error pointing at the relevant issue — so consumers don't hit a
331
- // cryptic `undefined is not a function` runtime crash.
332
- //
333
- // Throw-stubs so consumers get actionable errors rather than cryptic crashes.
334
- /** @throws — chainable Query<T> over a virtual collection is deferred. */
335
- query() {
336
- throw new Error(
337
- `OverlayedCollection "${this.spec.name}".query() is not yet implemented for overlay views (#154). Use \`list()\` + filter for now, or read from the underlying \`${this.spec.base}\` / \`${this.spec.overlay}\` collections directly. Reactive APIs land in a future MV sub-issue.`
338
- );
339
- }
340
- /** @throws — change-stream subscription over a virtual collection is deferred. */
341
- subscribe() {
342
- throw new Error(
343
- `OverlayedCollection "${this.spec.name}".subscribe() is not yet implemented for overlay views (#154). Subscribe to the underlying \`${this.spec.base}\` / \`${this.spec.overlay}\` collections individually for now. Merged change-stream lands in a future MV sub-issue.`
344
- );
345
- }
346
- /** @throws — live query over a virtual collection is deferred. */
347
- live() {
348
- throw new Error(
349
- `OverlayedCollection "${this.spec.name}".live() is not yet implemented for overlay views (#154). Reactive APIs land in a future MV sub-issue.`
350
- );
351
- }
352
- /** @throws — async iteration over a virtual collection is deferred. */
353
- scan() {
354
- throw new Error(
355
- `OverlayedCollection "${this.spec.name}".scan() is not yet implemented for overlay views (#154). Use \`list()\` for now (no row-count ceiling at niwat scale), or scan the underlying collections directly.`
356
- );
357
- }
358
- /** @throws — lazy-mode query is not applicable to virtual collections. */
359
- lazyQuery() {
360
- throw new Error(
361
- `OverlayedCollection "${this.spec.name}".lazyQuery() is not supported. Virtual collections always materialize through base + overlay reads \u2014 lazy-mode indexed lookups don't apply.`
362
- );
363
- }
364
- /** @throws — bulk-atomic put is deferred to a future MV sub-issue. */
365
- putManyAtomic() {
366
- throw new Error(
367
- `OverlayedCollection "${this.spec.name}".putManyAtomic() is not yet implemented for overlay views (#154). Use sequential \`.put(record)\` calls for now, or write to \`${this.spec.overlay}\` directly.`
368
- );
369
- }
370
- /** @throws — bulk delete is deferred to a future MV sub-issue. */
371
- deleteMany() {
372
- throw new Error(
373
- `OverlayedCollection "${this.spec.name}".deleteMany() is not yet implemented for overlay views (#154). Use sequential \`.delete(id)\` calls for now, or operate on \`${this.spec.overlay}\` directly.`
374
- );
375
- }
376
- /** @throws — `.first()` over a virtual collection is deferred. */
377
- first() {
378
- throw new Error(
379
- `OverlayedCollection "${this.spec.name}".first() is not yet implemented for overlay views (#154). Use \`(await list())[0]\` for now.`
380
- );
381
- }
382
- /** @throws — `.count()` over a virtual collection is deferred. */
383
- count() {
384
- throw new Error(
385
- `OverlayedCollection "${this.spec.name}".count() is not yet implemented for overlay views (#154). Use \`(await list()).length\` for now.`
386
- );
387
- }
388
- };
389
- // Annotate the CommonJS export names for ESM import in node:
390
- 0 && (module.exports = {
391
- OverlayBaseIsVirtualError,
392
- OverlayCollectionUnavailableError,
393
- OverlayIdMismatchError,
394
- OverlayNameCollisionError,
395
- OverlayedCollection,
396
- OverlayedViewRegistry,
397
- withOverlayedView
398
- });
399
- //# sourceMappingURL=index.cjs.map