@noy-db/hub 0.4.0-pre.2 → 0.4.0-pre.4
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.
- package/dist/aggregate/index.js +1 -1
- package/dist/blobs/index.js.map +1 -1
- package/dist/broker/index.js +3 -3
- package/dist/broker/index.js.map +1 -1
- package/dist/cargo/index.js +5 -5
- package/dist/{chunk-OGY4ELVE.js → chunk-3XVOLB75.js} +2 -2
- package/dist/{chunk-OTU5ZI3U.js → chunk-4X6DJZHY.js} +3 -3
- package/dist/{chunk-IU22SQGU.js → chunk-5KI3REO3.js} +2 -2
- package/dist/{chunk-IU22SQGU.js.map → chunk-5KI3REO3.js.map} +1 -1
- package/dist/{chunk-PWZKD4HW.js → chunk-BLB7P7LS.js} +3 -3
- package/dist/{chunk-Y5E6CH6S.js → chunk-EW4HFWGJ.js} +2 -2
- package/dist/{chunk-S3OYXPSE.js → chunk-HKR25MGX.js} +2 -2
- package/dist/{chunk-RI3OKC3Y.js → chunk-JIMEB4C6.js} +1 -1
- package/dist/chunk-JIMEB4C6.js.map +1 -0
- package/dist/{chunk-J6U4BOKP.js → chunk-JW3XCZA2.js} +9 -9
- package/dist/{chunk-4JYYIFHW.js → chunk-QUIG6BZT.js} +16 -16
- package/dist/{chunk-4JYYIFHW.js.map → chunk-QUIG6BZT.js.map} +1 -1
- package/dist/{chunk-TYBXP6WE.js → chunk-QYJIOWKN.js} +2 -2
- package/dist/{chunk-A64XXIIB.js → chunk-U73LHVPF.js} +17 -17
- package/dist/{chunk-A64XXIIB.js.map → chunk-U73LHVPF.js.map} +1 -1
- package/dist/{chunk-VZELV7ZJ.js → chunk-W7TCXZWU.js} +455 -554
- package/dist/chunk-W7TCXZWU.js.map +1 -0
- package/dist/{chunk-RGL53NXZ.js → chunk-WEC3JGBA.js} +2 -2
- package/dist/{chunk-HVZT5T22.js → chunk-WJDYZP3U.js} +1 -1
- package/dist/chunk-WJDYZP3U.js.map +1 -0
- package/dist/{collection-facade-ENLTJZBT.js → collection-facade-CMZGQ6IS.js} +2 -2
- package/dist/{executor-UF7LTX6O.js → executor-YORMIBWV.js} +3 -3
- package/dist/index.d.ts +5 -0
- package/dist/index.js +14 -14
- package/dist/kernel/collection-config.d.ts +11 -69
- package/dist/kernel/collection.d.ts +10 -21
- package/dist/kernel/enclave/index.d.ts +1 -1
- package/dist/kernel/noydb.d.ts +24 -13
- package/dist/kernel/vault.d.ts +21 -68
- package/dist/{liberate-W5MDWYOV.js → liberate-FK7JI2QX.js} +3 -3
- package/dist/materialized-views/index.js +3 -3
- package/dist/{noydb-U63S3Z7F.js → noydb-N5IW6OFZ.js} +10 -10
- package/dist/port/with/archive-strategy.d.ts +31 -0
- package/dist/port/with/strategies.d.ts +134 -0
- package/dist/query/index.js +2 -2
- package/dist/{seed-6GTDHL4E.js → seed-EKF4DIBB.js} +2 -2
- package/dist/{stale-NB5BGRVU.js → stale-4UNPHWOU.js} +2 -2
- package/dist/team/index.js +3 -3
- package/dist/tiers/index.js +1 -1
- package/dist/via/blob/active.d.ts +2 -1
- package/dist/with/index.js +2 -2
- package/dist/with-audit/forget/index.d.ts +2 -1
- package/dist/with-audit/tiers/index.d.ts +1 -0
- package/dist/with-cargo/index.d.ts +2 -0
- package/dist/with-formula/derivations/index.d.ts +2 -0
- package/dist/with-formula/materialized-views/index.d.ts +1 -0
- package/dist/with-lookup/aggregate/reducers.d.ts +1 -2
- package/dist/with-party/broker/index.d.ts +1 -0
- package/dist/with-party/team/keyring.d.ts +2 -2
- package/package.json +5 -4
- package/dist/chunk-HVZT5T22.js.map +0 -1
- package/dist/chunk-RI3OKC3Y.js.map +0 -1
- package/dist/chunk-VZELV7ZJ.js.map +0 -1
- /package/dist/{chunk-OGY4ELVE.js.map → chunk-3XVOLB75.js.map} +0 -0
- /package/dist/{chunk-OTU5ZI3U.js.map → chunk-4X6DJZHY.js.map} +0 -0
- /package/dist/{chunk-PWZKD4HW.js.map → chunk-BLB7P7LS.js.map} +0 -0
- /package/dist/{chunk-Y5E6CH6S.js.map → chunk-EW4HFWGJ.js.map} +0 -0
- /package/dist/{chunk-S3OYXPSE.js.map → chunk-HKR25MGX.js.map} +0 -0
- /package/dist/{chunk-J6U4BOKP.js.map → chunk-JW3XCZA2.js.map} +0 -0
- /package/dist/{chunk-TYBXP6WE.js.map → chunk-QYJIOWKN.js.map} +0 -0
- /package/dist/{chunk-RGL53NXZ.js.map → chunk-WEC3JGBA.js.map} +0 -0
- /package/dist/{collection-facade-ENLTJZBT.js.map → collection-facade-CMZGQ6IS.js.map} +0 -0
- /package/dist/{executor-UF7LTX6O.js.map → executor-YORMIBWV.js.map} +0 -0
- /package/dist/{liberate-W5MDWYOV.js.map → liberate-FK7JI2QX.js.map} +0 -0
- /package/dist/{noydb-U63S3Z7F.js.map → noydb-N5IW6OFZ.js.map} +0 -0
- /package/dist/{seed-6GTDHL4E.js.map → seed-EKF4DIBB.js.map} +0 -0
- /package/dist/{stale-NB5BGRVU.js.map → stale-4UNPHWOU.js.map} +0 -0
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
buildPersistedIndexCallbacks,
|
|
32
32
|
encodeVecId,
|
|
33
33
|
syncTierSearch
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-JW3XCZA2.js";
|
|
35
35
|
import {
|
|
36
36
|
derivePersistedSchema,
|
|
37
37
|
isZod4Schema
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
CustodyApi,
|
|
45
45
|
NO_CARGO,
|
|
46
46
|
NO_CUSTODY
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-U73LHVPF.js";
|
|
48
48
|
import {
|
|
49
49
|
resolveManagedSecret,
|
|
50
50
|
saveSealedPassphrase
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
assertCanImport,
|
|
57
57
|
canExport,
|
|
58
58
|
canImport
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-WEC3JGBA.js";
|
|
60
60
|
import {
|
|
61
61
|
runDrainBarrier
|
|
62
62
|
} from "./chunk-KMONEHDJ.js";
|
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
NO_TIERS,
|
|
73
73
|
classifySealedShred,
|
|
74
74
|
syncDerivedOutputs
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-5KI3REO3.js";
|
|
76
76
|
import {
|
|
77
77
|
NO_PORTABILITY
|
|
78
78
|
} from "./chunk-GYB2QK5H.js";
|
|
@@ -115,7 +115,7 @@ import {
|
|
|
115
115
|
NO_AGGREGATE,
|
|
116
116
|
Query,
|
|
117
117
|
ScanBuilder
|
|
118
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-4X6DJZHY.js";
|
|
119
119
|
import {
|
|
120
120
|
EXPORT_AUDIT_COLLECTION,
|
|
121
121
|
createExportBlobsHandle,
|
|
@@ -133,7 +133,7 @@ import {
|
|
|
133
133
|
} from "./chunk-NO272T7Q.js";
|
|
134
134
|
import {
|
|
135
135
|
canonicalGroupKey
|
|
136
|
-
} from "./chunk-
|
|
136
|
+
} from "./chunk-JIMEB4C6.js";
|
|
137
137
|
import {
|
|
138
138
|
readPath
|
|
139
139
|
} from "./chunk-IGJCYUT5.js";
|
|
@@ -163,7 +163,7 @@ import {
|
|
|
163
163
|
rotatePassphrase,
|
|
164
164
|
updateAuthenticator,
|
|
165
165
|
writeMagicLinkGrant
|
|
166
|
-
} from "./chunk-
|
|
166
|
+
} from "./chunk-QUIG6BZT.js";
|
|
167
167
|
import {
|
|
168
168
|
assertKeyringOpenAllowed,
|
|
169
169
|
buildRecipientKeyringFile,
|
|
@@ -176,7 +176,7 @@ import {
|
|
|
176
176
|
listUsers,
|
|
177
177
|
loadKeyring,
|
|
178
178
|
updateKeyringIdentity
|
|
179
|
-
} from "./chunk-
|
|
179
|
+
} from "./chunk-WJDYZP3U.js";
|
|
180
180
|
import {
|
|
181
181
|
persistDirectoryConfig,
|
|
182
182
|
readDirectoryConfig
|
|
@@ -293,6 +293,284 @@ import {
|
|
|
293
293
|
ValidationError
|
|
294
294
|
} from "./chunk-IGM563N5.js";
|
|
295
295
|
|
|
296
|
+
// src/via/blob/binding.ts
|
|
297
|
+
async function eraseBlobs(ctx, cfg) {
|
|
298
|
+
if (cfg.purgeBlobsForRecord) return cfg.purgeBlobsForRecord(ctx.id);
|
|
299
|
+
return { shredded: 0, residue: [] };
|
|
300
|
+
}
|
|
301
|
+
function buildBlobDescribeFragment(fields) {
|
|
302
|
+
return {
|
|
303
|
+
blobFields: Object.fromEntries(
|
|
304
|
+
Object.entries(fields).map(([field, p]) => [field, {
|
|
305
|
+
...p.retainDays !== void 0 ? { retainDays: p.retainDays } : {},
|
|
306
|
+
...p.evictWhen !== void 0 ? { evictWhen: true } : {},
|
|
307
|
+
...p.legalHold !== void 0 ? { legalHold: true } : {},
|
|
308
|
+
...p.retainUntil !== void 0 ? { retainUntil: true } : {},
|
|
309
|
+
...p.external === true ? { external: true } : {},
|
|
310
|
+
...p.public === true ? { public: true } : {},
|
|
311
|
+
...p.backlink !== void 0 ? { backlink: p.backlink } : {}
|
|
312
|
+
}])
|
|
313
|
+
)
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function blobBinding(cfg) {
|
|
317
|
+
return {
|
|
318
|
+
brand: "blob",
|
|
319
|
+
// encryptedAtRest: 'envelope' — blob chunks are AEAD-encrypted envelopes
|
|
320
|
+
// in `_blob_chunks` (service-side), not sealed record fields; queryable:
|
|
321
|
+
// 'none' — nothing indexes blob content; exportable — vault.exportBlobs()
|
|
322
|
+
// is a first-class door; forgettable — shredAllForRecord participates in
|
|
323
|
+
// vault.forget().
|
|
324
|
+
posture: { encryptedAtRest: "envelope", queryable: "none", exportable: true, forgettable: true },
|
|
325
|
+
covers: (field) => field in cfg.fields,
|
|
326
|
+
erase: (ctx) => eraseBlobs(ctx, cfg),
|
|
327
|
+
describeFragment: () => buildBlobDescribeFragment(cfg.fields)
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function linkBlobVia() {
|
|
331
|
+
installViaBinder("blob", (c) => blobBinding(c));
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// src/port/with/blob-strategy.ts
|
|
335
|
+
linkBlobVia();
|
|
336
|
+
var NO_BLOBS = {
|
|
337
|
+
openSlot() {
|
|
338
|
+
throw new Error(
|
|
339
|
+
'Blob storage is not enabled on this Noydb instance. Import `{ withBlobs }` from "@noy-db/hub/blobs" and pass `withBlobs()` to `createNoydb({ blobStrategy: withBlobs() })`.'
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
// src/with-audit/consent/strategy.ts
|
|
345
|
+
var NO_CONSENT = {
|
|
346
|
+
async write() {
|
|
347
|
+
},
|
|
348
|
+
async read() {
|
|
349
|
+
return [];
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
// src/with-commit/crdt/strategy.ts
|
|
354
|
+
var NOT_ENABLED = new Error(
|
|
355
|
+
'CRDT mode requires the CRDT strategy. Import `{ withCrdt }` from "@noy-db/hub/crdt" and pass it to `createNoydb({ crdtStrategy: withCrdt() })`.'
|
|
356
|
+
);
|
|
357
|
+
var NO_CRDT = {
|
|
358
|
+
buildLwwMapState() {
|
|
359
|
+
throw NOT_ENABLED;
|
|
360
|
+
},
|
|
361
|
+
buildRgaState() {
|
|
362
|
+
throw NOT_ENABLED;
|
|
363
|
+
},
|
|
364
|
+
mergeCrdtStates() {
|
|
365
|
+
throw NOT_ENABLED;
|
|
366
|
+
},
|
|
367
|
+
resolveCrdtSnapshot() {
|
|
368
|
+
throw NOT_ENABLED;
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// src/with-commit/history/strategy.ts
|
|
373
|
+
function notEnabled(op) {
|
|
374
|
+
return new Error(
|
|
375
|
+
`${op} requires the history strategy. Import \`{ withHistory }\` from "@noy-db/hub/history" and pass it to \`createNoydb({ historyStrategy: withHistory() })\`.`
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
var NO_HISTORY = {
|
|
379
|
+
async saveHistory() {
|
|
380
|
+
},
|
|
381
|
+
async getHistoryEntries() {
|
|
382
|
+
throw notEnabled("collection.history()");
|
|
383
|
+
},
|
|
384
|
+
async getVersionEnvelope() {
|
|
385
|
+
throw notEnabled("collection.getVersion()");
|
|
386
|
+
},
|
|
387
|
+
async pruneHistory() {
|
|
388
|
+
return 0;
|
|
389
|
+
},
|
|
390
|
+
async clearHistory() {
|
|
391
|
+
return 0;
|
|
392
|
+
},
|
|
393
|
+
async tombstoneHistory() {
|
|
394
|
+
return 0;
|
|
395
|
+
},
|
|
396
|
+
async rewrapHistory() {
|
|
397
|
+
},
|
|
398
|
+
async envelopePayloadHash() {
|
|
399
|
+
return "";
|
|
400
|
+
},
|
|
401
|
+
computePatch() {
|
|
402
|
+
return [];
|
|
403
|
+
},
|
|
404
|
+
diff() {
|
|
405
|
+
throw notEnabled("collection.diff()");
|
|
406
|
+
},
|
|
407
|
+
buildLedger() {
|
|
408
|
+
return null;
|
|
409
|
+
},
|
|
410
|
+
buildVaultInstant() {
|
|
411
|
+
throw notEnabled("vault.at() / vault.timeMachine()");
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
// src/with-lookup/indexing/strategy.ts
|
|
416
|
+
var NO_INDEXING = {
|
|
417
|
+
createState() {
|
|
418
|
+
return DISABLED_STATE;
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
var DISABLED_STATE = {
|
|
422
|
+
isEnabled: false,
|
|
423
|
+
getEagerIndexes: () => null,
|
|
424
|
+
getPersistedIndexes: () => null
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
// src/with-audit/periods/strategy.ts
|
|
428
|
+
var NOT_ENABLED2 = new Error(
|
|
429
|
+
'Accounting periods require the periods strategy. Import `{ withPeriods }` from "@noy-db/hub/periods" and pass it to `createNoydb({ periodsStrategy: withPeriods() })`.'
|
|
430
|
+
);
|
|
431
|
+
var NO_PERIODS = {
|
|
432
|
+
async loadPeriods() {
|
|
433
|
+
return [];
|
|
434
|
+
},
|
|
435
|
+
async chainAnchor() {
|
|
436
|
+
return { priorPeriodHash: "" };
|
|
437
|
+
},
|
|
438
|
+
assertTsWritable() {
|
|
439
|
+
},
|
|
440
|
+
validatePeriodName() {
|
|
441
|
+
throw NOT_ENABLED2;
|
|
442
|
+
},
|
|
443
|
+
async appendPeriodLedgerEntry() {
|
|
444
|
+
throw NOT_ENABLED2;
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
// src/with-party/session/strategy.ts
|
|
449
|
+
function notEnabled2(op) {
|
|
450
|
+
return new Error(
|
|
451
|
+
`${op} requires the session strategy. Import \`{ withSession }\` from "@noy-db/hub/session" and pass it to \`createNoydb({ sessionStrategy: withSession() })\`.`
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
var NO_SESSION = {
|
|
455
|
+
validateSessionPolicy() {
|
|
456
|
+
throw notEnabled2("sessionPolicy");
|
|
457
|
+
},
|
|
458
|
+
createEnforcer() {
|
|
459
|
+
throw notEnabled2("session policy enforcement");
|
|
460
|
+
},
|
|
461
|
+
revokeAllSessions() {
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
// src/with-fork/shadow/strategy.ts
|
|
466
|
+
var NOT_ENABLED3 = new Error(
|
|
467
|
+
'VaultFrame requires the shadow strategy. Import `{ withShadow }` from "@noy-db/hub/shadow" and pass it to `createNoydb({ shadowStrategy: withShadow() })`.'
|
|
468
|
+
);
|
|
469
|
+
var NO_SHADOW = {
|
|
470
|
+
buildFrame() {
|
|
471
|
+
throw NOT_ENABLED3;
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
// src/with-fork/snapshots/strategy.ts
|
|
476
|
+
var NOT_ENABLED4 = new Error(
|
|
477
|
+
'Snapshots require the snapshot strategy. Import `{ withSnapshots }` from "@noy-db/hub/snapshots" and pass it to `createNoydb({ snapshotStrategy: withSnapshots({ store }) })`.'
|
|
478
|
+
);
|
|
479
|
+
var NO_SNAPSHOTS = {
|
|
480
|
+
async snapshot() {
|
|
481
|
+
throw NOT_ENABLED4;
|
|
482
|
+
},
|
|
483
|
+
async listSnapshots() {
|
|
484
|
+
throw NOT_ENABLED4;
|
|
485
|
+
},
|
|
486
|
+
async restoreSnapshot() {
|
|
487
|
+
throw NOT_ENABLED4;
|
|
488
|
+
},
|
|
489
|
+
async autoSnapshot() {
|
|
490
|
+
throw NOT_ENABLED4;
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
// src/with-party/team/sync-strategy.ts
|
|
495
|
+
function notEnabled3(op) {
|
|
496
|
+
return new Error(
|
|
497
|
+
`${op} requires the sync strategy. Import \`{ withSync }\` from "@noy-db/hub/sync" and pass it to \`createNoydb({ syncStrategy: withSync() })\`.`
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
var NO_SYNC = {
|
|
501
|
+
buildSyncEngine() {
|
|
502
|
+
throw notEnabled3("SyncEngine");
|
|
503
|
+
},
|
|
504
|
+
buildSyncTransaction() {
|
|
505
|
+
throw notEnabled3("SyncTransaction");
|
|
506
|
+
},
|
|
507
|
+
buildPresence() {
|
|
508
|
+
throw notEnabled3("collection.presence()");
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
// src/with-commit/tx/strategy.ts
|
|
513
|
+
var NOT_ENABLED5 = new Error(
|
|
514
|
+
'Multi-record transactions require the tx strategy. Import `{ withTransactions }` from "@noy-db/hub/tx" and pass it to `createNoydb({ txStrategy: withTransactions() })`.'
|
|
515
|
+
);
|
|
516
|
+
var NO_TX = {
|
|
517
|
+
async runTransaction(_db, _fn, _options, _txInvariants) {
|
|
518
|
+
throw NOT_ENABLED5;
|
|
519
|
+
},
|
|
520
|
+
async runDryRun() {
|
|
521
|
+
throw NOT_ENABLED5;
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// src/port/with/archive-strategy.ts
|
|
526
|
+
var ARCHIVE_NOT_ENABLED = "vault.archive/restore/listArchived require `archiveStrategy: withArchive({ store })` in createNoydb";
|
|
527
|
+
var NO_ARCHIVE = {
|
|
528
|
+
get store() {
|
|
529
|
+
throw new Error(ARCHIVE_NOT_ENABLED);
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
// src/port/with/strategies.ts
|
|
534
|
+
var STRATEGY_DEFAULTS = {
|
|
535
|
+
aggregate: NO_AGGREGATE,
|
|
536
|
+
archive: NO_ARCHIVE,
|
|
537
|
+
attestation: NO_ATTESTATION,
|
|
538
|
+
blob: NO_BLOBS,
|
|
539
|
+
broker: NO_BROKER,
|
|
540
|
+
cargo: NO_CARGO,
|
|
541
|
+
classified: NO_CLASSIFIED,
|
|
542
|
+
consent: NO_CONSENT,
|
|
543
|
+
crdt: NO_CRDT,
|
|
544
|
+
custody: NO_CUSTODY,
|
|
545
|
+
forget: NO_FORGET,
|
|
546
|
+
history: NO_HISTORY,
|
|
547
|
+
i18n: NO_I18N,
|
|
548
|
+
index: NO_INDEXING,
|
|
549
|
+
lazy: IMPLICIT_LAZY,
|
|
550
|
+
periods: NO_PERIODS,
|
|
551
|
+
portability: NO_PORTABILITY,
|
|
552
|
+
sealedRecord: NO_SEALED_RECORD,
|
|
553
|
+
search: NO_SEARCH,
|
|
554
|
+
sequence: NO_SEQUENCE,
|
|
555
|
+
session: NO_SESSION,
|
|
556
|
+
shadow: NO_SHADOW,
|
|
557
|
+
snapshot: NO_SNAPSHOTS,
|
|
558
|
+
sync: NO_SYNC,
|
|
559
|
+
team: NO_TEAM,
|
|
560
|
+
tiers: NO_TIERS,
|
|
561
|
+
tx: NO_TX
|
|
562
|
+
};
|
|
563
|
+
var STRATEGY_KEYS = Object.keys(STRATEGY_DEFAULTS);
|
|
564
|
+
function resolveStrategies(options) {
|
|
565
|
+
const provided = options;
|
|
566
|
+
const resolved = { ...STRATEGY_DEFAULTS };
|
|
567
|
+
for (const key of STRATEGY_KEYS) {
|
|
568
|
+
const value = provided[`${key}Strategy`];
|
|
569
|
+
if (value !== void 0) resolved[key] = value;
|
|
570
|
+
}
|
|
571
|
+
return resolved;
|
|
572
|
+
}
|
|
573
|
+
|
|
296
574
|
// src/port/by/default-provider.ts
|
|
297
575
|
async function createDefaultCoordinationProvider(store) {
|
|
298
576
|
const { StoreCoordinationProvider } = await import("./store-coordination-provider-3AELCZ4Y.js");
|
|
@@ -964,61 +1242,6 @@ async function resolveTierSyncPrior(ctx, id, priorEnvelope) {
|
|
|
964
1242
|
return await ctx.codec.decryptRecord(priorEnvelope, { skipValidation: true, id });
|
|
965
1243
|
}
|
|
966
1244
|
|
|
967
|
-
// src/with-commit/history/strategy.ts
|
|
968
|
-
function notEnabled(op) {
|
|
969
|
-
return new Error(
|
|
970
|
-
`${op} requires the history strategy. Import \`{ withHistory }\` from "@noy-db/hub/history" and pass it to \`createNoydb({ historyStrategy: withHistory() })\`.`
|
|
971
|
-
);
|
|
972
|
-
}
|
|
973
|
-
var NO_HISTORY = {
|
|
974
|
-
async saveHistory() {
|
|
975
|
-
},
|
|
976
|
-
async getHistoryEntries() {
|
|
977
|
-
throw notEnabled("collection.history()");
|
|
978
|
-
},
|
|
979
|
-
async getVersionEnvelope() {
|
|
980
|
-
throw notEnabled("collection.getVersion()");
|
|
981
|
-
},
|
|
982
|
-
async pruneHistory() {
|
|
983
|
-
return 0;
|
|
984
|
-
},
|
|
985
|
-
async clearHistory() {
|
|
986
|
-
return 0;
|
|
987
|
-
},
|
|
988
|
-
async tombstoneHistory() {
|
|
989
|
-
return 0;
|
|
990
|
-
},
|
|
991
|
-
async rewrapHistory() {
|
|
992
|
-
},
|
|
993
|
-
async envelopePayloadHash() {
|
|
994
|
-
return "";
|
|
995
|
-
},
|
|
996
|
-
computePatch() {
|
|
997
|
-
return [];
|
|
998
|
-
},
|
|
999
|
-
diff() {
|
|
1000
|
-
throw notEnabled("collection.diff()");
|
|
1001
|
-
},
|
|
1002
|
-
buildLedger() {
|
|
1003
|
-
return null;
|
|
1004
|
-
},
|
|
1005
|
-
buildVaultInstant() {
|
|
1006
|
-
throw notEnabled("vault.at() / vault.timeMachine()");
|
|
1007
|
-
}
|
|
1008
|
-
};
|
|
1009
|
-
|
|
1010
|
-
// src/with-lookup/indexing/strategy.ts
|
|
1011
|
-
var NO_INDEXING = {
|
|
1012
|
-
createState() {
|
|
1013
|
-
return DISABLED_STATE;
|
|
1014
|
-
}
|
|
1015
|
-
};
|
|
1016
|
-
var DISABLED_STATE = {
|
|
1017
|
-
isEnabled: false,
|
|
1018
|
-
getEagerIndexes: () => null,
|
|
1019
|
-
getPersistedIndexes: () => null
|
|
1020
|
-
};
|
|
1021
|
-
|
|
1022
1245
|
// src/with-lookup/search/serialize.ts
|
|
1023
1246
|
function serializeIndex(idx) {
|
|
1024
1247
|
return JSON.stringify(idx.toSnapshot());
|
|
@@ -1621,54 +1844,6 @@ function buildDescription(input) {
|
|
|
1621
1844
|
};
|
|
1622
1845
|
}
|
|
1623
1846
|
|
|
1624
|
-
// src/via/blob/binding.ts
|
|
1625
|
-
async function eraseBlobs(ctx, cfg) {
|
|
1626
|
-
if (cfg.purgeBlobsForRecord) return cfg.purgeBlobsForRecord(ctx.id);
|
|
1627
|
-
return { shredded: 0, residue: [] };
|
|
1628
|
-
}
|
|
1629
|
-
function buildBlobDescribeFragment(fields) {
|
|
1630
|
-
return {
|
|
1631
|
-
blobFields: Object.fromEntries(
|
|
1632
|
-
Object.entries(fields).map(([field, p]) => [field, {
|
|
1633
|
-
...p.retainDays !== void 0 ? { retainDays: p.retainDays } : {},
|
|
1634
|
-
...p.evictWhen !== void 0 ? { evictWhen: true } : {},
|
|
1635
|
-
...p.legalHold !== void 0 ? { legalHold: true } : {},
|
|
1636
|
-
...p.retainUntil !== void 0 ? { retainUntil: true } : {},
|
|
1637
|
-
...p.external === true ? { external: true } : {},
|
|
1638
|
-
...p.public === true ? { public: true } : {},
|
|
1639
|
-
...p.backlink !== void 0 ? { backlink: p.backlink } : {}
|
|
1640
|
-
}])
|
|
1641
|
-
)
|
|
1642
|
-
};
|
|
1643
|
-
}
|
|
1644
|
-
function blobBinding(cfg) {
|
|
1645
|
-
return {
|
|
1646
|
-
brand: "blob",
|
|
1647
|
-
// encryptedAtRest: 'envelope' — blob chunks are AEAD-encrypted envelopes
|
|
1648
|
-
// in `_blob_chunks` (service-side), not sealed record fields; queryable:
|
|
1649
|
-
// 'none' — nothing indexes blob content; exportable — vault.exportBlobs()
|
|
1650
|
-
// is a first-class door; forgettable — shredAllForRecord participates in
|
|
1651
|
-
// vault.forget().
|
|
1652
|
-
posture: { encryptedAtRest: "envelope", queryable: "none", exportable: true, forgettable: true },
|
|
1653
|
-
covers: (field) => field in cfg.fields,
|
|
1654
|
-
erase: (ctx) => eraseBlobs(ctx, cfg),
|
|
1655
|
-
describeFragment: () => buildBlobDescribeFragment(cfg.fields)
|
|
1656
|
-
};
|
|
1657
|
-
}
|
|
1658
|
-
function linkBlobVia() {
|
|
1659
|
-
installViaBinder("blob", (c) => blobBinding(c));
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
// src/port/with/blob-strategy.ts
|
|
1663
|
-
linkBlobVia();
|
|
1664
|
-
var NO_BLOBS = {
|
|
1665
|
-
openSlot() {
|
|
1666
|
-
throw new Error(
|
|
1667
|
-
'Blob storage is not enabled on this Noydb instance. Import `{ withBlobs }` from "@noy-db/hub/blobs" and pass `withBlobs()` to `createNoydb({ blobStrategy: withBlobs() })`.'
|
|
1668
|
-
);
|
|
1669
|
-
}
|
|
1670
|
-
};
|
|
1671
|
-
|
|
1672
1847
|
// src/with-formula/derivations/stale.ts
|
|
1673
1848
|
var _staleByRegistry = /* @__PURE__ */ new WeakMap();
|
|
1674
1849
|
var keyFor = (source, sourceId) => `${source}/${sourceId}`;
|
|
@@ -1742,43 +1917,6 @@ async function resolveStaleOnRead(accessor, outputCollection, id) {
|
|
|
1742
1917
|
}
|
|
1743
1918
|
}
|
|
1744
1919
|
|
|
1745
|
-
// src/with-commit/crdt/strategy.ts
|
|
1746
|
-
var NOT_ENABLED = new Error(
|
|
1747
|
-
'CRDT mode requires the CRDT strategy. Import `{ withCrdt }` from "@noy-db/hub/crdt" and pass it to `createNoydb({ crdtStrategy: withCrdt() })`.'
|
|
1748
|
-
);
|
|
1749
|
-
var NO_CRDT = {
|
|
1750
|
-
buildLwwMapState() {
|
|
1751
|
-
throw NOT_ENABLED;
|
|
1752
|
-
},
|
|
1753
|
-
buildRgaState() {
|
|
1754
|
-
throw NOT_ENABLED;
|
|
1755
|
-
},
|
|
1756
|
-
mergeCrdtStates() {
|
|
1757
|
-
throw NOT_ENABLED;
|
|
1758
|
-
},
|
|
1759
|
-
resolveCrdtSnapshot() {
|
|
1760
|
-
throw NOT_ENABLED;
|
|
1761
|
-
}
|
|
1762
|
-
};
|
|
1763
|
-
|
|
1764
|
-
// src/with-party/team/sync-strategy.ts
|
|
1765
|
-
function notEnabled2(op) {
|
|
1766
|
-
return new Error(
|
|
1767
|
-
`${op} requires the sync strategy. Import \`{ withSync }\` from "@noy-db/hub/sync" and pass it to \`createNoydb({ syncStrategy: withSync() })\`.`
|
|
1768
|
-
);
|
|
1769
|
-
}
|
|
1770
|
-
var NO_SYNC = {
|
|
1771
|
-
buildSyncEngine() {
|
|
1772
|
-
throw notEnabled2("SyncEngine");
|
|
1773
|
-
},
|
|
1774
|
-
buildSyncTransaction() {
|
|
1775
|
-
throw notEnabled2("SyncTransaction");
|
|
1776
|
-
},
|
|
1777
|
-
buildPresence() {
|
|
1778
|
-
throw notEnabled2("collection.presence()");
|
|
1779
|
-
}
|
|
1780
|
-
};
|
|
1781
|
-
|
|
1782
1920
|
// src/kernel/via/compose.ts
|
|
1783
1921
|
function via(...descriptors) {
|
|
1784
1922
|
if (descriptors.length === 0) {
|
|
@@ -1942,7 +2080,7 @@ function compileViaBindings(opts, classifiedGuardCtx, eraseCfgOut) {
|
|
|
1942
2080
|
...i18nFields !== void 0 ? { i18nFields } : {},
|
|
1943
2081
|
...dictKeyFields !== void 0 ? { dictKeyFields } : {},
|
|
1944
2082
|
...i18nDensifyFields !== void 0 ? { i18nDensifyFields } : {},
|
|
1945
|
-
strategy: opts.
|
|
2083
|
+
strategy: opts.strategies.i18n,
|
|
1946
2084
|
...opts.defaultLocale !== void 0 ? { defaultLocale: opts.defaultLocale } : {},
|
|
1947
2085
|
...opts.autoTranslateHook !== void 0 ? { autoTranslateHook: opts.autoTranslateHook } : {},
|
|
1948
2086
|
...opts.dictLabelResolver !== void 0 ? { dictLabelResolver: opts.dictLabelResolver } : {},
|
|
@@ -2056,6 +2194,11 @@ function resolveCollectionConfig(opts) {
|
|
|
2056
2194
|
`Collection "${opts.name}": embeddings are not supported on CRDT collections (L2). Use a non-CRDT collection for semantic search.`
|
|
2057
2195
|
);
|
|
2058
2196
|
}
|
|
2197
|
+
if (opts.sensitive && opts.sensitive.length > 0 && opts.crdt) {
|
|
2198
|
+
throw new Error(
|
|
2199
|
+
`Collection "${opts.name}": sensitive (structural group-encryption) is not supported on CRDT collections \u2014 the CRDT write path bypasses per-field sealing, so the fields would be stored in the ordinary encrypted body with no \`_sealed\` slot and no per-field key. Use a non-CRDT collection for sealed fields.`
|
|
2200
|
+
);
|
|
2201
|
+
}
|
|
2059
2202
|
if (opts.tiers && opts.tiers.length > 0 && opts.blobFields !== void 0 && Object.keys(opts.blobFields).length > 0 && opts.perRecordKeys !== true) {
|
|
2060
2203
|
throw new UnsupportedTierCompositionError(
|
|
2061
2204
|
"blobs",
|
|
@@ -2172,14 +2315,9 @@ function resolveCollectionConfig(opts) {
|
|
|
2172
2315
|
writeHooks: opts.writeHooks,
|
|
2173
2316
|
subsystemBus: opts.subsystemBus,
|
|
2174
2317
|
activeTxId: opts.activeTxId,
|
|
2175
|
-
|
|
2318
|
+
strategies: opts.strategies,
|
|
2176
2319
|
objectStore: opts.objectStore,
|
|
2177
2320
|
blobFields: opts.blobFields,
|
|
2178
|
-
aggregateStrategy: opts.aggregateStrategy ?? NO_AGGREGATE,
|
|
2179
|
-
crdtStrategy: opts.crdtStrategy ?? NO_CRDT,
|
|
2180
|
-
historyStrategy: opts.historyStrategy ?? NO_HISTORY,
|
|
2181
|
-
i18nStrategy: opts.i18nStrategy ?? NO_I18N,
|
|
2182
|
-
syncStrategy: opts.syncStrategy ?? NO_SYNC,
|
|
2183
2321
|
reconcileOnOpen: opts.reconcileOnOpen ?? "off",
|
|
2184
2322
|
getDEK: opts.getDEK,
|
|
2185
2323
|
onDirty: opts.onDirty,
|
|
@@ -2208,7 +2346,6 @@ function resolveCollectionConfig(opts) {
|
|
|
2208
2346
|
moneyFields: effectiveViaFields.moneyFields,
|
|
2209
2347
|
classified: resolvedClassified,
|
|
2210
2348
|
classifiedGuardCtx,
|
|
2211
|
-
classifiedStrategy: opts.classifiedStrategy ?? NO_CLASSIFIED,
|
|
2212
2349
|
computed: mergedComputed,
|
|
2213
2350
|
computedEdges,
|
|
2214
2351
|
viaDepsEdges,
|
|
@@ -2230,8 +2367,6 @@ function resolveCollectionConfig(opts) {
|
|
|
2230
2367
|
materializedViewSource: opts.materializedViewSource,
|
|
2231
2368
|
graphDispatch: opts.graphDispatch,
|
|
2232
2369
|
tiers: opts.tiers && opts.tiers.length > 0 ? new Set(opts.tiers) : null,
|
|
2233
|
-
tiersStrategy: opts.tiersStrategy ?? NO_TIERS,
|
|
2234
|
-
searchStrategy: opts.searchStrategy ?? NO_SEARCH,
|
|
2235
2370
|
tierMode: opts.tierMode ?? "invisibility",
|
|
2236
2371
|
blobTierPolicy: opts.blobTierPolicy ?? "isolate",
|
|
2237
2372
|
onCrossTierAccess: opts.onCrossTierAccess,
|
|
@@ -2293,25 +2428,20 @@ var Collection = class {
|
|
|
2293
2428
|
/** True when the caller explicitly provided a `historyConfig` option (vs. inheriting the vault default). */
|
|
2294
2429
|
historyConfigExplicit;
|
|
2295
2430
|
/**
|
|
2296
|
-
*
|
|
2297
|
-
*
|
|
2298
|
-
*
|
|
2299
|
-
*
|
|
2300
|
-
*
|
|
2301
|
-
*
|
|
2302
|
-
* reaches the bundle
|
|
2431
|
+
* Every opt-in service, resolved once by `createNoydb` (#838) and shared by
|
|
2432
|
+
* reference with the owning `Vault` and `Noydb`.
|
|
2433
|
+
*
|
|
2434
|
+
* Each entry is a tree-shake seam. An un-opted-in service resolves to its
|
|
2435
|
+
* `NO_*` stub — a tiny module that throws with an actionable message —
|
|
2436
|
+
* so, for example, none of the BlobSet / chunk / MIME-magic machinery
|
|
2437
|
+
* reaches the bundle unless the consumer imports `@noy-db/hub/blobs` and
|
|
2438
|
+
* passes `blobStrategy: blobs()` to `createNoydb`.
|
|
2303
2439
|
*/
|
|
2304
|
-
|
|
2440
|
+
strategies;
|
|
2305
2441
|
objectStore;
|
|
2306
2442
|
blobFields;
|
|
2307
2443
|
blobTierPolicy;
|
|
2308
2444
|
// #724 T2/T3
|
|
2309
|
-
aggregateStrategy;
|
|
2310
|
-
crdtStrategy;
|
|
2311
|
-
tiersStrategy;
|
|
2312
|
-
searchStrategy;
|
|
2313
|
-
historyStrategy;
|
|
2314
|
-
syncStrategy;
|
|
2315
2445
|
// In-memory cache of decrypted records (eager mode only). Lazy mode
|
|
2316
2446
|
// uses `lru` instead. Both fields exist so a single Collection instance
|
|
2317
2447
|
// doesn't need a runtime branch on every cache access.
|
|
@@ -2481,12 +2611,6 @@ var Collection = class {
|
|
|
2481
2611
|
/** C-A/R10 memoization: marker declared-set lookup (undefined=unresolved) + classified-handle persist-once flag. */
|
|
2482
2612
|
_markerDigestOnlyCache = void 0;
|
|
2483
2613
|
_markerPersisted = false;
|
|
2484
|
-
/**
|
|
2485
|
-
* Tree-shake seam for `reveal()` — defaults to `NO_CLASSIFIED`, which
|
|
2486
|
-
* throws `ClassifiedNotEnabledError`. Set via the `classifiedStrategy`
|
|
2487
|
-
* `createNoydb()` option (opt in with `withClassified()`).
|
|
2488
|
-
*/
|
|
2489
|
-
classifiedStrategy;
|
|
2490
2614
|
/** Async callback provided by the Vault to open a dynamic dictionary handle (for label-map pre-computation in the search index). Only used in `resolveDictLabelMaps()`; static dicts bypass this entirely. Mutable, assign-once — see {@link _reconcileReadState} (#671 item 1). */
|
|
2491
2615
|
getDictionary;
|
|
2492
2616
|
/**
|
|
@@ -2635,16 +2759,10 @@ var Collection = class {
|
|
|
2635
2759
|
this.writeHooks = cfg.writeHooks;
|
|
2636
2760
|
this.subsystemBus = cfg.subsystemBus;
|
|
2637
2761
|
this.activeTxId = cfg.activeTxId;
|
|
2638
|
-
this.
|
|
2762
|
+
this.strategies = cfg.strategies;
|
|
2639
2763
|
this.objectStore = cfg.objectStore;
|
|
2640
2764
|
this.blobFields = cfg.blobFields;
|
|
2641
2765
|
this.blobTierPolicy = cfg.blobTierPolicy ?? "isolate";
|
|
2642
|
-
this.aggregateStrategy = cfg.aggregateStrategy;
|
|
2643
|
-
this.crdtStrategy = cfg.crdtStrategy;
|
|
2644
|
-
this.tiersStrategy = cfg.tiersStrategy;
|
|
2645
|
-
this.searchStrategy = cfg.searchStrategy;
|
|
2646
|
-
this.historyStrategy = cfg.historyStrategy;
|
|
2647
|
-
this.syncStrategy = cfg.syncStrategy;
|
|
2648
2766
|
this.reconcileOnOpen = cfg.reconcileOnOpen;
|
|
2649
2767
|
this.getDEK = cfg.getDEK;
|
|
2650
2768
|
this.onDirty = cfg.onDirty;
|
|
@@ -2671,7 +2789,6 @@ var Collection = class {
|
|
|
2671
2789
|
this.classified = cfg.classified;
|
|
2672
2790
|
this.classifiedGuardCtx = cfg.classifiedGuardCtx;
|
|
2673
2791
|
this.vdigFields = cfg.vdigFields;
|
|
2674
|
-
this.classifiedStrategy = cfg.classifiedStrategy;
|
|
2675
2792
|
this.computed = cfg.computed;
|
|
2676
2793
|
this.getDictionary = cfg.getDictionary;
|
|
2677
2794
|
this.defaultLocale = cfg.defaultLocale;
|
|
@@ -2719,7 +2836,7 @@ var Collection = class {
|
|
|
2719
2836
|
deterministicFields: this.deterministicFields,
|
|
2720
2837
|
vdigFields: this.vdigFields,
|
|
2721
2838
|
crdtMode: this.crdtMode,
|
|
2722
|
-
crdtStrategy: this.
|
|
2839
|
+
crdtStrategy: this.strategies.crdt,
|
|
2723
2840
|
schema: this.schema,
|
|
2724
2841
|
getDEK: (collection) => this.getDEK(collection ?? this.name),
|
|
2725
2842
|
cekCache: this.cekCache,
|
|
@@ -2737,7 +2854,7 @@ var Collection = class {
|
|
|
2737
2854
|
const remoteJson = await this.codec.decryptJsonString(remote, id);
|
|
2738
2855
|
if (localJson === null) return local;
|
|
2739
2856
|
if (remoteJson === null) return remote;
|
|
2740
|
-
const merged = this.
|
|
2857
|
+
const merged = this.strategies.crdt.mergeCrdtStates(JSON.parse(localJson), JSON.parse(remoteJson));
|
|
2741
2858
|
const mergedVersion = Math.max(local._v, remote._v) + 1;
|
|
2742
2859
|
const cek = this.perRecordCek ? await this.resolveRecordCek(id) : void 0;
|
|
2743
2860
|
return this.codec.encryptJsonString(JSON.stringify(merged), mergedVersion, cek);
|
|
@@ -2795,12 +2912,12 @@ var Collection = class {
|
|
|
2795
2912
|
}
|
|
2796
2913
|
this.lazy = opts.prefetch === false;
|
|
2797
2914
|
if (this.lazy) {
|
|
2798
|
-
this.lru =
|
|
2915
|
+
this.lru = opts.strategies.lazy.createCache(this.name, opts.cache);
|
|
2799
2916
|
this.hydrated = true;
|
|
2800
2917
|
} else {
|
|
2801
2918
|
this.lru = null;
|
|
2802
2919
|
}
|
|
2803
|
-
const strategy = opts.
|
|
2920
|
+
const strategy = opts.strategies.index;
|
|
2804
2921
|
this.indexState = strategy.createState({
|
|
2805
2922
|
defs: opts.indexes ?? [],
|
|
2806
2923
|
lazy: this.lazy
|
|
@@ -2955,7 +3072,7 @@ var Collection = class {
|
|
|
2955
3072
|
if (spec.storage === "digest-only") {
|
|
2956
3073
|
throw new ClassifiedRevealError(this.name, field, `storage:'digest-only' \u2014 verify-only; nothing recoverable to reveal`);
|
|
2957
3074
|
}
|
|
2958
|
-
return this.
|
|
3075
|
+
return this.strategies.classified.reveal({
|
|
2959
3076
|
collection: this.name,
|
|
2960
3077
|
spec,
|
|
2961
3078
|
encrypted: this.storeCiphertext,
|
|
@@ -2975,7 +3092,7 @@ var Collection = class {
|
|
|
2975
3092
|
throw new ClassifiedVerifyError(this.name, field, `storage:'never' \u2014 nothing is stored to verify against`);
|
|
2976
3093
|
}
|
|
2977
3094
|
const ctx = this._classifiedVerifyCtx(spec);
|
|
2978
|
-
return spec.storage === "digest-only" ? this.
|
|
3095
|
+
return spec.storage === "digest-only" ? this.strategies.classified.verify(ctx, id, field, candidate) : this.strategies.classified.verifyText(ctx, id, field, candidate);
|
|
2979
3096
|
}
|
|
2980
3097
|
/** k-of-n challenge over the collection's secretAnswer members. Requires withClassified(). */
|
|
2981
3098
|
async verifyGroup(id, answers, opts) {
|
|
@@ -2984,7 +3101,7 @@ var Collection = class {
|
|
|
2984
3101
|
throw new ClassifiedVerifyError(this.name, "*", "no groupable digest-only (secretAnswer) fields declared");
|
|
2985
3102
|
}
|
|
2986
3103
|
const ctx = { ...this._classifiedVerifyCtx(members[0].spec), groupMembers: members };
|
|
2987
|
-
return this.
|
|
3104
|
+
return this.strategies.classified.matchGroup(ctx, id, answers, opts);
|
|
2988
3105
|
}
|
|
2989
3106
|
_classifiedVerifyCtx(spec) {
|
|
2990
3107
|
return {
|
|
@@ -3039,7 +3156,7 @@ var Collection = class {
|
|
|
3039
3156
|
if (typeof candidate !== "string") {
|
|
3040
3157
|
throw new ClassifiedVerifyError(this.name, "*", "candidate must be a string");
|
|
3041
3158
|
}
|
|
3042
|
-
const target = await this.
|
|
3159
|
+
const target = await this.strategies.classified.computeTarget(this._classifiedVerifyCtx(spec), field, candidate);
|
|
3043
3160
|
const ids = await this.adapter.list(this.vault, this.name);
|
|
3044
3161
|
const hits = [];
|
|
3045
3162
|
const hitMap = /* @__PURE__ */ new Map();
|
|
@@ -3126,7 +3243,7 @@ var Collection = class {
|
|
|
3126
3243
|
id,
|
|
3127
3244
|
version: scrubbed._v,
|
|
3128
3245
|
actor: this.keyring.userId,
|
|
3129
|
-
payloadHash: await this.
|
|
3246
|
+
payloadHash: await this.strategies.history.envelopePayloadHash(scrubbed),
|
|
3130
3247
|
reason: "classified:scrub-equatable-tags"
|
|
3131
3248
|
});
|
|
3132
3249
|
}
|
|
@@ -3258,7 +3375,7 @@ var Collection = class {
|
|
|
3258
3375
|
}
|
|
3259
3376
|
}
|
|
3260
3377
|
if (this.materializedViewSource !== void 0) {
|
|
3261
|
-
const { resolveStaleMVOnRead } = await import("./stale-
|
|
3378
|
+
const { resolveStaleMVOnRead } = await import("./stale-4UNPHWOU.js");
|
|
3262
3379
|
await resolveStaleMVOnRead(this.materializedViewSource, this.name, this.#dispatchCtx({ collection: this.name, id: "resolve-on-read" }));
|
|
3263
3380
|
}
|
|
3264
3381
|
let record;
|
|
@@ -3352,7 +3469,7 @@ var Collection = class {
|
|
|
3352
3469
|
if (this.syncAdapter !== void 0) presenceOpts.syncAdapter = this.syncAdapter;
|
|
3353
3470
|
if (opts?.staleMs !== void 0) presenceOpts.staleMs = opts.staleMs;
|
|
3354
3471
|
if (opts?.pollIntervalMs !== void 0) presenceOpts.pollIntervalMs = opts.pollIntervalMs;
|
|
3355
|
-
return this.
|
|
3472
|
+
return this.strategies.sync.buildPresence(presenceOpts);
|
|
3356
3473
|
}
|
|
3357
3474
|
/**
|
|
3358
3475
|
* Create or update a record. Runs inside the hub's write-queue tracker
|
|
@@ -3572,7 +3689,7 @@ var Collection = class {
|
|
|
3572
3689
|
}
|
|
3573
3690
|
}
|
|
3574
3691
|
}
|
|
3575
|
-
crdtState = this.
|
|
3692
|
+
crdtState = this.strategies.crdt.buildLwwMapState(record, existingState, now);
|
|
3576
3693
|
} else if (this.crdtMode === "rga") {
|
|
3577
3694
|
let existingState;
|
|
3578
3695
|
if (existingEnvelope) {
|
|
@@ -3584,7 +3701,7 @@ var Collection = class {
|
|
|
3584
3701
|
}
|
|
3585
3702
|
}
|
|
3586
3703
|
}
|
|
3587
|
-
crdtState = this.
|
|
3704
|
+
crdtState = this.strategies.crdt.buildRgaState(Array.isArray(record) ? record : [record], existingState, generateULID);
|
|
3588
3705
|
} else {
|
|
3589
3706
|
crdtState = { _crdt: "yjs", update: record };
|
|
3590
3707
|
}
|
|
@@ -3592,14 +3709,14 @@ var Collection = class {
|
|
|
3592
3709
|
const cek2 = this.perRecordCek ? await this.resolveRecordCek(id) : void 0;
|
|
3593
3710
|
const envelope2 = await this.codec.encryptJsonString(JSON.stringify(crdtState), version2, cek2, options?.source, options?.sourceTs);
|
|
3594
3711
|
await this.adapter.put(this.vault, this.name, id, envelope2);
|
|
3595
|
-
const resolvedRecord = this.
|
|
3712
|
+
const resolvedRecord = this.strategies.crdt.resolveCrdtSnapshot(crdtState);
|
|
3596
3713
|
const existingResolvedRecord = existingEnvelope ? await this.codec.decryptRecord(existingEnvelope, { skipValidation: true }) : null;
|
|
3597
3714
|
const existingResolved = existingResolvedRecord !== null ? { record: existingResolvedRecord, version: existingVersion } : void 0;
|
|
3598
3715
|
if (existingResolved && this.historyConfig.enabled !== false) {
|
|
3599
|
-
await this.
|
|
3716
|
+
await this.strategies.history.saveHistory(this.adapter, this.vault, this.name, id, await this.codec.encryptRecord(existingResolved.record, existingResolved.version, cek2, void 0, void 0, this.vdigFields !== null ? { id, prev: existingEnvelope } : void 0, id));
|
|
3600
3717
|
this.emitter.emit("history:save", { vault: this.vault, collection: this.name, id, version: existingResolved.version });
|
|
3601
3718
|
if (this.historyConfig.maxVersions) {
|
|
3602
|
-
await this.
|
|
3719
|
+
await this.strategies.history.pruneHistory(this.adapter, this.vault, this.name, id, { keepVersions: this.historyConfig.maxVersions });
|
|
3603
3720
|
}
|
|
3604
3721
|
}
|
|
3605
3722
|
if (this.ledger) {
|
|
@@ -3609,9 +3726,9 @@ var Collection = class {
|
|
|
3609
3726
|
id,
|
|
3610
3727
|
version: version2,
|
|
3611
3728
|
actor: this.keyring.userId,
|
|
3612
|
-
payloadHash: await this.
|
|
3729
|
+
payloadHash: await this.strategies.history.envelopePayloadHash(envelope2)
|
|
3613
3730
|
};
|
|
3614
|
-
if (existingResolved) appendInput.delta = this.
|
|
3731
|
+
if (existingResolved) appendInput.delta = this.strategies.history.computePatch(resolvedRecord, existingResolved.record);
|
|
3615
3732
|
if (options?.reason !== void 0) appendInput.reason = options.reason;
|
|
3616
3733
|
await this.ledger.append(appendInput);
|
|
3617
3734
|
}
|
|
@@ -3658,21 +3775,21 @@ var Collection = class {
|
|
|
3658
3775
|
const cek = this.perRecordCek ? await this.resolveRecordCek(id) : void 0;
|
|
3659
3776
|
const vdigCtx = this.vdigFields !== null ? { id, prev: await this.adapter.get(this.vault, this.name, id) } : void 0;
|
|
3660
3777
|
if (existing && this.historyConfig.enabled !== false) {
|
|
3661
|
-
await this.
|
|
3778
|
+
await this.strategies.history.saveHistory(this.adapter, this.vault, this.name, id, await this.codec.encryptRecord(existing.record, existing.version, cek, void 0, void 0, vdigCtx, id));
|
|
3662
3779
|
this.emitter.emit("history:save", {
|
|
3663
3780
|
vault: this.vault,
|
|
3664
3781
|
collection: this.name,
|
|
3665
3782
|
id,
|
|
3666
3783
|
version: existing.version
|
|
3667
3784
|
});
|
|
3668
|
-
if (this.historyConfig.maxVersions) await this.
|
|
3785
|
+
if (this.historyConfig.maxVersions) await this.strategies.history.pruneHistory(this.adapter, this.vault, this.name, id, { keepVersions: this.historyConfig.maxVersions });
|
|
3669
3786
|
}
|
|
3670
3787
|
const envelope = await this.codec.encryptRecord(record, version, cek, options?.source, options?.sourceTs, vdigCtx, id);
|
|
3671
3788
|
await this.adapter.put(this.vault, this.name, id, envelope);
|
|
3672
3789
|
this.markerIds.delete(id);
|
|
3673
3790
|
await this._ensureClassifiedMarker();
|
|
3674
3791
|
if (this.embeddings) {
|
|
3675
|
-
await this.
|
|
3792
|
+
await this.strategies.search.embedOnWrite(this.searchContext(), id, record, version);
|
|
3676
3793
|
}
|
|
3677
3794
|
if (this.ledger) {
|
|
3678
3795
|
const appendInput = {
|
|
@@ -3681,10 +3798,10 @@ var Collection = class {
|
|
|
3681
3798
|
id,
|
|
3682
3799
|
version,
|
|
3683
3800
|
actor: this.keyring.userId,
|
|
3684
|
-
payloadHash: await this.
|
|
3801
|
+
payloadHash: await this.strategies.history.envelopePayloadHash(envelope)
|
|
3685
3802
|
};
|
|
3686
3803
|
if (existing) {
|
|
3687
|
-
appendInput.delta = this.
|
|
3804
|
+
appendInput.delta = this.strategies.history.computePatch(record, existing.record);
|
|
3688
3805
|
}
|
|
3689
3806
|
if (options?.reason !== void 0) appendInput.reason = options.reason;
|
|
3690
3807
|
await this.ledger.append(appendInput);
|
|
@@ -3727,7 +3844,7 @@ var Collection = class {
|
|
|
3727
3844
|
if (wave?.seen(`mv\0${reg.spec.name}`)) continue;
|
|
3728
3845
|
if (executor === null) {
|
|
3729
3846
|
;
|
|
3730
|
-
({ MaterializedViewExecutor: executor } = await import("./executor-
|
|
3847
|
+
({ MaterializedViewExecutor: executor } = await import("./executor-YORMIBWV.js"));
|
|
3731
3848
|
}
|
|
3732
3849
|
await executor.refresh(reg, {
|
|
3733
3850
|
getCollection: (name) => this.materializedViewSource.getCollection(name),
|
|
@@ -3737,7 +3854,7 @@ var Collection = class {
|
|
|
3737
3854
|
});
|
|
3738
3855
|
} else if (mode === "lazy") {
|
|
3739
3856
|
if (staleHelpers === null) {
|
|
3740
|
-
staleHelpers = await import("./stale-
|
|
3857
|
+
staleHelpers = await import("./stale-4UNPHWOU.js");
|
|
3741
3858
|
}
|
|
3742
3859
|
staleHelpers.markMVStale(registry, reg.spec.name);
|
|
3743
3860
|
}
|
|
@@ -4203,10 +4320,10 @@ var Collection = class {
|
|
|
4203
4320
|
if (existing && this.historyConfig.enabled !== false) {
|
|
4204
4321
|
const cek = this.perRecordCek ? await this.resolveRecordCek(id) : void 0;
|
|
4205
4322
|
const prevForVdig = this.vdigFields !== null ? await this.adapter.get(this.vault, this.name, id) : null;
|
|
4206
|
-
await this.
|
|
4323
|
+
await this.strategies.history.saveHistory(this.adapter, this.vault, this.name, id, await this.codec.encryptRecord(existing.record, existing.version, cek, void 0, void 0, this.vdigFields !== null ? { id, prev: prevForVdig } : void 0, id));
|
|
4207
4324
|
}
|
|
4208
4325
|
const previousEnvelope = await this.adapter.get(this.vault, this.name, id);
|
|
4209
|
-
const previousPayloadHash = await this.
|
|
4326
|
+
const previousPayloadHash = await this.strategies.history.envelopePayloadHash(previousEnvelope);
|
|
4210
4327
|
let markerVersion;
|
|
4211
4328
|
if (this.onDirty) {
|
|
4212
4329
|
const live = previousEnvelope;
|
|
@@ -4356,7 +4473,7 @@ var Collection = class {
|
|
|
4356
4473
|
if (mode === "eager") {
|
|
4357
4474
|
if (executor === null) {
|
|
4358
4475
|
;
|
|
4359
|
-
({ MaterializedViewExecutor: executor } = await import("./executor-
|
|
4476
|
+
({ MaterializedViewExecutor: executor } = await import("./executor-YORMIBWV.js"));
|
|
4360
4477
|
}
|
|
4361
4478
|
const rr = await executor.refresh(reg, {
|
|
4362
4479
|
getCollection: (name) => this.materializedViewSource.getCollection(name),
|
|
@@ -4369,7 +4486,7 @@ var Collection = class {
|
|
|
4369
4486
|
residueDeclined.push(...rr.residueDeclined);
|
|
4370
4487
|
} else {
|
|
4371
4488
|
if (staleHelpers === null) {
|
|
4372
|
-
staleHelpers = await import("./stale-
|
|
4489
|
+
staleHelpers = await import("./stale-4UNPHWOU.js");
|
|
4373
4490
|
}
|
|
4374
4491
|
const inv = await staleHelpers.invalidateMVAtRest(this.materializedViewSource, reg, mode);
|
|
4375
4492
|
deleted += inv.deleted;
|
|
@@ -4396,7 +4513,7 @@ var Collection = class {
|
|
|
4396
4513
|
);
|
|
4397
4514
|
}
|
|
4398
4515
|
if (this.materializedViewSource !== void 0) {
|
|
4399
|
-
const { resolveStaleMVOnRead } = await import("./stale-
|
|
4516
|
+
const { resolveStaleMVOnRead } = await import("./stale-4UNPHWOU.js");
|
|
4400
4517
|
await resolveStaleMVOnRead(this.materializedViewSource, this.name, this.#dispatchCtx({ collection: this.name, id: "resolve-on-read" }));
|
|
4401
4518
|
}
|
|
4402
4519
|
await this.ensureHydrated();
|
|
@@ -4417,28 +4534,28 @@ var Collection = class {
|
|
|
4417
4534
|
* see `src/search/tokenize.ts` for the Thai/CJK caveat.
|
|
4418
4535
|
*/
|
|
4419
4536
|
search(field, query, opts = {}) {
|
|
4420
|
-
return this.
|
|
4537
|
+
return this.strategies.search.search(this.searchContext(), field, query, opts);
|
|
4421
4538
|
}
|
|
4422
4539
|
/** Force-persist the lexical index now — gated behind `searchStrategy: withSearch()`. */
|
|
4423
4540
|
flushIndex() {
|
|
4424
|
-
return this.
|
|
4541
|
+
return this.strategies.search.flushIndex(this.searchContext());
|
|
4425
4542
|
}
|
|
4426
4543
|
/** Pre-build the lexical index — gated behind `searchStrategy: withSearch()`. */
|
|
4427
4544
|
warmIndex() {
|
|
4428
|
-
return this.
|
|
4545
|
+
return this.strategies.search.warmIndex(this.searchContext());
|
|
4429
4546
|
}
|
|
4430
4547
|
/** Retrieval (lexical | semantic | hybrid) — gated behind `searchStrategy: withSearch()`. */
|
|
4431
4548
|
retrieve(query, opts = {}) {
|
|
4432
|
-
return this.
|
|
4549
|
+
return this.strategies.search.retrieve(this.searchContext(), query, opts);
|
|
4433
4550
|
}
|
|
4434
4551
|
/** Raw-vector kNN — gated behind `searchStrategy: withSearch()`. */
|
|
4435
4552
|
similarTo(vector, opts = {}) {
|
|
4436
|
-
return this.
|
|
4553
|
+
return this.strategies.search.similarTo(this.searchContext(), vector, opts);
|
|
4437
4554
|
}
|
|
4438
4555
|
/** Opt-in bulk `_vec` re-derive (#788) — a plain collection has nothing to rebuild; gated behind `searchStrategy: withSearch()` otherwise. */
|
|
4439
4556
|
rebuildEmbeddings() {
|
|
4440
4557
|
if (!this.embeddings) return Promise.resolve({ rebuilt: 0, skipped: 0 });
|
|
4441
|
-
return this.
|
|
4558
|
+
return this.strategies.search.rebuildEmbeddings(this.searchContext());
|
|
4442
4559
|
}
|
|
4443
4560
|
/**
|
|
4444
4561
|
* Bind the {@link SearchContext} the search/retrieval surface needs. The
|
|
@@ -4648,7 +4765,7 @@ var Collection = class {
|
|
|
4648
4765
|
...this.defaultLocale !== void 0 ? { defaultLocale: this.defaultLocale } : {},
|
|
4649
4766
|
...resolver.resolveDictSource ? { resolveDictSource: (field) => resolver.resolveDictSource(leftCollection, field) } : {}
|
|
4650
4767
|
} : void 0;
|
|
4651
|
-
return new Query(source, void 0, joinContext, this.
|
|
4768
|
+
return new Query(source, void 0, joinContext, this.strategies.aggregate);
|
|
4652
4769
|
}
|
|
4653
4770
|
/**
|
|
4654
4771
|
* Subscribe to every put/delete on this collection. Returns an
|
|
@@ -4762,7 +4879,7 @@ var Collection = class {
|
|
|
4762
4879
|
// ─── History Methods ────────────────────────────────────────────
|
|
4763
4880
|
/** Get version history for a record, newest first. */
|
|
4764
4881
|
async history(id, options) {
|
|
4765
|
-
const envelopes = await this.
|
|
4882
|
+
const envelopes = await this.strategies.history.getHistoryEntries(
|
|
4766
4883
|
this.adapter,
|
|
4767
4884
|
this.vault,
|
|
4768
4885
|
this.name,
|
|
@@ -4794,7 +4911,7 @@ var Collection = class {
|
|
|
4794
4911
|
* and re-put the records through the normal `put()` path.
|
|
4795
4912
|
*/
|
|
4796
4913
|
async getVersion(id, version) {
|
|
4797
|
-
const envelope = await this.
|
|
4914
|
+
const envelope = await this.strategies.history.getVersionEnvelope(
|
|
4798
4915
|
this.adapter,
|
|
4799
4916
|
this.vault,
|
|
4800
4917
|
this.name,
|
|
@@ -4819,7 +4936,7 @@ var Collection = class {
|
|
|
4819
4936
|
*/
|
|
4820
4937
|
async diff(id, versionA, versionB) {
|
|
4821
4938
|
const recordA = versionA === 0 ? null : await this.resolveVersion(id, versionA);
|
|
4822
|
-
return this.
|
|
4939
|
+
return this.strategies.history.diff(recordA, versionB === void 0 || versionB === 0 ? versionB === 0 ? null : await this.resolveCurrentOrVersion(id) : await this.resolveVersion(id, versionB));
|
|
4823
4940
|
}
|
|
4824
4941
|
/** Resolve a version: try history first, then check if it's the current version. */
|
|
4825
4942
|
async resolveVersion(id, version) {
|
|
@@ -4836,7 +4953,7 @@ var Collection = class {
|
|
|
4836
4953
|
}
|
|
4837
4954
|
/** Prune history entries for a record (or all records if id is undefined). */
|
|
4838
4955
|
async pruneRecordHistory(id, options) {
|
|
4839
|
-
const pruned = await this.
|
|
4956
|
+
const pruned = await this.strategies.history.pruneHistory(
|
|
4840
4957
|
this.adapter,
|
|
4841
4958
|
this.vault,
|
|
4842
4959
|
this.name,
|
|
@@ -4855,7 +4972,7 @@ var Collection = class {
|
|
|
4855
4972
|
}
|
|
4856
4973
|
/** Clear all history for this collection (or a specific record). */
|
|
4857
4974
|
async clearHistory(id) {
|
|
4858
|
-
return this.
|
|
4975
|
+
return this.strategies.history.clearHistory(this.adapter, this.vault, this.name, id);
|
|
4859
4976
|
}
|
|
4860
4977
|
// ─── Core Methods ─────────────────────────────────────────────
|
|
4861
4978
|
/**
|
|
@@ -5277,7 +5394,7 @@ var Collection = class {
|
|
|
5277
5394
|
* vault-shared `_blob` DEK (enabling cross-collection deduplication).
|
|
5278
5395
|
*/
|
|
5279
5396
|
blob(id) {
|
|
5280
|
-
return this.
|
|
5397
|
+
return this.strategies.blob.openSlot({
|
|
5281
5398
|
store: this.adapter,
|
|
5282
5399
|
vault: this.vault,
|
|
5283
5400
|
collection: this.name,
|
|
@@ -5598,23 +5715,23 @@ var Collection = class {
|
|
|
5598
5715
|
// ─── Hierarchical Access ──────────────────────────
|
|
5599
5716
|
/** tier-aware put — gated behind `tiersStrategy: withTiers()`. `searchResidue: true` = stuck search compensation (#774, mirroring #764's elevate/demote posture); the write itself always completes. */
|
|
5600
5717
|
putAtTier(id, record, tier, opts) {
|
|
5601
|
-
return this.
|
|
5718
|
+
return this.strategies.tiers.putAtTier(this.tiersContext(), id, record, tier, opts);
|
|
5602
5719
|
}
|
|
5603
5720
|
/** tier-aware get — gated behind `tiersStrategy: withTiers()`. */
|
|
5604
5721
|
getAtTier(id) {
|
|
5605
|
-
return this.
|
|
5722
|
+
return this.strategies.tiers.getAtTier(this.tiersContext(), id);
|
|
5606
5723
|
}
|
|
5607
5724
|
/** list ids grouped by the caller's readability — gated behind `withTiers()`. */
|
|
5608
5725
|
listAtTier() {
|
|
5609
|
-
return this.
|
|
5726
|
+
return this.strategies.tiers.listAtTier(this.tiersContext());
|
|
5610
5727
|
}
|
|
5611
5728
|
/** elevate a record to a higher tier — gated behind `withTiers()`. `searchResidue: true` = stuck search compensation (#764); the move itself always completes. */
|
|
5612
5729
|
elevate(id, toTier) {
|
|
5613
|
-
return this.
|
|
5730
|
+
return this.strategies.tiers.elevate(this.tiersContext(), id, toTier);
|
|
5614
5731
|
}
|
|
5615
5732
|
/** demote a record to a lower tier — gated behind `withTiers()`. Same `searchResidue` posture as {@link elevate} (#764). */
|
|
5616
5733
|
demote(id, toTier) {
|
|
5617
|
-
return this.
|
|
5734
|
+
return this.strategies.tiers.demote(this.tiersContext(), id, toTier);
|
|
5618
5735
|
}
|
|
5619
5736
|
/**
|
|
5620
5737
|
* Emit a cross-tier access event. The subscriber sink stays collection-resident (it captures `onCrossTierAccess`); the tiers module reaches it via the {@link TiersContext.emitCrossTierEvent} callback.
|
|
@@ -5675,16 +5792,16 @@ var Collection = class {
|
|
|
5675
5792
|
},
|
|
5676
5793
|
syncIndexes: (id, rec, version, priorEnvelope) => syncTierIndexes(this.indexingContext(), id, rec, version, priorEnvelope),
|
|
5677
5794
|
syncSearch: (id, rec, version) => syncTierSearch(this.searchContext(), id, rec, version),
|
|
5678
|
-
syncHistory: async (id, fromDek, toDek) => this.
|
|
5795
|
+
syncHistory: async (id, fromDek, toDek) => this.strategies.history.rewrapHistory(this.adapter, this.vault, this.name, id, fromDek, toDek, await this.getDEK(this.name)),
|
|
5679
5796
|
saveHistorySnapshot: async (id, envelope) => {
|
|
5680
5797
|
if (this.historyConfig.enabled === false) return;
|
|
5681
|
-
await this.
|
|
5798
|
+
await this.strategies.history.saveHistory(this.adapter, this.vault, this.name, id, envelope);
|
|
5682
5799
|
this.emitter.emit("history:save", { vault: this.vault, collection: this.name, id, version: envelope._v });
|
|
5683
|
-
if (this.historyConfig.maxVersions) await this.
|
|
5800
|
+
if (this.historyConfig.maxVersions) await this.strategies.history.pruneHistory(this.adapter, this.vault, this.name, id, { keepVersions: this.historyConfig.maxVersions });
|
|
5684
5801
|
},
|
|
5685
|
-
historyEnabled: this.historyConfig.enabled !== false && this.
|
|
5802
|
+
historyEnabled: this.historyConfig.enabled !== false && this.strategies.history !== NO_HISTORY,
|
|
5686
5803
|
// #728/#737: lets putAtTier skip decrypting `existing` when no real history strategy is wired
|
|
5687
|
-
syncBlobs: (id, fromTier, toTier) => this.
|
|
5804
|
+
syncBlobs: (id, fromTier, toTier) => this.strategies.blob !== NO_BLOBS ? this.blob(id).syncTierMove(fromTier, toTier, this.blobTierPolicy) : Promise.resolve(),
|
|
5688
5805
|
// #724 I1: gate on blob storage enabled (not on declared blobFields) so undeclared-field blobs still rehome; #746: syncTierMove mints/resumes the rehome journal marker; self-no-ops on an empty slot map
|
|
5689
5806
|
syncLedger: async (id) => {
|
|
5690
5807
|
await this.ledger?.purgeRecordDeltas(this.name, id);
|
|
@@ -6012,46 +6129,6 @@ var DeferredNumberingStore = class {
|
|
|
6012
6129
|
}
|
|
6013
6130
|
};
|
|
6014
6131
|
|
|
6015
|
-
// src/with-fork/shadow/strategy.ts
|
|
6016
|
-
var NOT_ENABLED2 = new Error(
|
|
6017
|
-
'VaultFrame requires the shadow strategy. Import `{ withShadow }` from "@noy-db/hub/shadow" and pass it to `createNoydb({ shadowStrategy: withShadow() })`.'
|
|
6018
|
-
);
|
|
6019
|
-
var NO_SHADOW = {
|
|
6020
|
-
buildFrame() {
|
|
6021
|
-
throw NOT_ENABLED2;
|
|
6022
|
-
}
|
|
6023
|
-
};
|
|
6024
|
-
|
|
6025
|
-
// src/with-audit/consent/strategy.ts
|
|
6026
|
-
var NO_CONSENT = {
|
|
6027
|
-
async write() {
|
|
6028
|
-
},
|
|
6029
|
-
async read() {
|
|
6030
|
-
return [];
|
|
6031
|
-
}
|
|
6032
|
-
};
|
|
6033
|
-
|
|
6034
|
-
// src/with-audit/periods/strategy.ts
|
|
6035
|
-
var NOT_ENABLED3 = new Error(
|
|
6036
|
-
'Accounting periods require the periods strategy. Import `{ withPeriods }` from "@noy-db/hub/periods" and pass it to `createNoydb({ periodsStrategy: withPeriods() })`.'
|
|
6037
|
-
);
|
|
6038
|
-
var NO_PERIODS = {
|
|
6039
|
-
async loadPeriods() {
|
|
6040
|
-
return [];
|
|
6041
|
-
},
|
|
6042
|
-
async chainAnchor() {
|
|
6043
|
-
return { priorPeriodHash: "" };
|
|
6044
|
-
},
|
|
6045
|
-
assertTsWritable() {
|
|
6046
|
-
},
|
|
6047
|
-
validatePeriodName() {
|
|
6048
|
-
throw NOT_ENABLED3;
|
|
6049
|
-
},
|
|
6050
|
-
async appendPeriodLedgerEntry() {
|
|
6051
|
-
throw NOT_ENABLED3;
|
|
6052
|
-
}
|
|
6053
|
-
};
|
|
6054
|
-
|
|
6055
6132
|
// src/with-audit/periods/vault-facade.ts
|
|
6056
6133
|
var VaultPeriods = class {
|
|
6057
6134
|
constructor(deps) {
|
|
@@ -8053,36 +8130,22 @@ var Vault = class {
|
|
|
8053
8130
|
syncAdapter;
|
|
8054
8131
|
getPurgeableTargets;
|
|
8055
8132
|
historyConfig;
|
|
8056
|
-
/**
|
|
8057
|
-
*
|
|
8058
|
-
|
|
8133
|
+
/**
|
|
8134
|
+
* Every opt-in service, resolved once by `createNoydb` (#838). Shared by
|
|
8135
|
+
* reference with the owning `Noydb` and with every `Collection` this vault
|
|
8136
|
+
* opens, so all three always agree about which services are enabled.
|
|
8137
|
+
*/
|
|
8138
|
+
strategies;
|
|
8059
8139
|
objectStore;
|
|
8060
|
-
/** Cold-storage archival strategy (the archive target store). */
|
|
8061
|
-
archiveStrategy;
|
|
8062
8140
|
/** Per-collection record archival policies. Indexed by collection name. */
|
|
8063
8141
|
archiveRegistry = /* @__PURE__ */ new Map();
|
|
8064
|
-
indexStrategy;
|
|
8065
|
-
lazyStrategy;
|
|
8066
|
-
aggregateStrategy;
|
|
8067
|
-
crdtStrategy;
|
|
8068
|
-
tiersStrategy;
|
|
8069
|
-
searchStrategy;
|
|
8070
|
-
/** Cargo (partition extraction) strategy — `NO_CARGO` (throwing) unless `withCargo()` was passed.
|
|
8071
|
-
* Public so the `extractPartition` free function (which takes a `Vault`) routes through it. */
|
|
8072
|
-
cargoStrategy;
|
|
8073
|
-
brokerStrategy;
|
|
8074
|
-
sealedRecordStrategy;
|
|
8075
|
-
portabilityStrategy;
|
|
8076
|
-
sequenceStrategy;
|
|
8077
|
-
consentStrategy;
|
|
8078
8142
|
periods;
|
|
8079
8143
|
linksEnforcer;
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
classifiedStrategy;
|
|
8144
|
+
/** Cargo (partition extraction) strategy — `NO_CARGO` (throwing) unless `withCargo()` was passed.
|
|
8145
|
+
* Public so the `extractPartition` free function (which takes a `Vault`) routes through it. */
|
|
8146
|
+
get cargoStrategy() {
|
|
8147
|
+
return this.strategies.cargo;
|
|
8148
|
+
}
|
|
8086
8149
|
/** Per-vault guard registry; `null` until `_initGuards()` runs (or for vaults that never register
|
|
8087
8150
|
* one) — the runtime class is dynamic-imported on demand to keep it out of the floor bundle. */
|
|
8088
8151
|
guardRegistry = null;
|
|
@@ -8264,23 +8327,10 @@ var Vault = class {
|
|
|
8264
8327
|
this.onRegisterConflictResolver = opts.onRegisterConflictResolver;
|
|
8265
8328
|
this.syncAdapter = opts.syncAdapter;
|
|
8266
8329
|
this.getPurgeableTargets = opts.getPurgeableTargets ?? (() => []);
|
|
8267
|
-
this.
|
|
8330
|
+
this.strategies = opts.strategies;
|
|
8268
8331
|
this.objectStore = opts.objectStore;
|
|
8269
|
-
this.archiveStrategy = opts.archiveStrategy;
|
|
8270
|
-
this.indexStrategy = opts.indexStrategy;
|
|
8271
|
-
this.lazyStrategy = opts.lazyStrategy;
|
|
8272
|
-
this.aggregateStrategy = opts.aggregateStrategy;
|
|
8273
|
-
this.crdtStrategy = opts.crdtStrategy;
|
|
8274
|
-
this.tiersStrategy = opts.tiersStrategy;
|
|
8275
|
-
this.searchStrategy = opts.searchStrategy;
|
|
8276
|
-
this.cargoStrategy = opts.cargoStrategy ?? NO_CARGO;
|
|
8277
|
-
this.brokerStrategy = opts.brokerStrategy ?? NO_BROKER;
|
|
8278
|
-
this.sealedRecordStrategy = opts.sealedRecordStrategy ?? NO_SEALED_RECORD;
|
|
8279
|
-
this.portabilityStrategy = opts.portabilityStrategy ?? NO_PORTABILITY;
|
|
8280
|
-
this.sequenceStrategy = opts.sequenceStrategy ?? NO_SEQUENCE;
|
|
8281
|
-
this.consentStrategy = opts.consentStrategy ?? NO_CONSENT;
|
|
8282
8332
|
this.periods = new VaultPeriods({
|
|
8283
|
-
strategy:
|
|
8333
|
+
strategy: this.strategies.periods,
|
|
8284
8334
|
adapter: this.adapter,
|
|
8285
8335
|
vault: this.name,
|
|
8286
8336
|
encrypted: this.encrypted,
|
|
@@ -8305,12 +8355,6 @@ var Vault = class {
|
|
|
8305
8355
|
getActiveTxContext: () => this.noydb._activeTxContextOrNull,
|
|
8306
8356
|
emitter: this.emitter
|
|
8307
8357
|
});
|
|
8308
|
-
this.shadowStrategy = opts.shadowStrategy ?? NO_SHADOW;
|
|
8309
|
-
this.historyStrategy = opts.historyStrategy ?? NO_HISTORY;
|
|
8310
|
-
this.forgetStrategy = opts.forgetStrategy ?? NO_FORGET;
|
|
8311
|
-
this.i18nStrategy = opts.i18nStrategy ?? NO_I18N;
|
|
8312
|
-
this.syncStrategy = opts.syncStrategy ?? NO_SYNC;
|
|
8313
|
-
this.classifiedStrategy = opts.classifiedStrategy ?? NO_CLASSIFIED;
|
|
8314
8358
|
this.graph = new ViaGraph();
|
|
8315
8359
|
void opts.guardStrategies;
|
|
8316
8360
|
this.historyConfig = opts.historyConfig ?? { enabled: true };
|
|
@@ -8325,19 +8369,19 @@ var Vault = class {
|
|
|
8325
8369
|
getDEK: (collection) => this.getDEK(collection),
|
|
8326
8370
|
role: () => this.keyring.role,
|
|
8327
8371
|
getRawRecord: async (collection, recId) => await this.collection(collection).get(recId, { locale: "raw" })
|
|
8328
|
-
},
|
|
8372
|
+
}, this.strategies.attestation);
|
|
8329
8373
|
this.user = this.noydb.userApiFactory({
|
|
8330
8374
|
adapter: this.adapter,
|
|
8331
8375
|
vaultName: this.name,
|
|
8332
8376
|
writerKeyringId: this.keyring.userId,
|
|
8333
8377
|
getDek: () => this.getDEK(USER_ENVELOPE_COLLECTION),
|
|
8334
8378
|
checkGate: (gate, presented) => this.noydb.checkGate(this.name, gate, presented),
|
|
8335
|
-
exportAccessible: (opts2) => this.
|
|
8336
|
-
unilateralWithdraw: (opts2) => this.
|
|
8337
|
-
requestWithdraw: (opts2) => this.
|
|
8338
|
-
listWithdrawals: (opts2) => this.
|
|
8339
|
-
approveWithdraw: (requestId, opts2) => this.
|
|
8340
|
-
rejectWithdraw: (requestId, opts2) => this.
|
|
8379
|
+
exportAccessible: (opts2) => this.strategies.portability.exportAccessibleData(this, opts2),
|
|
8380
|
+
unilateralWithdraw: (opts2) => this.strategies.portability.withdrawAccessibleData(this, opts2),
|
|
8381
|
+
requestWithdraw: (opts2) => this.strategies.portability.requestWithdrawal(this, opts2),
|
|
8382
|
+
listWithdrawals: (opts2) => this.strategies.portability.listWithdrawalRequests(this, opts2),
|
|
8383
|
+
approveWithdraw: (requestId, opts2) => this.strategies.portability.approveWithdrawal(this, requestId, opts2),
|
|
8384
|
+
rejectWithdraw: (requestId, opts2) => this.strategies.portability.rejectWithdrawal(this, requestId, opts2)
|
|
8341
8385
|
});
|
|
8342
8386
|
this.custody = new CustodyApi(
|
|
8343
8387
|
(options, factors) => this.noydb.grantCustodian(this.name, options, factors),
|
|
@@ -8395,7 +8439,7 @@ var Vault = class {
|
|
|
8395
8439
|
* dispatch reads/writes — from this vault's OWN privates, rather than passing `this` itself. */
|
|
8396
8440
|
_viaReconcileCtx() {
|
|
8397
8441
|
return {
|
|
8398
|
-
i18nStrategy: this.
|
|
8442
|
+
i18nStrategy: this.strategies.i18n,
|
|
8399
8443
|
locale: this.locale,
|
|
8400
8444
|
translateText: this.translateText,
|
|
8401
8445
|
i18nFieldRegistry: this.i18nFieldRegistry,
|
|
@@ -8436,7 +8480,7 @@ var Vault = class {
|
|
|
8436
8480
|
this.satelliteRegistry = declareSatellite({
|
|
8437
8481
|
adapter: this.adapter,
|
|
8438
8482
|
vaultName: this.name,
|
|
8439
|
-
forgetSubjects: this.
|
|
8483
|
+
forgetSubjects: this.strategies.forget.subjects,
|
|
8440
8484
|
getDEK: this.getDEK,
|
|
8441
8485
|
getBaseSchema: (base) => this.collectionCache.get(base)?.getSchema(),
|
|
8442
8486
|
getBaseCrdt: (base) => this.collectionCache.get(base)?.getConfig()?.crdt,
|
|
@@ -8556,22 +8600,9 @@ var Vault = class {
|
|
|
8556
8600
|
// #693: re-create gate fallback
|
|
8557
8601
|
historyConfig: effectiveHistoryConfig,
|
|
8558
8602
|
historyConfigExplicit: options?.historyConfig !== void 0,
|
|
8559
|
-
// thread the vault-wide blob strategy into every
|
|
8560
|
-
// collection. `undefined` is intentionally preserved so the
|
|
8561
|
-
// Collection constructor uses its NO_BLOBS default.
|
|
8562
|
-
...this.blobStrategy !== void 0 ? { blobStrategy: this.blobStrategy } : {},
|
|
8563
8603
|
...this.objectStore !== void 0 ? { objectStore: this.objectStore } : {},
|
|
8564
8604
|
...options?.blobFields !== void 0 ? { blobFields: options.blobFields } : {},
|
|
8565
|
-
|
|
8566
|
-
...this.lazyStrategy !== void 0 ? { lazyStrategy: this.lazyStrategy } : {},
|
|
8567
|
-
...this.aggregateStrategy !== void 0 ? { aggregateStrategy: this.aggregateStrategy } : {},
|
|
8568
|
-
...this.crdtStrategy !== void 0 ? { crdtStrategy: this.crdtStrategy } : {},
|
|
8569
|
-
...this.tiersStrategy !== void 0 ? { tiersStrategy: this.tiersStrategy } : {},
|
|
8570
|
-
...this.searchStrategy !== void 0 ? { searchStrategy: this.searchStrategy } : {},
|
|
8571
|
-
historyStrategy: this.historyStrategy,
|
|
8572
|
-
i18nStrategy: this.i18nStrategy,
|
|
8573
|
-
syncStrategy: this.syncStrategy,
|
|
8574
|
-
classifiedStrategy: this.classifiedStrategy,
|
|
8605
|
+
strategies: this.strategies,
|
|
8575
8606
|
// Per-collection ledger opt-out: when this collection sets
|
|
8576
8607
|
// `historyConfig.ledger: false`, withhold the ledger reference so all
|
|
8577
8608
|
// four `if (this.ledger)` append sites in Collection no-op. The chain
|
|
@@ -8629,7 +8660,7 @@ var Vault = class {
|
|
|
8629
8660
|
collOpts.sensitive = options.sensitive;
|
|
8630
8661
|
}
|
|
8631
8662
|
if (options?.perRecordKeys !== void 0) collOpts.perRecordKeys = options.perRecordKeys;
|
|
8632
|
-
const subjectKey = this.
|
|
8663
|
+
const subjectKey = this.strategies.forget.subjects[collectionName];
|
|
8633
8664
|
if (subjectKey !== void 0) {
|
|
8634
8665
|
if (options?.perRecordKeys === false) {
|
|
8635
8666
|
console.warn(
|
|
@@ -9010,7 +9041,7 @@ var Vault = class {
|
|
|
9010
9041
|
const values = getAtPath(obj, field);
|
|
9011
9042
|
for (const value of values) {
|
|
9012
9043
|
if (value === void 0 || value === null) continue;
|
|
9013
|
-
this.
|
|
9044
|
+
this.strategies.i18n.validateI18nTextValue(value, field, descriptor);
|
|
9014
9045
|
}
|
|
9015
9046
|
}
|
|
9016
9047
|
}
|
|
@@ -9051,7 +9082,7 @@ var Vault = class {
|
|
|
9051
9082
|
this.reservedLookupCollections.set(dictCollectionName(name), name);
|
|
9052
9083
|
let handle = this.dictionaryCache.get(name);
|
|
9053
9084
|
if (!handle) {
|
|
9054
|
-
handle = this.
|
|
9085
|
+
handle = this.strategies.i18n.buildDictionaryHandle({
|
|
9055
9086
|
adapter: this.adapter,
|
|
9056
9087
|
compartmentName: this.name,
|
|
9057
9088
|
dictionaryName: name,
|
|
@@ -9264,7 +9295,7 @@ var Vault = class {
|
|
|
9264
9295
|
};
|
|
9265
9296
|
}
|
|
9266
9297
|
if (!this.sequenceStore) {
|
|
9267
|
-
this.sequenceStore = this.
|
|
9298
|
+
this.sequenceStore = this.strategies.sequence.createStore({
|
|
9268
9299
|
adapter: this.adapter,
|
|
9269
9300
|
vault: this.name,
|
|
9270
9301
|
encrypted: this.encrypted,
|
|
@@ -9362,7 +9393,7 @@ var Vault = class {
|
|
|
9362
9393
|
return runListArchived(this._archiveContext(), collection);
|
|
9363
9394
|
}
|
|
9364
9395
|
_archiveContext() {
|
|
9365
|
-
const strategy = this.
|
|
9396
|
+
const strategy = this.strategies.archive;
|
|
9366
9397
|
if (!strategy) {
|
|
9367
9398
|
throw new Error(
|
|
9368
9399
|
"vault.archive/restore/listArchived require `archiveStrategy: withArchive({ store })` in createNoydb"
|
|
@@ -9529,7 +9560,7 @@ var Vault = class {
|
|
|
9529
9560
|
*/
|
|
9530
9561
|
getLedgerOrNull() {
|
|
9531
9562
|
if (!this.ledgerStore) {
|
|
9532
|
-
this.ledgerStore = this.
|
|
9563
|
+
this.ledgerStore = this.strategies.history.buildLedger({
|
|
9533
9564
|
adapter: this.adapter,
|
|
9534
9565
|
vault: this.name,
|
|
9535
9566
|
encrypted: this.encrypted,
|
|
@@ -9554,7 +9585,7 @@ var Vault = class {
|
|
|
9554
9585
|
* number of distinct subjects re-indexed.
|
|
9555
9586
|
*/
|
|
9556
9587
|
async rebuildSubjectIndex() {
|
|
9557
|
-
if (Object.keys(this.
|
|
9588
|
+
if (Object.keys(this.strategies.forget.subjects).length === 0) {
|
|
9558
9589
|
throw new ForgetStrategyNotConfiguredError();
|
|
9559
9590
|
}
|
|
9560
9591
|
return rebuildSubjectIndex(
|
|
@@ -9562,7 +9593,7 @@ var Vault = class {
|
|
|
9562
9593
|
this.name,
|
|
9563
9594
|
this.getDEK,
|
|
9564
9595
|
this.encrypted,
|
|
9565
|
-
this.
|
|
9596
|
+
this.strategies.forget.subjects,
|
|
9566
9597
|
async (collectionName, id, env) => {
|
|
9567
9598
|
const coll = this.collection(collectionName);
|
|
9568
9599
|
return coll._decodeEnvelope(env, id);
|
|
@@ -9587,7 +9618,7 @@ var Vault = class {
|
|
|
9587
9618
|
* @throws ForgetStrategyNotConfiguredError when no `withForgetCascade` was set.
|
|
9588
9619
|
*/
|
|
9589
9620
|
async forget(subjectId) {
|
|
9590
|
-
if (Object.keys(this.
|
|
9621
|
+
if (Object.keys(this.strategies.forget.subjects).length === 0) {
|
|
9591
9622
|
throw new ForgetStrategyNotConfiguredError();
|
|
9592
9623
|
}
|
|
9593
9624
|
const ledger = this.getLedgerOrNull();
|
|
@@ -9609,17 +9640,17 @@ var Vault = class {
|
|
|
9609
9640
|
const sealedResidue = [];
|
|
9610
9641
|
const indexResidue = [];
|
|
9611
9642
|
const ledgerDeltaResidue = [];
|
|
9612
|
-
const blobsEnabled = this.
|
|
9643
|
+
const blobsEnabled = this.strategies.blob !== NO_BLOBS;
|
|
9613
9644
|
const actor = this.keyring.userId;
|
|
9614
9645
|
const fanoutStats = { recordsErased: 0, aggregatesRecomputed: 0, residueFrozen: [], lookupReferencesCascaded: 0, lookupReferencesNullified: 0, lookupReferencesResidue: [], derivedResidueUndecodable: [], derivedResidueDeclined: [] };
|
|
9615
9646
|
const { partitionSealedCekKeys, shouldSkipBlobScan, bumpResidueCount, residueNoticesFromMap } = await import("./purge-scope-FGNNLWHD.js");
|
|
9616
|
-
const scopedPurge = this.
|
|
9647
|
+
const scopedPurge = this.strategies.forget.scopedPurge === true;
|
|
9617
9648
|
const sealedCekScopedSkipped = /* @__PURE__ */ new Map();
|
|
9618
9649
|
const blobScopedSkipped = /* @__PURE__ */ new Map();
|
|
9619
9650
|
for (const ref2 of allRefs) {
|
|
9620
9651
|
const coll = this.collection(ref2.collection);
|
|
9621
9652
|
const satelliteOf = ref2.satelliteOf;
|
|
9622
|
-
const perRecordKeys = this.
|
|
9653
|
+
const perRecordKeys = this.strategies.forget.subjects[satelliteOf ?? ref2.collection] !== void 0;
|
|
9623
9654
|
const lookupCompareKeys = await this.linksEnforcer.checkLookupRefsRestrict(this.graph, ref2.collection, ref2.collection, ref2.id);
|
|
9624
9655
|
const live = await this.adapter.get(this.name, ref2.collection, ref2.id);
|
|
9625
9656
|
if (perRecordKeys && live && live._data && !hasPerRecordKey(live)) {
|
|
@@ -9679,7 +9710,7 @@ var Vault = class {
|
|
|
9679
9710
|
collections.add(ref2.collection);
|
|
9680
9711
|
await forgetDerivedFanout(this, { collection: ref2.collection, id: ref2.id }, live, fanoutStats, lookupCompareKeys);
|
|
9681
9712
|
}
|
|
9682
|
-
historyVersionsShredded += await this.
|
|
9713
|
+
historyVersionsShredded += await this.strategies.history.tombstoneHistory(
|
|
9683
9714
|
this.adapter,
|
|
9684
9715
|
this.name,
|
|
9685
9716
|
ref2.collection,
|
|
@@ -9809,7 +9840,7 @@ var Vault = class {
|
|
|
9809
9840
|
* `<collection>/<id>/<pid>` key the delivery envelope was written under.
|
|
9810
9841
|
*/
|
|
9811
9842
|
async sealRecordToHost(collection, id, hostSealer, opts) {
|
|
9812
|
-
return this.
|
|
9843
|
+
return this.strategies.sealedRecord.sealRecordToHost(this._sealingContext(), collection, id, hostSealer, opts);
|
|
9813
9844
|
}
|
|
9814
9845
|
/**
|
|
9815
9846
|
* Revoke a sealed-CEK grant. **Default is SOFT**: deletes the `pid` delivery
|
|
@@ -9819,7 +9850,7 @@ var Vault = class {
|
|
|
9819
9850
|
* longer open the record. See `revokeSealedRecord` in `record-keys/sealing.ts`.
|
|
9820
9851
|
*/
|
|
9821
9852
|
async revokeSealedRecord(collection, id, pid, opts) {
|
|
9822
|
-
return this.
|
|
9853
|
+
return this.strategies.sealedRecord.revokeSealedRecord(this._sealingContext(), collection, id, pid, opts);
|
|
9823
9854
|
}
|
|
9824
9855
|
/**
|
|
9825
9856
|
* HARD-rotate a record's CEK: decrypt the live body under the old CEK,
|
|
@@ -9839,7 +9870,7 @@ var Vault = class {
|
|
|
9839
9870
|
* @throws {@link RecordCekNotFoundError} if the record is missing or has no `_cek`.
|
|
9840
9871
|
*/
|
|
9841
9872
|
async rotateRecordCek(collection, id) {
|
|
9842
|
-
return this.
|
|
9873
|
+
return this.strategies.sealedRecord.rotateRecordCek(this._sealingContext(), collection, id);
|
|
9843
9874
|
}
|
|
9844
9875
|
/**
|
|
9845
9876
|
* Build the {@link SealingContext} the record-keys grantor functions need:
|
|
@@ -10005,14 +10036,14 @@ var Vault = class {
|
|
|
10005
10036
|
if (!reg) {
|
|
10006
10037
|
throw new Error(`refreshView: no MV registered with name "${name}"`);
|
|
10007
10038
|
}
|
|
10008
|
-
const { MaterializedViewExecutor } = await import("./executor-
|
|
10039
|
+
const { MaterializedViewExecutor } = await import("./executor-YORMIBWV.js");
|
|
10009
10040
|
const result = await MaterializedViewExecutor.refresh(reg, {
|
|
10010
10041
|
getCollection: (n) => this.collection(n),
|
|
10011
10042
|
getActiveTxContext: () => this.noydb._activeTxContextOrNull,
|
|
10012
10043
|
getQueryContext: () => this,
|
|
10013
10044
|
dispatchCtx: this._dispatchCtx({ collection: name, id: "refreshView" })
|
|
10014
10045
|
});
|
|
10015
|
-
const { clearMVStaleFully } = await import("./stale-
|
|
10046
|
+
const { clearMVStaleFully } = await import("./stale-4UNPHWOU.js");
|
|
10016
10047
|
await clearMVStaleFully(this.adapter, this.name, registry, name);
|
|
10017
10048
|
return result;
|
|
10018
10049
|
}
|
|
@@ -10146,7 +10177,7 @@ var Vault = class {
|
|
|
10146
10177
|
*/
|
|
10147
10178
|
at(timestamp) {
|
|
10148
10179
|
const iso = timestamp instanceof Date ? timestamp.toISOString() : timestamp;
|
|
10149
|
-
return this.
|
|
10180
|
+
return this.strategies.history.buildVaultInstant(
|
|
10150
10181
|
{
|
|
10151
10182
|
adapter: this.adapter,
|
|
10152
10183
|
name: this.name,
|
|
@@ -10178,11 +10209,11 @@ var Vault = class {
|
|
|
10178
10209
|
*.
|
|
10179
10210
|
*/
|
|
10180
10211
|
frame() {
|
|
10181
|
-
return this.
|
|
10212
|
+
return this.strategies.shadow.buildFrame(this);
|
|
10182
10213
|
}
|
|
10183
10214
|
/** Credential-broker handle (#479); `NO_BROKER` throws unless `brokerStrategy: withBroker(config)` was passed to createNoydb(). */
|
|
10184
10215
|
broker() {
|
|
10185
|
-
return buildCredentialBrokerHandle(this.
|
|
10216
|
+
return buildCredentialBrokerHandle(this.strategies.broker, this.adapter, this.name, () => this.keyring);
|
|
10186
10217
|
}
|
|
10187
10218
|
/**
|
|
10188
10219
|
* Run `fn` under a consent scope. Every `get` / `put` / `delete`
|
|
@@ -10224,7 +10255,7 @@ var Vault = class {
|
|
|
10224
10255
|
*.
|
|
10225
10256
|
*/
|
|
10226
10257
|
async consentAudit(filter = {}) {
|
|
10227
|
-
return this.
|
|
10258
|
+
return this.strategies.consent.read(this.adapter, this.name, this.encrypted, this.getDEK, filter);
|
|
10228
10259
|
}
|
|
10229
10260
|
/**
|
|
10230
10261
|
* Called by Collection after every access when a consent scope is
|
|
@@ -10235,7 +10266,7 @@ var Vault = class {
|
|
|
10235
10266
|
async _logConsent(op, collection, recordId) {
|
|
10236
10267
|
const ctx = this.consentContext;
|
|
10237
10268
|
if (!ctx) return;
|
|
10238
|
-
await this.
|
|
10269
|
+
await this.strategies.consent.write(
|
|
10239
10270
|
this.adapter,
|
|
10240
10271
|
this.name,
|
|
10241
10272
|
this.encrypted,
|
|
@@ -10714,7 +10745,7 @@ var Vault = class {
|
|
|
10714
10745
|
vault: this.name,
|
|
10715
10746
|
userId: () => this.keyring.userId,
|
|
10716
10747
|
getLedgerOrNull: () => this.getLedgerOrNull(),
|
|
10717
|
-
envelopePayloadHash: (envelope) => this.
|
|
10748
|
+
envelopePayloadHash: (envelope) => this.strategies.history.envelopePayloadHash(envelope),
|
|
10718
10749
|
reloadKeyringAndRebuildDEK: async () => {
|
|
10719
10750
|
if (this.reloadKeyring) {
|
|
10720
10751
|
this.keyring = await this.reloadKeyring();
|
|
@@ -11399,25 +11430,6 @@ var QuickUnlockStore = class {
|
|
|
11399
11430
|
}
|
|
11400
11431
|
};
|
|
11401
11432
|
|
|
11402
|
-
// src/with-fork/snapshots/strategy.ts
|
|
11403
|
-
var NOT_ENABLED4 = new Error(
|
|
11404
|
-
'Snapshots require the snapshot strategy. Import `{ withSnapshots }` from "@noy-db/hub/snapshots" and pass it to `createNoydb({ snapshotStrategy: withSnapshots({ store }) })`.'
|
|
11405
|
-
);
|
|
11406
|
-
var NO_SNAPSHOTS = {
|
|
11407
|
-
async snapshot() {
|
|
11408
|
-
throw NOT_ENABLED4;
|
|
11409
|
-
},
|
|
11410
|
-
async listSnapshots() {
|
|
11411
|
-
throw NOT_ENABLED4;
|
|
11412
|
-
},
|
|
11413
|
-
async restoreSnapshot() {
|
|
11414
|
-
throw NOT_ENABLED4;
|
|
11415
|
-
},
|
|
11416
|
-
async autoSnapshot() {
|
|
11417
|
-
throw NOT_ENABLED4;
|
|
11418
|
-
}
|
|
11419
|
-
};
|
|
11420
|
-
|
|
11421
11433
|
// src/with-fork/snapshots/scheduler.ts
|
|
11422
11434
|
var SnapshotScheduler = class {
|
|
11423
11435
|
policy;
|
|
@@ -11618,19 +11630,6 @@ var NoydbSnapshots = class {
|
|
|
11618
11630
|
}
|
|
11619
11631
|
};
|
|
11620
11632
|
|
|
11621
|
-
// src/with-commit/tx/strategy.ts
|
|
11622
|
-
var NOT_ENABLED5 = new Error(
|
|
11623
|
-
'Multi-record transactions require the tx strategy. Import `{ withTransactions }` from "@noy-db/hub/tx" and pass it to `createNoydb({ txStrategy: withTransactions() })`.'
|
|
11624
|
-
);
|
|
11625
|
-
var NO_TX = {
|
|
11626
|
-
async runTransaction(_db, _fn, _options, _txInvariants) {
|
|
11627
|
-
throw NOT_ENABLED5;
|
|
11628
|
-
},
|
|
11629
|
-
async runDryRun() {
|
|
11630
|
-
throw NOT_ENABLED5;
|
|
11631
|
-
}
|
|
11632
|
-
};
|
|
11633
|
-
|
|
11634
11633
|
// src/kernel/memory-store.ts
|
|
11635
11634
|
function memoryStore() {
|
|
11636
11635
|
const store = /* @__PURE__ */ new Map();
|
|
@@ -11714,23 +11713,6 @@ function memoryStore() {
|
|
|
11714
11713
|
};
|
|
11715
11714
|
}
|
|
11716
11715
|
|
|
11717
|
-
// src/with-party/session/strategy.ts
|
|
11718
|
-
function notEnabled3(op) {
|
|
11719
|
-
return new Error(
|
|
11720
|
-
`${op} requires the session strategy. Import \`{ withSession }\` from "@noy-db/hub/session" and pass it to \`createNoydb({ sessionStrategy: withSession() })\`.`
|
|
11721
|
-
);
|
|
11722
|
-
}
|
|
11723
|
-
var NO_SESSION = {
|
|
11724
|
-
validateSessionPolicy() {
|
|
11725
|
-
throw notEnabled3("sessionPolicy");
|
|
11726
|
-
},
|
|
11727
|
-
createEnforcer() {
|
|
11728
|
-
throw notEnabled3("session policy enforcement");
|
|
11729
|
-
},
|
|
11730
|
-
revokeAllSessions() {
|
|
11731
|
-
}
|
|
11732
|
-
};
|
|
11733
|
-
|
|
11734
11716
|
// src/with-party/auth-introspection/index.ts
|
|
11735
11717
|
async function describeAuthConfig(store, vault) {
|
|
11736
11718
|
const policy = await loadVaultPolicy(store, vault) ?? defaultPolicySnapshot();
|
|
@@ -12684,21 +12666,22 @@ var Noydb = class {
|
|
|
12684
12666
|
writeRelay;
|
|
12685
12667
|
/** Per-vault policy enforcers. */
|
|
12686
12668
|
policyEnforcers = /* @__PURE__ */ new Map();
|
|
12687
|
-
txStrategy;
|
|
12688
|
-
forgetStrategy;
|
|
12689
12669
|
/**
|
|
12690
|
-
*
|
|
12691
|
-
* `
|
|
12692
|
-
*
|
|
12670
|
+
* Every opt-in service, resolved once (#838). Shared by reference with each
|
|
12671
|
+
* `Vault` this instance opens and, through them, every `Collection` — so
|
|
12672
|
+
* there is exactly one resolution and no construction path can disagree
|
|
12673
|
+
* about which services are enabled (the #834 bug class).
|
|
12693
12674
|
*/
|
|
12694
|
-
|
|
12675
|
+
strategies;
|
|
12695
12676
|
/**
|
|
12696
|
-
* Opt-in
|
|
12697
|
-
* `
|
|
12698
|
-
*
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
12677
|
+
* Opt-in sovereign-custody (FR-6) strategy — `NO_CUSTODY` (throwing) unless
|
|
12678
|
+
* `withCustody()` was passed. Kept as a public accessor because `Vault`
|
|
12679
|
+
* routes `vault.custody.liberate` through `this.noydb.custodyStrategy`.
|
|
12680
|
+
* @internal
|
|
12681
|
+
*/
|
|
12682
|
+
get custodyStrategy() {
|
|
12683
|
+
return this.strategies.custody;
|
|
12684
|
+
}
|
|
12702
12685
|
snapshots;
|
|
12703
12686
|
policyManager;
|
|
12704
12687
|
/** Pre-resolved policy-gate engine function (mirrors `coordinationProvider`/`userApiFactory` above). */
|
|
@@ -12742,14 +12725,9 @@ var Noydb = class {
|
|
|
12742
12725
|
this.userApiFactory = options.userApiFactory;
|
|
12743
12726
|
if (!options.policyFactory || !options.policyCheckGateFn) throw new ValidationError("Noydb must be constructed via createNoydb(), which resolves the default policy service.");
|
|
12744
12727
|
this.policyCheckGate = options.policyCheckGateFn;
|
|
12745
|
-
this.
|
|
12746
|
-
this.forgetStrategy = options.forgetStrategy ?? NO_FORGET;
|
|
12747
|
-
this.custodyStrategy = options.custodyStrategy ?? NO_CUSTODY;
|
|
12748
|
-
this.teamStrategy = options.teamStrategy ?? NO_TEAM;
|
|
12749
|
-
this.sessionStrategy = options.sessionStrategy ?? NO_SESSION;
|
|
12750
|
-
this.syncStrategy = options.syncStrategy ?? NO_SYNC;
|
|
12728
|
+
this.strategies = resolveStrategies(options);
|
|
12751
12729
|
this.snapshots = new NoydbSnapshots({
|
|
12752
|
-
strategy:
|
|
12730
|
+
strategy: this.strategies.snapshot,
|
|
12753
12731
|
user: options.user,
|
|
12754
12732
|
isClosed: () => this.closed,
|
|
12755
12733
|
getVault: (name) => this.vaultCache.get(name),
|
|
@@ -12786,7 +12764,7 @@ var Noydb = class {
|
|
|
12786
12764
|
}
|
|
12787
12765
|
});
|
|
12788
12766
|
if (options.sessionPolicy) {
|
|
12789
|
-
this.
|
|
12767
|
+
this.strategies.session.validateSessionPolicy(options.sessionPolicy);
|
|
12790
12768
|
}
|
|
12791
12769
|
this.#registerGuardGate();
|
|
12792
12770
|
this.#registerPeriodGate();
|
|
@@ -12795,7 +12773,7 @@ var Noydb = class {
|
|
|
12795
12773
|
}
|
|
12796
12774
|
/** @internal — resolved forget strategy (NO_FORGET when not configured). */
|
|
12797
12775
|
get _forgetStrategy() {
|
|
12798
|
-
return this.
|
|
12776
|
+
return this.strategies.forget;
|
|
12799
12777
|
}
|
|
12800
12778
|
// GDPR subject-index maintenance. When `withForgetCascade` declares
|
|
12801
12779
|
// any subject fields, keep the encrypted `_subject_index` in lock-step with
|
|
@@ -12808,7 +12786,7 @@ var Noydb = class {
|
|
|
12808
12786
|
// does NOT) — drop the ref so a deleted record never lingers in the
|
|
12809
12787
|
// index (RISK #2). Without it, forget() would try to shred a ghost.
|
|
12810
12788
|
#registerForgetHooks() {
|
|
12811
|
-
const subjects = this.
|
|
12789
|
+
const subjects = this.strategies.forget.subjects;
|
|
12812
12790
|
if (Object.keys(subjects).length === 0) return;
|
|
12813
12791
|
const subjectFieldFor = (collection) => subjects[collection];
|
|
12814
12792
|
this.writeHooks.onAfterWrite(async (event) => {
|
|
@@ -12997,7 +12975,7 @@ var Noydb = class {
|
|
|
12997
12975
|
if (targets.length > 0) {
|
|
12998
12976
|
const primary = targets.find((t) => t.role === "sync-peer") ?? targets[0];
|
|
12999
12977
|
const effectivePolicy = this.options.syncPolicy ?? primary.policy ?? INDEXED_STORE_POLICY;
|
|
13000
|
-
syncEngine = this.
|
|
12978
|
+
syncEngine = this.strategies.sync.buildSyncEngine({
|
|
13001
12979
|
local: this.options.store,
|
|
13002
12980
|
remote: primary.store,
|
|
13003
12981
|
vault: name,
|
|
@@ -13011,7 +12989,7 @@ var Noydb = class {
|
|
|
13011
12989
|
for (const target of targets) {
|
|
13012
12990
|
if (target === primary) continue;
|
|
13013
12991
|
const targetPolicy = target.policy ?? this.options.syncPolicy ?? INDEXED_STORE_POLICY;
|
|
13014
|
-
const engine = this.
|
|
12992
|
+
const engine = this.strategies.sync.buildSyncEngine({
|
|
13015
12993
|
local: this.options.store,
|
|
13016
12994
|
remote: target.store,
|
|
13017
12995
|
vault: name,
|
|
@@ -13044,31 +13022,14 @@ var Noydb = class {
|
|
|
13044
13022
|
syncAdapter: targets.length > 0 ? targets[0].store : void 0,
|
|
13045
13023
|
getPurgeableTargets: () => targets.filter((t) => t.role === "backup" || t.role === "archive").map((t) => ({ store: t.store, role: t.role, ...t.label !== void 0 ? { label: t.label } : {} })),
|
|
13046
13024
|
historyConfig: this.options.history,
|
|
13047
|
-
|
|
13025
|
+
// #838 — the 21 conditional strategy spreads that used to live here are
|
|
13026
|
+
// one shared reference. This block is where #834's drift happened: a
|
|
13027
|
+
// copy of it silently omitted six strategies, and there was nothing to
|
|
13028
|
+
// catch that. There is no longer a per-service line to omit.
|
|
13029
|
+
strategies: this.strategies,
|
|
13048
13030
|
...this.options.objectStore !== void 0 ? { objectStore: this.options.objectStore } : {},
|
|
13049
|
-
...this.options.archiveStrategy !== void 0 ? { archiveStrategy: this.options.archiveStrategy } : {},
|
|
13050
|
-
...this.options.indexStrategy !== void 0 ? { indexStrategy: this.options.indexStrategy } : {},
|
|
13051
|
-
...this.options.lazyStrategy !== void 0 ? { lazyStrategy: this.options.lazyStrategy } : {},
|
|
13052
|
-
...this.options.aggregateStrategy !== void 0 ? { aggregateStrategy: this.options.aggregateStrategy } : {},
|
|
13053
|
-
...this.options.crdtStrategy !== void 0 ? { crdtStrategy: this.options.crdtStrategy } : {},
|
|
13054
|
-
...this.options.tiersStrategy !== void 0 ? { tiersStrategy: this.options.tiersStrategy } : {},
|
|
13055
|
-
...this.options.searchStrategy !== void 0 ? { searchStrategy: this.options.searchStrategy } : {},
|
|
13056
|
-
...this.options.cargoStrategy !== void 0 ? { cargoStrategy: this.options.cargoStrategy } : {},
|
|
13057
|
-
...this.options.brokerStrategy !== void 0 ? { brokerStrategy: this.options.brokerStrategy } : {},
|
|
13058
|
-
...this.options.consentStrategy !== void 0 ? { consentStrategy: this.options.consentStrategy } : {},
|
|
13059
|
-
...this.options.periodsStrategy !== void 0 ? { periodsStrategy: this.options.periodsStrategy } : {},
|
|
13060
|
-
...this.options.shadowStrategy !== void 0 ? { shadowStrategy: this.options.shadowStrategy } : {},
|
|
13061
|
-
...this.options.historyStrategy !== void 0 ? { historyStrategy: this.options.historyStrategy } : {},
|
|
13062
|
-
...this.options.i18nStrategy !== void 0 ? { i18nStrategy: this.options.i18nStrategy } : {},
|
|
13063
|
-
...this.options.syncStrategy !== void 0 ? { syncStrategy: this.options.syncStrategy } : {},
|
|
13064
13031
|
...this.options.guardStrategies !== void 0 ? { guardStrategies: this.options.guardStrategies } : {},
|
|
13065
13032
|
...this.options.numbering !== void 0 ? { numberingConfigs: this.options.numbering } : {},
|
|
13066
|
-
forgetStrategy: this.forgetStrategy,
|
|
13067
|
-
...this.options.attestationStrategy !== void 0 ? { attestationStrategy: this.options.attestationStrategy } : {},
|
|
13068
|
-
...this.options.classifiedStrategy !== void 0 ? { classifiedStrategy: this.options.classifiedStrategy } : {},
|
|
13069
|
-
...this.options.sealedRecordStrategy !== void 0 ? { sealedRecordStrategy: this.options.sealedRecordStrategy } : {},
|
|
13070
|
-
...this.options.portabilityStrategy !== void 0 ? { portabilityStrategy: this.options.portabilityStrategy } : {},
|
|
13071
|
-
...this.options.sequenceStrategy !== void 0 ? { sequenceStrategy: this.options.sequenceStrategy } : {},
|
|
13072
13033
|
locale: opts?.locale,
|
|
13073
13034
|
...opts?.meta !== void 0 ? { meta: opts.meta } : {},
|
|
13074
13035
|
// Thread the translator hook so Collection.put() can invoke it
|
|
@@ -13105,85 +13066,25 @@ var Noydb = class {
|
|
|
13105
13066
|
this.vaultCache.set(name, comp);
|
|
13106
13067
|
return comp;
|
|
13107
13068
|
}
|
|
13108
|
-
/**
|
|
13069
|
+
/**
|
|
13070
|
+
* Synchronous access to an ALREADY-OPEN vault.
|
|
13071
|
+
*
|
|
13072
|
+
* Returns the instance `openVault()` produced, or throws — it never
|
|
13073
|
+
* constructs. It used to fall back to building a Vault itself (once for
|
|
13074
|
+
* plaintext, once for encrypted-with-cached-keyring), and those copies
|
|
13075
|
+
* drifted from the real open path: the encrypted one silently omitted six
|
|
13076
|
+
* strategies, so a vault reached this way threw `*NotEnabledError` for
|
|
13077
|
+
* services the caller had configured (#834). Both fallbacks also skipped
|
|
13078
|
+
* the async registry init and schema-fence snapshot that `openVault`
|
|
13079
|
+
* performs, which a synchronous method cannot await. One construction
|
|
13080
|
+
* path is the only way that divergence stays fixed.
|
|
13081
|
+
*/
|
|
13109
13082
|
vault(name) {
|
|
13110
13083
|
const cached = this.vaultCache.get(name);
|
|
13111
13084
|
if (cached) return cached;
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13115
|
-
adapter: this.options.store,
|
|
13116
|
-
name,
|
|
13117
|
-
noydb: this,
|
|
13118
|
-
keyring: keyring2,
|
|
13119
|
-
encrypted: false,
|
|
13120
|
-
emitter: this.emitter,
|
|
13121
|
-
historyConfig: this.options.history,
|
|
13122
|
-
...this.options.blobStrategy !== void 0 ? { blobStrategy: this.options.blobStrategy } : {},
|
|
13123
|
-
...this.options.objectStore !== void 0 ? { objectStore: this.options.objectStore } : {},
|
|
13124
|
-
...this.options.archiveStrategy !== void 0 ? { archiveStrategy: this.options.archiveStrategy } : {},
|
|
13125
|
-
...this.options.indexStrategy !== void 0 ? { indexStrategy: this.options.indexStrategy } : {},
|
|
13126
|
-
...this.options.lazyStrategy !== void 0 ? { lazyStrategy: this.options.lazyStrategy } : {},
|
|
13127
|
-
...this.options.aggregateStrategy !== void 0 ? { aggregateStrategy: this.options.aggregateStrategy } : {},
|
|
13128
|
-
...this.options.crdtStrategy !== void 0 ? { crdtStrategy: this.options.crdtStrategy } : {},
|
|
13129
|
-
...this.options.tiersStrategy !== void 0 ? { tiersStrategy: this.options.tiersStrategy } : {},
|
|
13130
|
-
...this.options.searchStrategy !== void 0 ? { searchStrategy: this.options.searchStrategy } : {},
|
|
13131
|
-
...this.options.cargoStrategy !== void 0 ? { cargoStrategy: this.options.cargoStrategy } : {},
|
|
13132
|
-
...this.options.brokerStrategy !== void 0 ? { brokerStrategy: this.options.brokerStrategy } : {},
|
|
13133
|
-
...this.options.consentStrategy !== void 0 ? { consentStrategy: this.options.consentStrategy } : {},
|
|
13134
|
-
...this.options.periodsStrategy !== void 0 ? { periodsStrategy: this.options.periodsStrategy } : {},
|
|
13135
|
-
...this.options.shadowStrategy !== void 0 ? { shadowStrategy: this.options.shadowStrategy } : {},
|
|
13136
|
-
...this.options.historyStrategy !== void 0 ? { historyStrategy: this.options.historyStrategy } : {},
|
|
13137
|
-
...this.options.i18nStrategy !== void 0 ? { i18nStrategy: this.options.i18nStrategy } : {},
|
|
13138
|
-
...this.options.syncStrategy !== void 0 ? { syncStrategy: this.options.syncStrategy } : {},
|
|
13139
|
-
...this.options.guardStrategies !== void 0 ? { guardStrategies: this.options.guardStrategies } : {},
|
|
13140
|
-
...this.options.numbering !== void 0 ? { numberingConfigs: this.options.numbering } : {},
|
|
13141
|
-
forgetStrategy: this.forgetStrategy,
|
|
13142
|
-
...this.options.attestationStrategy !== void 0 ? { attestationStrategy: this.options.attestationStrategy } : {},
|
|
13143
|
-
...this.options.classifiedStrategy !== void 0 ? { classifiedStrategy: this.options.classifiedStrategy } : {},
|
|
13144
|
-
...this.options.sealedRecordStrategy !== void 0 ? { sealedRecordStrategy: this.options.sealedRecordStrategy } : {},
|
|
13145
|
-
...this.options.portabilityStrategy !== void 0 ? { portabilityStrategy: this.options.portabilityStrategy } : {},
|
|
13146
|
-
...this.options.sequenceStrategy !== void 0 ? { sequenceStrategy: this.options.sequenceStrategy } : {}
|
|
13147
|
-
});
|
|
13148
|
-
this.vaultCache.set(name, comp2);
|
|
13149
|
-
return comp2;
|
|
13150
|
-
}
|
|
13151
|
-
const keyring = this.keyringCache.get(name);
|
|
13152
|
-
if (!keyring) {
|
|
13153
|
-
throw new ValidationError(
|
|
13154
|
-
`Vault "${name}" not opened. Use await db.openVault("${name}") first.`
|
|
13155
|
-
);
|
|
13156
|
-
}
|
|
13157
|
-
const comp = new Vault({
|
|
13158
|
-
adapter: this.options.store,
|
|
13159
|
-
name,
|
|
13160
|
-
noydb: this,
|
|
13161
|
-
keyring,
|
|
13162
|
-
encrypted: true,
|
|
13163
|
-
historyConfig: this.options.history,
|
|
13164
|
-
...this.options.blobStrategy !== void 0 ? { blobStrategy: this.options.blobStrategy } : {},
|
|
13165
|
-
...this.options.objectStore !== void 0 ? { objectStore: this.options.objectStore } : {},
|
|
13166
|
-
...this.options.archiveStrategy !== void 0 ? { archiveStrategy: this.options.archiveStrategy } : {},
|
|
13167
|
-
...this.options.indexStrategy !== void 0 ? { indexStrategy: this.options.indexStrategy } : {},
|
|
13168
|
-
...this.options.lazyStrategy !== void 0 ? { lazyStrategy: this.options.lazyStrategy } : {},
|
|
13169
|
-
...this.options.aggregateStrategy !== void 0 ? { aggregateStrategy: this.options.aggregateStrategy } : {},
|
|
13170
|
-
...this.options.crdtStrategy !== void 0 ? { crdtStrategy: this.options.crdtStrategy } : {},
|
|
13171
|
-
...this.options.tiersStrategy !== void 0 ? { tiersStrategy: this.options.tiersStrategy } : {},
|
|
13172
|
-
...this.options.searchStrategy !== void 0 ? { searchStrategy: this.options.searchStrategy } : {},
|
|
13173
|
-
...this.options.cargoStrategy !== void 0 ? { cargoStrategy: this.options.cargoStrategy } : {},
|
|
13174
|
-
...this.options.brokerStrategy !== void 0 ? { brokerStrategy: this.options.brokerStrategy } : {},
|
|
13175
|
-
...this.options.consentStrategy !== void 0 ? { consentStrategy: this.options.consentStrategy } : {},
|
|
13176
|
-
...this.options.periodsStrategy !== void 0 ? { periodsStrategy: this.options.periodsStrategy } : {},
|
|
13177
|
-
...this.options.shadowStrategy !== void 0 ? { shadowStrategy: this.options.shadowStrategy } : {},
|
|
13178
|
-
...this.options.historyStrategy !== void 0 ? { historyStrategy: this.options.historyStrategy } : {},
|
|
13179
|
-
...this.options.i18nStrategy !== void 0 ? { i18nStrategy: this.options.i18nStrategy } : {},
|
|
13180
|
-
...this.options.syncStrategy !== void 0 ? { syncStrategy: this.options.syncStrategy } : {},
|
|
13181
|
-
...this.options.guardStrategies !== void 0 ? { guardStrategies: this.options.guardStrategies } : {},
|
|
13182
|
-
...this.options.numbering !== void 0 ? { numberingConfigs: this.options.numbering } : {},
|
|
13183
|
-
emitter: this.emitter
|
|
13184
|
-
});
|
|
13185
|
-
this.vaultCache.set(name, comp);
|
|
13186
|
-
return comp;
|
|
13085
|
+
throw new ValidationError(
|
|
13086
|
+
`Vault "${name}" is not open. Call \`await db.openVault("${name}")\` first \u2014 vault() only returns an already-open vault, because opening involves async work (registry init, schema fence) that a sync accessor cannot do.`
|
|
13087
|
+
);
|
|
13187
13088
|
}
|
|
13188
13089
|
/**
|
|
13189
13090
|
* Grant access to a user for a vault.
|
|
@@ -13197,7 +13098,7 @@ var Noydb = class {
|
|
|
13197
13098
|
* Opt-in (#267): throws {@link TeamNotEnabledError} without `withTeam()`.
|
|
13198
13099
|
*/
|
|
13199
13100
|
async grant(vault, options, factors) {
|
|
13200
|
-
return this.
|
|
13101
|
+
return this.strategies.team.grant(this.team, vault, options, factors);
|
|
13201
13102
|
}
|
|
13202
13103
|
/**
|
|
13203
13104
|
* Revoke a user's access to a vault.
|
|
@@ -13210,7 +13111,7 @@ var Noydb = class {
|
|
|
13210
13111
|
* Opt-in (#267): throws {@link TeamNotEnabledError} without `withTeam()`.
|
|
13211
13112
|
*/
|
|
13212
13113
|
async revoke(vault, options, factors) {
|
|
13213
|
-
return this.
|
|
13114
|
+
return this.strategies.team.revoke(this.team, vault, options, factors);
|
|
13214
13115
|
}
|
|
13215
13116
|
/**
|
|
13216
13117
|
* Grant the FR-6 `custodian` role to a user (owner-only custody API).
|
|
@@ -13223,7 +13124,7 @@ var Noydb = class {
|
|
|
13223
13124
|
* owner-only invariant even if a host mis-configures the gate.
|
|
13224
13125
|
*/
|
|
13225
13126
|
async grantCustodian(vault, options, factors) {
|
|
13226
|
-
return this.
|
|
13127
|
+
return this.strategies.custody.grantCustodian(this, vault, options, factors);
|
|
13227
13128
|
}
|
|
13228
13129
|
/** @internal — grant-custodian engine, reached only via withCustody(); the
|
|
13229
13130
|
* keyring engine arrives as an argument so the floor never carries it (#267). */
|
|
@@ -13242,7 +13143,7 @@ var Noydb = class {
|
|
|
13242
13143
|
* 'owner'` check, so an admin cannot unwind a custodianship.
|
|
13243
13144
|
*/
|
|
13244
13145
|
async revokeCustodian(vault, options, factors) {
|
|
13245
|
-
return this.
|
|
13146
|
+
return this.strategies.custody.revokeCustodian(this, vault, options, factors);
|
|
13246
13147
|
}
|
|
13247
13148
|
/** @internal — revoke-custodian engine, reached only via withCustody().
|
|
13248
13149
|
* Mirrors `_grantCustodianImpl` (#267: engine passed in). */
|
|
@@ -13321,7 +13222,7 @@ var Noydb = class {
|
|
|
13321
13222
|
* Opt-in (#267): throws {@link TeamNotEnabledError} without `withTeam()`.
|
|
13322
13223
|
*/
|
|
13323
13224
|
async rotate(vault, collections) {
|
|
13324
|
-
return this.
|
|
13225
|
+
return this.strategies.team.rotate(this.team, vault, collections);
|
|
13325
13226
|
}
|
|
13326
13227
|
/** List all users with access to a vault. */
|
|
13327
13228
|
async listUsers(vault) {
|
|
@@ -13611,7 +13512,7 @@ var Noydb = class {
|
|
|
13611
13512
|
}
|
|
13612
13513
|
transaction(arg, maybeFn) {
|
|
13613
13514
|
if (typeof arg === "function") {
|
|
13614
|
-
return this.
|
|
13515
|
+
return this.strategies.tx.runTransaction(this, arg);
|
|
13615
13516
|
}
|
|
13616
13517
|
if (typeof arg === "object" && arg !== null && arg.dryRun === true) {
|
|
13617
13518
|
if (typeof maybeFn !== "function") {
|
|
@@ -13619,7 +13520,7 @@ var Noydb = class {
|
|
|
13619
13520
|
"db.transaction({ dryRun: true }, fn) requires the callback as the second argument."
|
|
13620
13521
|
);
|
|
13621
13522
|
}
|
|
13622
|
-
return this.
|
|
13523
|
+
return this.strategies.tx.runDryRun(this, maybeFn);
|
|
13623
13524
|
}
|
|
13624
13525
|
if (typeof arg === "object" && arg !== null && arg.amendment === true) {
|
|
13625
13526
|
if (typeof maybeFn !== "function") {
|
|
@@ -13627,7 +13528,7 @@ var Noydb = class {
|
|
|
13627
13528
|
"db.transaction({ amendment: true }, fn) requires the callback as the second argument."
|
|
13628
13529
|
);
|
|
13629
13530
|
}
|
|
13630
|
-
return this.
|
|
13531
|
+
return this.strategies.tx.runTransaction(this, maybeFn, arg);
|
|
13631
13532
|
}
|
|
13632
13533
|
const vault = arg;
|
|
13633
13534
|
const comp = this.vaultCache.get(vault);
|
|
@@ -13637,7 +13538,7 @@ var Noydb = class {
|
|
|
13637
13538
|
);
|
|
13638
13539
|
}
|
|
13639
13540
|
const engine = this.getSyncEngine(vault);
|
|
13640
|
-
return this.
|
|
13541
|
+
return this.strategies.sync.buildSyncTransaction(comp, engine);
|
|
13641
13542
|
}
|
|
13642
13543
|
/**
|
|
13643
13544
|
* Internal accessor for the primary store — used by the tx
|
|
@@ -13918,7 +13819,7 @@ var Noydb = class {
|
|
|
13918
13819
|
enforcer.destroy();
|
|
13919
13820
|
}
|
|
13920
13821
|
this.policyEnforcers.clear();
|
|
13921
|
-
this.
|
|
13822
|
+
this.strategies.session.revokeAllSessions();
|
|
13922
13823
|
for (const engine of this.syncEngines.values()) {
|
|
13923
13824
|
engine.stopAutoSync();
|
|
13924
13825
|
}
|
|
@@ -14419,4 +14320,4 @@ export {
|
|
|
14419
14320
|
Noydb,
|
|
14420
14321
|
createNoydb
|
|
14421
14322
|
};
|
|
14422
|
-
//# sourceMappingURL=chunk-
|
|
14323
|
+
//# sourceMappingURL=chunk-W7TCXZWU.js.map
|