mindoodb 0.0.44 → 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.
Files changed (91) hide show
  1. package/README.md +9 -0
  2. package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
  3. package/dist/appendonlystores/network/HttpTransport.js +4 -0
  4. package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
  5. package/dist/browser/index.mjs +31 -0
  6. package/dist/core/BaseMindooDB.d.ts +74 -0
  7. package/dist/core/BaseMindooDB.d.ts.map +1 -1
  8. package/dist/core/BaseMindooDB.js +160 -0
  9. package/dist/core/BaseMindooDB.js.map +1 -1
  10. package/dist/core/BaseMindooTenant.d.ts +22 -0
  11. package/dist/core/BaseMindooTenant.d.ts.map +1 -1
  12. package/dist/core/BaseMindooTenant.js +57 -6
  13. package/dist/core/BaseMindooTenant.js.map +1 -1
  14. package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
  15. package/dist/core/BaseMindooTenantFactory.js +31 -9
  16. package/dist/core/BaseMindooTenantFactory.js.map +1 -1
  17. package/dist/core/copy/attachments.d.ts +53 -0
  18. package/dist/core/copy/attachments.d.ts.map +1 -0
  19. package/dist/core/copy/attachments.js +186 -0
  20. package/dist/core/copy/attachments.js.map +1 -0
  21. package/dist/core/copy/copyDocument.d.ts +86 -0
  22. package/dist/core/copy/copyDocument.d.ts.map +1 -0
  23. package/dist/core/copy/copyDocument.js +369 -0
  24. package/dist/core/copy/copyDocument.js.map +1 -0
  25. package/dist/core/copy/copyDocuments.d.ts +57 -0
  26. package/dist/core/copy/copyDocuments.d.ts.map +1 -0
  27. package/dist/core/copy/copyDocuments.js +167 -0
  28. package/dist/core/copy/copyDocuments.js.map +1 -0
  29. package/dist/core/copy/entryRewrite.d.ts +49 -0
  30. package/dist/core/copy/entryRewrite.d.ts.map +1 -0
  31. package/dist/core/copy/entryRewrite.js +74 -0
  32. package/dist/core/copy/entryRewrite.js.map +1 -0
  33. package/dist/core/copy/feasibility.d.ts +73 -0
  34. package/dist/core/copy/feasibility.d.ts.map +1 -0
  35. package/dist/core/copy/feasibility.js +169 -0
  36. package/dist/core/copy/feasibility.js.map +1 -0
  37. package/dist/core/copy/flatten.d.ts +55 -0
  38. package/dist/core/copy/flatten.d.ts.map +1 -0
  39. package/dist/core/copy/flatten.js +155 -0
  40. package/dist/core/copy/flatten.js.map +1 -0
  41. package/dist/core/copy/host.d.ts +92 -0
  42. package/dist/core/copy/host.d.ts.map +1 -0
  43. package/dist/core/copy/host.js +16 -0
  44. package/dist/core/copy/host.js.map +1 -0
  45. package/dist/core/copy/preflight.d.ts +62 -0
  46. package/dist/core/copy/preflight.d.ts.map +1 -0
  47. package/dist/core/copy/preflight.js +98 -0
  48. package/dist/core/copy/preflight.js.map +1 -0
  49. package/dist/core/copy/provenance.d.ts +74 -0
  50. package/dist/core/copy/provenance.d.ts.map +1 -0
  51. package/dist/core/copy/provenance.js +91 -0
  52. package/dist/core/copy/provenance.js.map +1 -0
  53. package/dist/core/copy/types.d.ts +418 -0
  54. package/dist/core/copy/types.d.ts.map +1 -0
  55. package/dist/core/copy/types.js +21 -0
  56. package/dist/core/copy/types.js.map +1 -0
  57. package/dist/core/crypto/DomainStatement.d.ts +44 -0
  58. package/dist/core/crypto/DomainStatement.d.ts.map +1 -0
  59. package/dist/core/crypto/DomainStatement.js +71 -0
  60. package/dist/core/crypto/DomainStatement.js.map +1 -0
  61. package/dist/core/crypto/EntrySignature.d.ts +109 -15
  62. package/dist/core/crypto/EntrySignature.d.ts.map +1 -1
  63. package/dist/core/crypto/EntrySignature.js +83 -22
  64. package/dist/core/crypto/EntrySignature.js.map +1 -1
  65. package/dist/core/index.d.ts +21 -0
  66. package/dist/core/index.d.ts.map +1 -1
  67. package/dist/core/index.js +54 -3
  68. package/dist/core/index.js.map +1 -1
  69. package/dist/core/timestamps/timestampClient.d.ts +88 -0
  70. package/dist/core/timestamps/timestampClient.d.ts.map +1 -0
  71. package/dist/core/timestamps/timestampClient.js +157 -0
  72. package/dist/core/timestamps/timestampClient.js.map +1 -0
  73. package/dist/core/types.d.ts +134 -4
  74. package/dist/core/types.d.ts.map +1 -1
  75. package/dist/core/types.js.map +1 -1
  76. package/dist/node/server/MindooDBServer.d.ts +37 -0
  77. package/dist/node/server/MindooDBServer.d.ts.map +1 -1
  78. package/dist/node/server/MindooDBServer.js +157 -0
  79. package/dist/node/server/MindooDBServer.js.map +1 -1
  80. package/dist/node/server/config.d.ts.map +1 -1
  81. package/dist/node/server/config.js +16 -0
  82. package/dist/node/server/config.js.map +1 -1
  83. package/dist/node/server/timestampProxy.d.ts +129 -0
  84. package/dist/node/server/timestampProxy.d.ts.map +1 -0
  85. package/dist/node/server/timestampProxy.js +361 -0
  86. package/dist/node/server/timestampProxy.js.map +1 -0
  87. package/dist/node/server/types.d.ts +20 -0
  88. package/dist/node/server/types.d.ts.map +1 -1
  89. package/dist/node/server/types.js +12 -0
  90. package/dist/node/server/types.js.map +1 -1
  91. 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
  *