mindoodb 0.0.45 → 0.0.46
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/README.md +9 -0
- package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.js +4 -0
- package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
- package/dist/browser/index.mjs +31 -0
- package/dist/core/BaseMindooDB.d.ts +74 -0
- package/dist/core/BaseMindooDB.d.ts.map +1 -1
- package/dist/core/BaseMindooDB.js +160 -0
- package/dist/core/BaseMindooDB.js.map +1 -1
- package/dist/core/BaseMindooTenant.d.ts +22 -0
- package/dist/core/BaseMindooTenant.d.ts.map +1 -1
- package/dist/core/BaseMindooTenant.js +38 -0
- package/dist/core/BaseMindooTenant.js.map +1 -1
- package/dist/core/copy/attachments.d.ts +53 -0
- package/dist/core/copy/attachments.d.ts.map +1 -0
- package/dist/core/copy/attachments.js +186 -0
- package/dist/core/copy/attachments.js.map +1 -0
- package/dist/core/copy/copyDocument.d.ts +86 -0
- package/dist/core/copy/copyDocument.d.ts.map +1 -0
- package/dist/core/copy/copyDocument.js +369 -0
- package/dist/core/copy/copyDocument.js.map +1 -0
- package/dist/core/copy/copyDocuments.d.ts +57 -0
- package/dist/core/copy/copyDocuments.d.ts.map +1 -0
- package/dist/core/copy/copyDocuments.js +167 -0
- package/dist/core/copy/copyDocuments.js.map +1 -0
- package/dist/core/copy/entryRewrite.d.ts +49 -0
- package/dist/core/copy/entryRewrite.d.ts.map +1 -0
- package/dist/core/copy/entryRewrite.js +74 -0
- package/dist/core/copy/entryRewrite.js.map +1 -0
- package/dist/core/copy/feasibility.d.ts +73 -0
- package/dist/core/copy/feasibility.d.ts.map +1 -0
- package/dist/core/copy/feasibility.js +169 -0
- package/dist/core/copy/feasibility.js.map +1 -0
- package/dist/core/copy/flatten.d.ts +55 -0
- package/dist/core/copy/flatten.d.ts.map +1 -0
- package/dist/core/copy/flatten.js +155 -0
- package/dist/core/copy/flatten.js.map +1 -0
- package/dist/core/copy/host.d.ts +92 -0
- package/dist/core/copy/host.d.ts.map +1 -0
- package/dist/core/copy/host.js +16 -0
- package/dist/core/copy/host.js.map +1 -0
- package/dist/core/copy/preflight.d.ts +62 -0
- package/dist/core/copy/preflight.d.ts.map +1 -0
- package/dist/core/copy/preflight.js +98 -0
- package/dist/core/copy/preflight.js.map +1 -0
- package/dist/core/copy/provenance.d.ts +74 -0
- package/dist/core/copy/provenance.d.ts.map +1 -0
- package/dist/core/copy/provenance.js +91 -0
- package/dist/core/copy/provenance.js.map +1 -0
- package/dist/core/copy/types.d.ts +418 -0
- package/dist/core/copy/types.d.ts.map +1 -0
- package/dist/core/copy/types.js +21 -0
- package/dist/core/copy/types.js.map +1 -0
- package/dist/core/crypto/DomainStatement.d.ts +44 -0
- package/dist/core/crypto/DomainStatement.d.ts.map +1 -0
- package/dist/core/crypto/DomainStatement.js +71 -0
- package/dist/core/crypto/DomainStatement.js.map +1 -0
- package/dist/core/crypto/EntrySignature.d.ts +109 -15
- package/dist/core/crypto/EntrySignature.d.ts.map +1 -1
- package/dist/core/crypto/EntrySignature.js +83 -22
- package/dist/core/crypto/EntrySignature.js.map +1 -1
- package/dist/core/index.d.ts +21 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +54 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/timestamps/timestampClient.d.ts +88 -0
- package/dist/core/timestamps/timestampClient.d.ts.map +1 -0
- package/dist/core/timestamps/timestampClient.js +157 -0
- package/dist/core/timestamps/timestampClient.js.map +1 -0
- package/dist/core/types.d.ts +90 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/node/server/MindooDBServer.d.ts +37 -0
- package/dist/node/server/MindooDBServer.d.ts.map +1 -1
- package/dist/node/server/MindooDBServer.js +157 -0
- package/dist/node/server/MindooDBServer.js.map +1 -1
- package/dist/node/server/config.d.ts.map +1 -1
- package/dist/node/server/config.js +16 -0
- package/dist/node/server/config.js.map +1 -1
- package/dist/node/server/timestampProxy.d.ts +129 -0
- package/dist/node/server/timestampProxy.d.ts.map +1 -0
- package/dist/node/server/timestampProxy.js +361 -0
- package/dist/node/server/timestampProxy.js.map +1 -0
- package/dist/node/server/types.d.ts +20 -0
- package/dist/node/server/types.d.ts.map +1 -1
- package/dist/node/server/types.js +12 -0
- package/dist/node/server/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -18,6 +18,8 @@ const idGeneration_1 = require("./utils/idGeneration");
|
|
|
18
18
|
const timeSource_1 = require("./utils/timeSource");
|
|
19
19
|
const errors_1 = require("./errors");
|
|
20
20
|
const EntrySignature_1 = require("./crypto/EntrySignature");
|
|
21
|
+
const copyDocument_1 = require("./copy/copyDocument");
|
|
22
|
+
const copyDocuments_1 = require("./copy/copyDocuments");
|
|
21
23
|
const materializationGuard_1 = require("./accesscontrol/materializationGuard");
|
|
22
24
|
const Ed25519WitnessProvider_1 = require("./accesscontrol/timestamp/Ed25519WitnessProvider");
|
|
23
25
|
const AccessDeniedError_1 = require("./accesscontrol/AccessDeniedError");
|
|
@@ -10545,6 +10547,164 @@ class BaseMindooDB {
|
|
|
10545
10547
|
}
|
|
10546
10548
|
};
|
|
10547
10549
|
}
|
|
10550
|
+
// ==========================================================================
|
|
10551
|
+
// Document copy across databases (src/core/copy/, docs/document-copy.md)
|
|
10552
|
+
// ==========================================================================
|
|
10553
|
+
/**
|
|
10554
|
+
* The seam the copy engine reaches this database through.
|
|
10555
|
+
*
|
|
10556
|
+
* The engine lives in `src/core/copy/` rather than as more methods on this
|
|
10557
|
+
* already-large class, and needs a few things that are private here (entry
|
|
10558
|
+
* signing, the attachment-ref snapshot, the attachment crypto envelope). This
|
|
10559
|
+
* hands them over as one narrow object instead of widening their visibility.
|
|
10560
|
+
*
|
|
10561
|
+
* @internal Not part of the supported API; may change without notice.
|
|
10562
|
+
*/
|
|
10563
|
+
getCopyEngineHost() {
|
|
10564
|
+
return {
|
|
10565
|
+
db: this,
|
|
10566
|
+
tenant: this.tenant,
|
|
10567
|
+
store: this.store,
|
|
10568
|
+
attachmentStore: this.getEffectiveAttachmentStore(),
|
|
10569
|
+
computeEntryMetadataSignature: (meta, signing) => this.computeEntryMetadataSignature(meta, signing),
|
|
10570
|
+
collectAttachmentRefs: (doc) => this.collectAttachmentRefs(doc),
|
|
10571
|
+
decryptAttachmentPayload: (payload, keyId) => this.tenant.decryptAttachmentPayload(payload, keyId),
|
|
10572
|
+
encryptAttachmentPayload: (payload, keyId) => this.tenant.encryptAttachmentPayload(payload, keyId),
|
|
10573
|
+
syncStoreChanges: () => this.syncStoreChanges(),
|
|
10574
|
+
evaluateWriteAccess: (op, signerKey, isAuthor) => this.evaluateClientWriteAccess({ op, signerKey, isAuthor }),
|
|
10575
|
+
hasWriteContentRules: async (op) => {
|
|
10576
|
+
const directory = await this.tenant.openDirectory();
|
|
10577
|
+
return (await directory.hasWriteContentRules?.(op, this.store.getId())) ?? false;
|
|
10578
|
+
},
|
|
10579
|
+
remapAttachmentPointers: (docId, lastChunkIdByAttachmentId, signing) => this.remapAttachmentPointers(docId, lastChunkIdByAttachmentId, signing),
|
|
10580
|
+
};
|
|
10581
|
+
}
|
|
10582
|
+
/** Obtain the copy seam from another database, with a clear error if absent. */
|
|
10583
|
+
resolveCopyHost(db, role) {
|
|
10584
|
+
const host = db.getCopyEngineHost?.();
|
|
10585
|
+
if (!host) {
|
|
10586
|
+
throw new Error(`The ${role} database does not support document copying (expected a BaseMindooDB instance).`);
|
|
10587
|
+
}
|
|
10588
|
+
return host;
|
|
10589
|
+
}
|
|
10590
|
+
/**
|
|
10591
|
+
* Re-point `_attachments[].lastChunkId` at a different set of chunks, as one
|
|
10592
|
+
* `doc_change`.
|
|
10593
|
+
*
|
|
10594
|
+
* Only used when a document is duplicated inside its own database: the copied
|
|
10595
|
+
* chunks had to be renamed to avoid colliding with the source's (see
|
|
10596
|
+
* `copy/attachments.ts`), so the copy's current revision has to be told where
|
|
10597
|
+
* its own chunks are. `changeDoc` deliberately offers no way to write
|
|
10598
|
+
* `_attachments` directly, hence this internal path.
|
|
10599
|
+
*/
|
|
10600
|
+
async remapAttachmentPointers(docId, lastChunkIdByAttachmentId, signing) {
|
|
10601
|
+
if (lastChunkIdByAttachmentId.size === 0) {
|
|
10602
|
+
return;
|
|
10603
|
+
}
|
|
10604
|
+
const internalDoc = this.getCachedDocument(docId) ?? (await this.loadDocumentInternal(docId));
|
|
10605
|
+
if (!internalDoc) {
|
|
10606
|
+
throw new Error(`Cannot remap attachment pointers: document ${docId} was not found.`);
|
|
10607
|
+
}
|
|
10608
|
+
const now = (0, timeSource_1.semanticNow)();
|
|
10609
|
+
let changed = false;
|
|
10610
|
+
const newDoc = this.runChangeWithOutdatedDocRecovery(internalDoc, (doc) => automerge_adapter_1.Automerge.change(doc, { time: now }, (mutableDoc) => {
|
|
10611
|
+
const attachments = mutableDoc._attachments ?? [];
|
|
10612
|
+
for (const attachment of attachments) {
|
|
10613
|
+
const nextChunkId = lastChunkIdByAttachmentId.get(attachment.attachmentId);
|
|
10614
|
+
if (nextChunkId && attachment.lastChunkId !== nextChunkId) {
|
|
10615
|
+
attachment.lastChunkId = nextChunkId;
|
|
10616
|
+
changed = true;
|
|
10617
|
+
}
|
|
10618
|
+
}
|
|
10619
|
+
if (changed) {
|
|
10620
|
+
mutableDoc._lastModified = now;
|
|
10621
|
+
}
|
|
10622
|
+
}));
|
|
10623
|
+
if (!changed) {
|
|
10624
|
+
return;
|
|
10625
|
+
}
|
|
10626
|
+
const changeBytes = automerge_adapter_1.Automerge.getLastLocalChange(newDoc);
|
|
10627
|
+
if (!changeBytes) {
|
|
10628
|
+
throw new Error("Failed to get change bytes while remapping attachment pointers");
|
|
10629
|
+
}
|
|
10630
|
+
const entry = await this.buildDocChangeStoreEntry({
|
|
10631
|
+
internalDoc,
|
|
10632
|
+
changeBytes,
|
|
10633
|
+
now,
|
|
10634
|
+
useCustomKey: signing !== undefined,
|
|
10635
|
+
signingKeyPair: signing?.signingKeyPair,
|
|
10636
|
+
signingKeyPassword: signing?.signingKeyPassword,
|
|
10637
|
+
attachmentRefs: this.collectAttachmentRefs(newDoc),
|
|
10638
|
+
});
|
|
10639
|
+
await this.store.putEntries([entry]);
|
|
10640
|
+
this.registerAutomergeHashMapping(docId, automerge_adapter_1.Automerge.decodeChange(changeBytes).hash, entry.id);
|
|
10641
|
+
internalDoc.doc = newDoc;
|
|
10642
|
+
internalDoc.lastModified = now;
|
|
10643
|
+
internalDoc.awaitingWitness = (0, storeEntryTime_1.isProvisional)(entry) || (internalDoc.awaitingWitness ?? false);
|
|
10644
|
+
const versioned = (0, storeEntryTime_1.isVersioned)(entry) || internalDoc.awaitingWitness || (internalDoc.witnessed ?? false);
|
|
10645
|
+
internalDoc.witnessed = versioned && !internalDoc.awaitingWitness;
|
|
10646
|
+
await this.storeCachedDocument(internalDoc);
|
|
10647
|
+
this.updateIndex(docId, internalDoc.lastModified, internalDoc.isDeleted, internalDoc.decryptionKeyId, "visible", internalDoc.awaitingWitness, internalDoc.witnessed, true);
|
|
10648
|
+
this.markDocDirty(docId);
|
|
10649
|
+
}
|
|
10650
|
+
/**
|
|
10651
|
+
* Report what {@link copyDocumentTo} would do with these options — the chosen
|
|
10652
|
+
* strategy, whether the original authors' signatures would survive, whether
|
|
10653
|
+
* the copy would merge into an existing document — without writing anything.
|
|
10654
|
+
*
|
|
10655
|
+
* The returned `reasons` explain a refusal, and also explain why a permitted
|
|
10656
|
+
* copy has to re-author, so a caller can distinguish an unavoidable
|
|
10657
|
+
* re-authoring from an accidental one.
|
|
10658
|
+
*
|
|
10659
|
+
* @param docId The document to copy.
|
|
10660
|
+
* @param target The database the copy would be written to.
|
|
10661
|
+
* @param options The same options that would be passed to {@link copyDocumentTo}.
|
|
10662
|
+
*/
|
|
10663
|
+
async canCopyDocumentTo(docId, target, options) {
|
|
10664
|
+
return (0, copyDocument_1.canCopyDocument)(this.getCopyEngineHost(), this.resolveCopyHost(target, "target"), docId, options);
|
|
10665
|
+
}
|
|
10666
|
+
/**
|
|
10667
|
+
* Copy one document into another database, either flattened to a single
|
|
10668
|
+
* revision or with its full history.
|
|
10669
|
+
*
|
|
10670
|
+
* See `docs/document-copy.md` for the strategy matrix. In short: the default
|
|
10671
|
+
* writes a flattened copy under a fresh id; `mode: "history"` carries the
|
|
10672
|
+
* whole revision graph; and adding `targetDocId: "same"` with
|
|
10673
|
+
* `authorship: "preserve"` (same tenant, same key, different database) keeps
|
|
10674
|
+
* the original signers, which is what makes sharding possible.
|
|
10675
|
+
*
|
|
10676
|
+
* @param docId The document to copy.
|
|
10677
|
+
* @param target The database to copy into.
|
|
10678
|
+
* @param options See {@link CopyDocumentOptions}; every default is documented there.
|
|
10679
|
+
* @return What was copied, including the target document id — returned even on
|
|
10680
|
+
* cancellation, so a resumed run can target the same id.
|
|
10681
|
+
*/
|
|
10682
|
+
async copyDocumentTo(docId, target, options) {
|
|
10683
|
+
const targetHost = this.resolveCopyHost(target, "target");
|
|
10684
|
+
this.assertWritable("copyDocumentTo");
|
|
10685
|
+
return (0, copyDocument_1.copyDocument)(this.getCopyEngineHost(), targetHost, docId, options);
|
|
10686
|
+
}
|
|
10687
|
+
/**
|
|
10688
|
+
* Copy many documents into another database in one pass.
|
|
10689
|
+
*
|
|
10690
|
+
* With `mode: "history"`, `targetDocId: "same"` and `authorship: "preserve"`
|
|
10691
|
+
* this is the database sharding primitive: document ids, full history and the
|
|
10692
|
+
* original signers all survive the split, and nothing is decrypted or
|
|
10693
|
+
* re-signed along the way. Repeated runs are safe and transfer only the delta,
|
|
10694
|
+
* so a shard can proceed against a live database.
|
|
10695
|
+
*
|
|
10696
|
+
* Per-document failures do not abort the run; they are collected in
|
|
10697
|
+
* {@link CopyDocumentsResult.failed}.
|
|
10698
|
+
*
|
|
10699
|
+
* @param selector Which documents to copy — explicit ids, id prefixes, or both.
|
|
10700
|
+
* @param target The database to copy into.
|
|
10701
|
+
* @param options See {@link CopyDocumentsOptions}.
|
|
10702
|
+
*/
|
|
10703
|
+
async copyDocumentsTo(selector, target, options) {
|
|
10704
|
+
const targetHost = this.resolveCopyHost(target, "target");
|
|
10705
|
+
this.assertWritable("copyDocumentsTo");
|
|
10706
|
+
return (0, copyDocuments_1.copyDocuments)(this.getCopyEngineHost(), targetHost, selector, options);
|
|
10707
|
+
}
|
|
10548
10708
|
/**
|
|
10549
10709
|
* Pull changes from a remote content-addressed store or another MindooDB instance.
|
|
10550
10710
|
*
|