mindoodb 0.0.2 → 0.0.3

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 (172) hide show
  1. package/README.md +92 -19
  2. package/dist/__mocks__/expo-standard-web-crypto.d.ts +10 -0
  3. package/dist/__mocks__/expo-standard-web-crypto.d.ts.map +1 -0
  4. package/dist/__mocks__/expo-standard-web-crypto.js +22 -0
  5. package/dist/__mocks__/expo-standard-web-crypto.js.map +1 -0
  6. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts +8 -0
  7. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts.map +1 -0
  8. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js +16 -0
  9. package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js.map +1 -0
  10. package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts +1 -1
  11. package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts.map +1 -1
  12. package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js +2 -2
  13. package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js.map +1 -1
  14. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +11 -1
  15. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
  16. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +94 -0
  17. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
  18. package/dist/appendonlystores/network/HttpTransport.d.ts +13 -2
  19. package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
  20. package/dist/appendonlystores/network/HttpTransport.js +86 -0
  21. package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
  22. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +19 -2
  23. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
  24. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +96 -0
  25. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
  26. package/dist/appendonlystores/network/index.d.ts +1 -1
  27. package/dist/appendonlystores/network/index.d.ts.map +1 -1
  28. package/dist/appendonlystores/network/index.js.map +1 -1
  29. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts +61 -0
  30. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts.map +1 -0
  31. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js +685 -0
  32. package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js.map +1 -0
  33. package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.d.ts +25 -0
  34. package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.d.ts.map +1 -0
  35. package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.js +41 -0
  36. package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.js.map +1 -0
  37. package/dist/browser/index.d.ts +5 -0
  38. package/dist/browser/index.d.ts.map +1 -1
  39. package/dist/browser/index.js +13 -1
  40. package/dist/browser/index.js.map +1 -1
  41. package/dist/core/BaseMindooDB.d.ts +12 -0
  42. package/dist/core/BaseMindooDB.d.ts.map +1 -1
  43. package/dist/core/BaseMindooDB.js +210 -108
  44. package/dist/core/BaseMindooDB.js.map +1 -1
  45. package/dist/core/BaseMindooTenant.d.ts +40 -6
  46. package/dist/core/BaseMindooTenant.d.ts.map +1 -1
  47. package/dist/core/BaseMindooTenant.js +179 -21
  48. package/dist/core/BaseMindooTenant.js.map +1 -1
  49. package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
  50. package/dist/core/BaseMindooTenantDirectory.js +10 -0
  51. package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
  52. package/dist/core/BaseMindooTenantFactory.d.ts +22 -28
  53. package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
  54. package/dist/core/BaseMindooTenantFactory.js +161 -65
  55. package/dist/core/BaseMindooTenantFactory.js.map +1 -1
  56. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +68 -0
  57. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -0
  58. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js +659 -0
  59. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -0
  60. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +43 -3
  61. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
  62. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +162 -23
  63. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
  64. package/dist/core/appendonlystores/bloom.d.ts +85 -0
  65. package/dist/core/appendonlystores/bloom.d.ts.map +1 -0
  66. package/dist/core/appendonlystores/bloom.js +228 -0
  67. package/dist/core/appendonlystores/bloom.js.map +1 -0
  68. package/dist/core/appendonlystores/network/NetworkTransport.d.ts +22 -2
  69. package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
  70. package/dist/core/appendonlystores/network/types.d.ts +10 -0
  71. package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
  72. package/dist/core/appendonlystores/network/types.js.map +1 -1
  73. package/dist/core/appendonlystores/types.d.ts +123 -0
  74. package/dist/core/appendonlystores/types.d.ts.map +1 -1
  75. package/dist/core/automerge-adapter.d.ts +15 -0
  76. package/dist/core/automerge-adapter.d.ts.map +1 -0
  77. package/dist/core/automerge-adapter.js +73 -0
  78. package/dist/core/automerge-adapter.js.map +1 -0
  79. package/dist/core/crypto/pbkdf2Iterations.d.ts +12 -0
  80. package/dist/core/crypto/pbkdf2Iterations.d.ts.map +1 -0
  81. package/dist/core/crypto/pbkdf2Iterations.js +55 -0
  82. package/dist/core/crypto/pbkdf2Iterations.js.map +1 -0
  83. package/dist/core/index.d.ts +7 -2
  84. package/dist/core/index.d.ts.map +1 -1
  85. package/dist/core/index.js +30 -1
  86. package/dist/core/index.js.map +1 -1
  87. package/dist/core/keys/KeyBag.d.ts +32 -12
  88. package/dist/core/keys/KeyBag.d.ts.map +1 -1
  89. package/dist/core/keys/KeyBag.js +86 -26
  90. package/dist/core/keys/KeyBag.js.map +1 -1
  91. package/dist/core/keys/KeyContext.d.ts +4 -0
  92. package/dist/core/keys/KeyContext.d.ts.map +1 -0
  93. package/dist/core/keys/KeyContext.js +11 -0
  94. package/dist/core/keys/KeyContext.js.map +1 -0
  95. package/dist/core/types.d.ts +218 -50
  96. package/dist/core/types.d.ts.map +1 -1
  97. package/dist/core/types.js +2 -0
  98. package/dist/core/types.js.map +1 -1
  99. package/dist/core/uri/MindooURI.d.ts +58 -0
  100. package/dist/core/uri/MindooURI.d.ts.map +1 -0
  101. package/dist/core/uri/MindooURI.js +169 -0
  102. package/dist/core/uri/MindooURI.js.map +1 -0
  103. package/dist/core/userid/index.d.ts +0 -10
  104. package/dist/core/userid/index.d.ts.map +1 -1
  105. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +541 -0
  106. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -0
  107. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +1334 -0
  108. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -0
  109. package/dist/node/index.d.ts +1 -0
  110. package/dist/node/index.d.ts.map +1 -1
  111. package/dist/node/index.js +5 -1
  112. package/dist/node/index.js.map +1 -1
  113. package/dist/reactnative/crypto/AESAdapter.d.ts +18 -0
  114. package/dist/reactnative/crypto/AESAdapter.d.ts.map +1 -0
  115. package/dist/reactnative/crypto/AESAdapter.js +112 -0
  116. package/dist/reactnative/crypto/AESAdapter.js.map +1 -0
  117. package/dist/reactnative/crypto/Ed25519Adapter.d.ts +34 -0
  118. package/dist/reactnative/crypto/Ed25519Adapter.d.ts.map +1 -0
  119. package/dist/reactnative/crypto/Ed25519Adapter.js +386 -0
  120. package/dist/reactnative/crypto/Ed25519Adapter.js.map +1 -0
  121. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.d.ts +23 -0
  122. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.d.ts.map +1 -0
  123. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.js +51 -0
  124. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.js.map +1 -0
  125. package/dist/reactnative/crypto/HMACAdapter.d.ts +13 -0
  126. package/dist/reactnative/crypto/HMACAdapter.d.ts.map +1 -0
  127. package/dist/reactnative/crypto/HMACAdapter.js +50 -0
  128. package/dist/reactnative/crypto/HMACAdapter.js.map +1 -0
  129. package/dist/reactnative/crypto/KeyFormatConverter.d.ts +21 -0
  130. package/dist/reactnative/crypto/KeyFormatConverter.d.ts.map +1 -0
  131. package/dist/reactnative/crypto/KeyFormatConverter.js +72 -0
  132. package/dist/reactnative/crypto/KeyFormatConverter.js.map +1 -0
  133. package/dist/reactnative/crypto/PBKDF2Adapter.d.ts +19 -0
  134. package/dist/reactnative/crypto/PBKDF2Adapter.d.ts.map +1 -0
  135. package/dist/reactnative/crypto/PBKDF2Adapter.js +67 -0
  136. package/dist/reactnative/crypto/PBKDF2Adapter.js.map +1 -0
  137. package/dist/reactnative/crypto/QuickCryptoAdapter.d.ts +37 -0
  138. package/dist/reactnative/crypto/QuickCryptoAdapter.d.ts.map +1 -0
  139. package/dist/reactnative/crypto/QuickCryptoAdapter.js +72 -0
  140. package/dist/reactnative/crypto/QuickCryptoAdapter.js.map +1 -0
  141. package/dist/reactnative/crypto/RSAAdapter.d.ts +38 -0
  142. package/dist/reactnative/crypto/RSAAdapter.d.ts.map +1 -0
  143. package/dist/reactnative/crypto/RSAAdapter.js +184 -0
  144. package/dist/reactnative/crypto/RSAAdapter.js.map +1 -0
  145. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.d.ts +33 -0
  146. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.d.ts.map +1 -0
  147. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.js +61 -0
  148. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.js.map +1 -0
  149. package/dist/reactnative/crypto/SHA256Adapter.d.ts +9 -0
  150. package/dist/reactnative/crypto/SHA256Adapter.d.ts.map +1 -0
  151. package/dist/reactnative/crypto/SHA256Adapter.js +29 -0
  152. package/dist/reactnative/crypto/SHA256Adapter.js.map +1 -0
  153. package/dist/reactnative/crypto/SubtleCryptoPolyfill.d.ts +63 -0
  154. package/dist/reactnative/crypto/SubtleCryptoPolyfill.d.ts.map +1 -0
  155. package/dist/reactnative/crypto/SubtleCryptoPolyfill.js +350 -0
  156. package/dist/reactnative/crypto/SubtleCryptoPolyfill.js.map +1 -0
  157. package/dist/reactnative/index.d.ts +8 -0
  158. package/dist/reactnative/index.d.ts.map +1 -0
  159. package/dist/reactnative/index.js +38 -0
  160. package/dist/reactnative/index.js.map +1 -0
  161. package/package.json +51 -6
  162. package/patches/PATCHES.md +111 -0
  163. package/patches/react-native+0.76.9.patch +34 -0
  164. package/patches/react-native-quick-crypto+1.0.7.patch +42 -0
  165. package/scripts/cli.js +21 -0
  166. package/scripts/setup-react-native.js +228 -0
  167. package/templates/reactnative/App.js +252 -0
  168. package/templates/reactnative/app.json +29 -0
  169. package/templates/reactnative/babel.config.js +6 -0
  170. package/templates/reactnative/index.js +26 -0
  171. package/templates/reactnative/metro.config.snippet.js +39 -0
  172. package/templates/reactnative/mindoodb-polyfills.js +116 -0
@@ -1,41 +1,12 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.BaseMindooDB = void 0;
37
- const Automerge = __importStar(require("@automerge/automerge"));
4
+ // Import platform-appropriate Automerge implementation
5
+ // React Native: native Rust (react-native-automerge-generated)
6
+ // Browser/Node.js: WASM (@automerge/automerge/slim)
7
+ const automerge_adapter_1 = require("./automerge-adapter");
38
8
  const uuid_1 = require("uuid");
9
+ const bloom_1 = require("./appendonlystores/bloom");
39
10
  const idGeneration_1 = require("./utils/idGeneration");
40
11
  const errors_1 = require("./errors");
41
12
  const logging_1 = require("./logging");
@@ -73,6 +44,7 @@ class BaseMindooDB {
73
44
  this.docCache = new Map();
74
45
  // Track which entry IDs we've already processed
75
46
  this.processedEntryIds = [];
47
+ this.processedEntryCursor = null;
76
48
  // Index: automergeHash -> entryId for each document
77
49
  // Used for resolving Automerge dependency hashes to entry IDs
78
50
  this.automergeHashToEntryId = new Map(); // Map<docId, Map<automergeHash, entryId>>
@@ -265,7 +237,7 @@ class BaseMindooDB {
265
237
  this.logger.debug(`Syncing store changes for database ${this.store.getId()} in tenant ${this.tenant.getId()}`);
266
238
  this.logger.debug(`Already processed ${this.processedEntryIds.length} entry IDs`);
267
239
  // Find new entries that we haven't processed yet
268
- const newEntryMetadata = await this.store.findNewEntries(this.processedEntryIds);
240
+ const newEntryMetadata = await this.getNewEntryMetadataForSync();
269
241
  this.logger.debug(`Found ${newEntryMetadata.length} new entries`);
270
242
  if (newEntryMetadata.length === 0) {
271
243
  this.logger.debug(`No new entries to process`);
@@ -367,6 +339,105 @@ class BaseMindooDB {
367
339
  this.processedEntryIds.push(...newEntryMetadata.map(em => em.id));
368
340
  this.logger.debug(`Synced ${newEntryMetadata.length} new entries, index now has ${this.index.length} documents`);
369
341
  }
342
+ supportsCursorScan(store) {
343
+ return typeof store.scanEntriesSince === "function";
344
+ }
345
+ async scanAllMetadata(store, filters) {
346
+ if (!this.supportsCursorScan(store)) {
347
+ if (filters?.docId) {
348
+ return store.findNewEntriesForDoc([], filters.docId);
349
+ }
350
+ return store.findNewEntries([]);
351
+ }
352
+ const all = [];
353
+ let cursor = null;
354
+ while (true) {
355
+ const page = await store.scanEntriesSince(cursor, 1000, filters);
356
+ all.push(...page.entries);
357
+ cursor = page.nextCursor;
358
+ if (!page.hasMore) {
359
+ break;
360
+ }
361
+ }
362
+ return all;
363
+ }
364
+ async getNewEntryMetadataForSync() {
365
+ if (!this.supportsCursorScan(this.store)) {
366
+ return this.store.findNewEntries(this.processedEntryIds);
367
+ }
368
+ const allNew = [];
369
+ let cursor = this.processedEntryCursor;
370
+ while (true) {
371
+ const page = await this.store.scanEntriesSince(cursor, 1000);
372
+ allNew.push(...page.entries);
373
+ cursor = page.nextCursor;
374
+ if (!page.hasMore) {
375
+ break;
376
+ }
377
+ }
378
+ this.processedEntryCursor = cursor;
379
+ return allNew;
380
+ }
381
+ async syncEntriesFromStore(sourceStore, targetStore) {
382
+ let transferred = 0;
383
+ let targetBloom = null;
384
+ if (typeof targetStore.getIdBloomSummary === "function") {
385
+ try {
386
+ targetBloom = await targetStore.getIdBloomSummary();
387
+ }
388
+ catch (error) {
389
+ this.logger.warn("Failed to get bloom summary from target store, falling back to exact checks", error);
390
+ }
391
+ }
392
+ if (this.supportsCursorScan(sourceStore)) {
393
+ let cursor = null;
394
+ while (true) {
395
+ const page = await sourceStore.scanEntriesSince(cursor, 1000);
396
+ if (page.entries.length > 0) {
397
+ const ids = page.entries.map((m) => m.id);
398
+ let definitelyMissing = [];
399
+ let maybeExisting = ids;
400
+ if (targetBloom) {
401
+ definitelyMissing = [];
402
+ maybeExisting = [];
403
+ for (const id of ids) {
404
+ if ((0, bloom_1.bloomMightContainId)(targetBloom, id)) {
405
+ maybeExisting.push(id);
406
+ }
407
+ else {
408
+ definitelyMissing.push(id);
409
+ }
410
+ }
411
+ }
412
+ let missingIds = definitelyMissing;
413
+ if (maybeExisting.length > 0) {
414
+ const existing = await targetStore.hasEntries(maybeExisting);
415
+ const existingSet = new Set(existing);
416
+ const maybeMissing = maybeExisting.filter((id) => !existingSet.has(id));
417
+ missingIds = missingIds.concat(maybeMissing);
418
+ }
419
+ if (missingIds.length > 0) {
420
+ const missingEntries = await sourceStore.getEntries(missingIds);
421
+ await targetStore.putEntries(missingEntries);
422
+ transferred += missingEntries.length;
423
+ }
424
+ }
425
+ cursor = page.nextCursor;
426
+ if (!page.hasMore) {
427
+ break;
428
+ }
429
+ }
430
+ return transferred;
431
+ }
432
+ const targetIds = await targetStore.getAllIds();
433
+ const sourceNewMetadata = await sourceStore.findNewEntries(targetIds);
434
+ if (sourceNewMetadata.length === 0) {
435
+ return 0;
436
+ }
437
+ const sourceEntries = await sourceStore.getEntries(sourceNewMetadata.map((m) => m.id));
438
+ await targetStore.putEntries(sourceEntries);
439
+ return sourceEntries.length;
440
+ }
370
441
  getStore() {
371
442
  return this.store;
372
443
  }
@@ -407,18 +478,18 @@ class BaseMindooDB {
407
478
  const docId = (0, uuid_1.v7)();
408
479
  this.logger.debug(`Creating document ${docId} with key ${keyId}${useCustomSigningKey ? ' using custom signing key' : ''}`);
409
480
  // Create initial Automerge document
410
- const initialDoc = Automerge.init();
481
+ const initialDoc = automerge_adapter_1.Automerge.init();
411
482
  // Create the first change
412
483
  const now = Date.now();
413
484
  this.logger.debug(`Creating initial Automerge change for document ${docId}`);
414
485
  let newDoc;
415
486
  try {
416
- newDoc = Automerge.change(initialDoc, (doc) => {
487
+ newDoc = automerge_adapter_1.Automerge.change(initialDoc, (doc) => {
417
488
  // Store metadata in the document payload
418
489
  // We need to modify the document to ensure a change is created
419
490
  doc._attachments = [];
420
491
  });
421
- this.logger.debug(`Successfully created Automerge change, document heads: ${JSON.stringify(Automerge.getHeads(newDoc))}`);
492
+ this.logger.debug(`Successfully created Automerge change, document heads: ${JSON.stringify(automerge_adapter_1.Automerge.getHeads(newDoc))}`);
422
493
  }
423
494
  catch (error) {
424
495
  this.logger.error(`Error in Automerge.change for document ${docId}:`, error);
@@ -426,7 +497,7 @@ class BaseMindooDB {
426
497
  }
427
498
  // Get the change bytes from the document
428
499
  this.logger.debug(`Getting change bytes from document ${docId}`);
429
- const changeBytes = Automerge.getLastLocalChange(newDoc);
500
+ const changeBytes = automerge_adapter_1.Automerge.getLastLocalChange(newDoc);
430
501
  if (!changeBytes) {
431
502
  throw new Error("Failed to get change bytes from Automerge document");
432
503
  }
@@ -435,7 +506,7 @@ class BaseMindooDB {
435
506
  this.logger.debug(`Decoding change to get hash and dependencies`);
436
507
  let decodedChange;
437
508
  try {
438
- decodedChange = Automerge.decodeChange(changeBytes);
509
+ decodedChange = automerge_adapter_1.Automerge.decodeChange(changeBytes);
439
510
  this.logger.debug(`Successfully decoded change, hash: ${decodedChange.hash}, deps: ${decodedChange.deps?.length || 0}`);
440
511
  }
441
512
  catch (error) {
@@ -523,7 +594,7 @@ class BaseMindooDB {
523
594
  async getDocumentAtTimestamp(docId, timestamp) {
524
595
  this.logger.debug(`Getting document ${docId} at timestamp ${timestamp}`);
525
596
  // Get all entry metadata for this document
526
- const allEntryMetadata = await this.store.findNewEntriesForDoc([], docId);
597
+ const allEntryMetadata = await this.scanAllMetadata(this.store, { docId });
527
598
  // Filter entries up to the timestamp
528
599
  const relevantEntries = allEntryMetadata
529
600
  .filter(em => em.createdAt <= timestamp)
@@ -534,7 +605,7 @@ class BaseMindooDB {
534
605
  // Load entries
535
606
  const entries = await this.store.getEntries(relevantEntries.map(em => em.id));
536
607
  // Apply changes in order
537
- let doc = Automerge.init();
608
+ let doc = automerge_adapter_1.Automerge.init();
538
609
  for (const entryData of entries) {
539
610
  // Admin-only mode: only accept entries signed by the admin key
540
611
  if (this._isAdminOnlyDb && entryData.createdByPublicKey !== this.getAdminPublicKey()) {
@@ -551,7 +622,7 @@ class BaseMindooDB {
551
622
  // Decrypt payload (only after signature verification passes)
552
623
  const decryptedPayload = await this.tenant.decryptPayload(entryData.encryptedData, entryData.decryptionKeyId);
553
624
  // Apply change using loadIncremental - this is the recommended way for binary change data
554
- doc = Automerge.loadIncremental(doc, decryptedPayload);
625
+ doc = automerge_adapter_1.Automerge.loadIncremental(doc, decryptedPayload);
555
626
  // Register the automerge hash -> entry ID mapping for future dependency resolution
556
627
  const parsed = (0, idGeneration_1.parseDocEntryId)(entryData.id);
557
628
  if (parsed) {
@@ -581,7 +652,7 @@ class BaseMindooDB {
581
652
  async *iterateDocumentHistory(docId) {
582
653
  this.logger.debug(`Iterating document history for ${docId}`);
583
654
  // Get all entry metadata for this document
584
- const allEntryMetadata = await this.store.findNewEntriesForDoc([], docId);
655
+ const allEntryMetadata = await this.scanAllMetadata(this.store, { docId });
585
656
  // Filter to only doc_create, doc_change, and doc_delete entries (exclude snapshots)
586
657
  const relevantEntries = allEntryMetadata
587
658
  .filter(em => em.entryType === "doc_create" || em.entryType === "doc_change" || em.entryType === "doc_delete")
@@ -623,17 +694,17 @@ class BaseMindooDB {
623
694
  this.logger.warn(`First entry is not doc_create, skipping`);
624
695
  continue;
625
696
  }
626
- currentDoc = Automerge.init();
697
+ currentDoc = automerge_adapter_1.Automerge.init();
627
698
  createdAt = entryMetadata.createdAt;
628
699
  decryptionKeyId = entryMetadata.decryptionKeyId;
629
700
  }
630
701
  // Check document heads before applying change (for non-first entries)
631
- const headsBefore = isFirstEntry ? null : (currentDoc ? Automerge.getHeads(currentDoc) : null);
702
+ const headsBefore = isFirstEntry ? null : (currentDoc ? automerge_adapter_1.Automerge.getHeads(currentDoc) : null);
632
703
  // Apply change using loadIncremental
633
704
  if (currentDoc === null) {
634
705
  throw new Error("currentDoc should not be null at this point");
635
706
  }
636
- currentDoc = Automerge.loadIncremental(currentDoc, decryptedPayload);
707
+ currentDoc = automerge_adapter_1.Automerge.loadIncremental(currentDoc, decryptedPayload);
637
708
  // Check if document actually changed by comparing heads
638
709
  // For first entry (doc_create), always yield since it's the initial creation
639
710
  // For delete entries, always yield
@@ -643,7 +714,7 @@ class BaseMindooDB {
643
714
  shouldYield = true;
644
715
  }
645
716
  else {
646
- const headsAfter = Automerge.getHeads(currentDoc);
717
+ const headsAfter = automerge_adapter_1.Automerge.getHeads(currentDoc);
647
718
  const headsChanged = headsBefore !== null && JSON.stringify(headsBefore) !== JSON.stringify(headsAfter);
648
719
  shouldYield = headsChanged;
649
720
  }
@@ -655,7 +726,7 @@ class BaseMindooDB {
655
726
  // Only yield if document actually changed (or if this is create/delete entry)
656
727
  if (shouldYield) {
657
728
  // Clone the document to ensure independence
658
- const clonedDoc = Automerge.clone(currentDoc);
729
+ const clonedDoc = automerge_adapter_1.Automerge.clone(currentDoc);
659
730
  // Create internal doc representation
660
731
  const internalDoc = {
661
732
  id: docId,
@@ -690,10 +761,14 @@ class BaseMindooDB {
690
761
  return docIds;
691
762
  }
692
763
  async getAllDocumentIdsAtTimestamp(timestamp) {
764
+ // findEntries() uses an exclusive upper bound (createdAt < creationDateUntil).
765
+ // Query up to timestamp + 1 so entries created exactly at `timestamp` are included
766
+ // for the strict checks below (createTime < timestamp, deleteTime > timestamp).
767
+ const upperBoundExclusive = timestamp === Number.MAX_SAFE_INTEGER ? timestamp : timestamp + 1;
693
768
  // Efficiently query for doc_create and doc_delete entries before the timestamp
694
769
  const [creates, deletes] = await Promise.all([
695
- this.store.findEntries("doc_create", null, timestamp),
696
- this.store.findEntries("doc_delete", null, timestamp)
770
+ this.store.findEntries("doc_create", null, upperBoundExclusive),
771
+ this.store.findEntries("doc_delete", null, upperBoundExclusive)
697
772
  ]);
698
773
  // Build sets of docIds for efficient lookup
699
774
  const createdDocIds = new Set();
@@ -722,9 +797,9 @@ class BaseMindooDB {
722
797
  const createTime = createTimes.get(docId);
723
798
  const deleteTime = deleteTimes.get(docId);
724
799
  // Document exists at timestamp if:
725
- // 1. It was created before the timestamp
800
+ // 1. It was created at or before the timestamp
726
801
  // 2. Either it was never deleted, or it was deleted after the timestamp
727
- if (createTime < timestamp) {
802
+ if (createTime <= timestamp) {
728
803
  if (!deleteTime || deleteTime > timestamp) {
729
804
  docIds.push(docId);
730
805
  }
@@ -764,7 +839,7 @@ class BaseMindooDB {
764
839
  // Create deletion change by clearing all fields from the document
765
840
  // This ensures Automerge produces actual change bytes
766
841
  // The deletion is also tracked via the "doc_delete" type entry in the append-only store
767
- const newDoc = Automerge.change(internalDoc.doc, (doc) => {
842
+ const newDoc = automerge_adapter_1.Automerge.change(internalDoc.doc, (doc) => {
768
843
  // Remove all fields from the document
769
844
  for (const key of Object.keys(doc)) {
770
845
  delete doc[key];
@@ -773,12 +848,12 @@ class BaseMindooDB {
773
848
  doc._deleted = true;
774
849
  });
775
850
  // Get the change bytes from the document
776
- const changeBytes = Automerge.getLastLocalChange(newDoc);
851
+ const changeBytes = automerge_adapter_1.Automerge.getLastLocalChange(newDoc);
777
852
  if (!changeBytes) {
778
853
  throw new Error("Failed to get change bytes from Automerge document");
779
854
  }
780
855
  // Decode the change to get hash and dependencies
781
- const decodedChange = Automerge.decodeChange(changeBytes);
856
+ const decodedChange = automerge_adapter_1.Automerge.decodeChange(changeBytes);
782
857
  const automergeHash = decodedChange.hash;
783
858
  const automergeDepHashes = decodedChange.deps || []; // Dependencies from the decoded change
784
859
  // Encrypt the change payload first
@@ -873,7 +948,7 @@ class BaseMindooDB {
873
948
  // Apply the change function
874
949
  const now = Date.now();
875
950
  this.logger.debug(`Applying change function to document ${docId}`);
876
- this.logger.debug(`Document state before change: heads=${JSON.stringify(Automerge.getHeads(internalDoc.doc))}`);
951
+ this.logger.debug(`Document state before change: heads=${JSON.stringify(automerge_adapter_1.Automerge.getHeads(internalDoc.doc))}`);
877
952
  // For async callbacks, we need to handle document modifications carefully.
878
953
  // Automerge.change() requires synchronous modifications, so we'll:
879
954
  // 1. Execute the async callback to do any async work (like signing)
@@ -916,8 +991,8 @@ class BaseMindooDB {
916
991
  pendingDeletions.delete(prop);
917
992
  // Track the change
918
993
  pendingChanges.set(prop, value);
919
- // Also set on the target for immediate access
920
- target[prop] = value;
994
+ // NOTE: Don't set on target immediately - Automerge requires changes
995
+ // to be made inside Automerge.change(). Pending changes are applied later.
921
996
  }
922
997
  return true;
923
998
  },
@@ -928,8 +1003,8 @@ class BaseMindooDB {
928
1003
  pendingDeletions.add(prop);
929
1004
  // Remove from pending changes if it was there
930
1005
  pendingChanges.delete(prop);
931
- // Also delete from the target for immediate access
932
- delete target[prop];
1006
+ // NOTE: Don't delete from target immediately - Automerge requires changes
1007
+ // to be made inside Automerge.change(). Pending deletions are applied later.
933
1008
  }
934
1009
  return true;
935
1010
  },
@@ -1048,7 +1123,7 @@ class BaseMindooDB {
1048
1123
  // Now apply the collected changes synchronously in Automerge.change()
1049
1124
  let newDoc;
1050
1125
  try {
1051
- newDoc = Automerge.change(internalDoc.doc, (automergeDoc) => {
1126
+ newDoc = automerge_adapter_1.Automerge.change(internalDoc.doc, (automergeDoc) => {
1052
1127
  // Apply all pending changes (sets/updates)
1053
1128
  for (const [key, value] of pendingChanges) {
1054
1129
  automergeDoc[key] = value;
@@ -1087,7 +1162,7 @@ class BaseMindooDB {
1087
1162
  // Update lastModified timestamp
1088
1163
  automergeDoc._lastModified = now;
1089
1164
  });
1090
- this.logger.debug(`Successfully applied change function, new document heads: ${JSON.stringify(Automerge.getHeads(newDoc))}`);
1165
+ this.logger.debug(`Successfully applied change function, new document heads: ${JSON.stringify(automerge_adapter_1.Automerge.getHeads(newDoc))}`);
1091
1166
  }
1092
1167
  catch (error) {
1093
1168
  this.logger.error(`Error in Automerge.change for document ${docId}:`, error);
@@ -1095,14 +1170,14 @@ class BaseMindooDB {
1095
1170
  }
1096
1171
  // Get the change bytes from the document
1097
1172
  this.logger.debug(`Getting change bytes from document ${docId}`);
1098
- const changeBytes = Automerge.getLastLocalChange(newDoc);
1173
+ const changeBytes = automerge_adapter_1.Automerge.getLastLocalChange(newDoc);
1099
1174
  if (!changeBytes) {
1100
1175
  //TODO decide if we just exit here or throw an error
1101
1176
  throw new Error("Failed to get change bytes from Automerge document");
1102
1177
  }
1103
1178
  this.logger.debug(`Got change bytes: ${changeBytes.length} bytes`);
1104
1179
  // Decode the change to get hash and dependencies
1105
- const decodedChange = Automerge.decodeChange(changeBytes);
1180
+ const decodedChange = automerge_adapter_1.Automerge.decodeChange(changeBytes);
1106
1181
  const automergeHash = decodedChange.hash;
1107
1182
  const automergeDepHashes = decodedChange.deps || []; // Dependencies from the decoded change
1108
1183
  // Encrypt the change payload first
@@ -1256,7 +1331,7 @@ class BaseMindooDB {
1256
1331
  }
1257
1332
  this.logger.debug(`Applying ${newEntryMetadata.length} new entries to cached document ${docId}`);
1258
1333
  // Get current document heads to check if it changes
1259
- const headsBefore = Automerge.getHeads(cachedDoc.doc);
1334
+ const headsBefore = automerge_adapter_1.Automerge.getHeads(cachedDoc.doc);
1260
1335
  // Filter entries to only include change entries (exclude snapshots)
1261
1336
  const entriesToApply = newEntryMetadata.filter(em => em.entryType === "doc_create" || em.entryType === "doc_change" || em.entryType === "doc_delete");
1262
1337
  if (entriesToApply.length === 0) {
@@ -1340,12 +1415,12 @@ class BaseMindooDB {
1340
1415
  // Clone the cached document to avoid "outdated document" error
1341
1416
  // This happens when the document has been wrapped and returned to the user
1342
1417
  // Automerge marks documents as outdated when they're accessed, preventing direct mutation
1343
- const clonedDoc = Automerge.clone(cachedDoc.doc);
1418
+ const clonedDoc = automerge_adapter_1.Automerge.clone(cachedDoc.doc);
1344
1419
  // Apply all changes at once (Automerge handles dependency ordering)
1345
- const result = Automerge.applyChanges(clonedDoc, changeBytes);
1420
+ const result = automerge_adapter_1.Automerge.applyChanges(clonedDoc, changeBytes);
1346
1421
  const updatedDoc = result[0];
1347
1422
  // Check if document actually changed
1348
- const headsAfter = Automerge.getHeads(updatedDoc);
1423
+ const headsAfter = automerge_adapter_1.Automerge.getHeads(updatedDoc);
1349
1424
  const headsChanged = JSON.stringify(headsBefore) !== JSON.stringify(headsAfter);
1350
1425
  if (!headsChanged) {
1351
1426
  this.logger.debug(`Document ${docId} heads unchanged after applying new entries`);
@@ -1385,7 +1460,7 @@ class BaseMindooDB {
1385
1460
  // Get all entry metadata for this document
1386
1461
  // TODO: Implement loading from last snapshot if available
1387
1462
  this.logger.debug(`Getting all entry hashes for document ${docId}`);
1388
- const allEntryMetadata = await this.store.findNewEntriesForDoc([], docId);
1463
+ const allEntryMetadata = await this.scanAllMetadata(this.store, { docId });
1389
1464
  this.logger.debug(`Found ${allEntryMetadata.length} total entry hashes for document ${docId}`);
1390
1465
  if (allEntryMetadata.length === 0) {
1391
1466
  this.logger.debug(`No entry hashes found for document ${docId}, returning null`);
@@ -1447,8 +1522,8 @@ class BaseMindooDB {
1447
1522
  // This deserializes a full document snapshot from binary data
1448
1523
  // According to Automerge docs: load() is equivalent to init() followed by loadIncremental()
1449
1524
  this.logger.debug(`Loading snapshot into Automerge document`);
1450
- doc = Automerge.load(decryptedSnapshot);
1451
- this.logger.debug(`Successfully loaded snapshot, document heads: ${JSON.stringify(Automerge.getHeads(doc))}`);
1525
+ doc = automerge_adapter_1.Automerge.load(decryptedSnapshot);
1526
+ this.logger.debug(`Successfully loaded snapshot, document heads: ${JSON.stringify(automerge_adapter_1.Automerge.getHeads(doc))}`);
1452
1527
  // Register the snapshot's automerge hash -> entry ID mapping
1453
1528
  const parsed = (0, idGeneration_1.parseDocEntryId)(snapshotData.id);
1454
1529
  if (parsed) {
@@ -1460,8 +1535,8 @@ class BaseMindooDB {
1460
1535
  // If we don't have a snapshot, start from scratch
1461
1536
  if (!doc) {
1462
1537
  this.logger.debug(`Initializing new Automerge document for ${docId}`);
1463
- doc = Automerge.init();
1464
- this.logger.debug(`Initialized empty document, heads: ${JSON.stringify(Automerge.getHeads(doc))}`);
1538
+ doc = automerge_adapter_1.Automerge.init();
1539
+ this.logger.debug(`Initialized empty document, heads: ${JSON.stringify(automerge_adapter_1.Automerge.getHeads(doc))}`);
1465
1540
  }
1466
1541
  // Sort entries by timestamp
1467
1542
  entriesToLoad.sort((a, b) => a.createdAt - b.createdAt);
@@ -1472,7 +1547,7 @@ class BaseMindooDB {
1472
1547
  this.logger.debug(`Retrieved ${entries.length} entries from store for document ${docId}`);
1473
1548
  this.logger.debug(`Loading document ${docId}: found ${entries.length} entries to apply (${startFromSnapshot ? 'starting from snapshot' : 'starting from scratch'})`);
1474
1549
  // Log current document state before applying entries
1475
- this.logger.debug(`Document state before applying entries: heads=${JSON.stringify(Automerge.getHeads(doc))}`);
1550
+ this.logger.debug(`Document state before applying entries: heads=${JSON.stringify(automerge_adapter_1.Automerge.getHeads(doc))}`);
1476
1551
  // Filter entries for admin-only mode first
1477
1552
  const validEntries = entries.filter(entryData => {
1478
1553
  if (this._isAdminOnlyDb && entryData.createdByPublicKey !== this.getAdminPublicKey()) {
@@ -1551,10 +1626,10 @@ class BaseMindooDB {
1551
1626
  if (changeBytes.length > 0) {
1552
1627
  this.logger.debug(`Applying ${changeBytes.length} changes to document ${docId} using batch applyChanges`);
1553
1628
  try {
1554
- const result = Automerge.applyChanges(doc, changeBytes);
1629
+ const result = automerge_adapter_1.Automerge.applyChanges(doc, changeBytes);
1555
1630
  doc = result[0];
1556
1631
  this.logger.debug(`Successfully applied ${changeBytes.length} changes to document ${docId}`);
1557
- this.logger.debug(`Document state after applying changes: heads=${JSON.stringify(Automerge.getHeads(doc))}`);
1632
+ this.logger.debug(`Document state after applying changes: heads=${JSON.stringify(automerge_adapter_1.Automerge.getHeads(doc))}`);
1558
1633
  }
1559
1634
  catch (error) {
1560
1635
  this.logger.error(`Error applying changes to document ${docId}:`, error);
@@ -1566,7 +1641,7 @@ class BaseMindooDB {
1566
1641
  }
1567
1642
  // Extract metadata from document (doc is guaranteed to be defined at this point)
1568
1643
  this.logger.debug(`All entries applied successfully for document ${docId}`);
1569
- this.logger.debug(`Final document heads: ${JSON.stringify(Automerge.getHeads(doc))}`);
1644
+ this.logger.debug(`Final document heads: ${JSON.stringify(automerge_adapter_1.Automerge.getHeads(doc))}`);
1570
1645
  const payload = doc;
1571
1646
  // Check if document was deleted by looking for a "doc_delete" type entry
1572
1647
  const hasDeleteEntry = allEntryMetadata.some(em => em.entryType === "doc_delete");
@@ -1594,6 +1669,50 @@ class BaseMindooDB {
1594
1669
  this.logger.debug(`===== Successfully loaded document ${docId} and cached it =====`);
1595
1670
  return internalDoc;
1596
1671
  }
1672
+ /**
1673
+ * Convert an Automerge document to a plain JS object, converting Text objects to strings.
1674
+ * If using native Automerge (react-native-automerge-generated), this uses the native
1675
+ * materialize() method which properly converts Text objects to strings.
1676
+ * Falls back to direct access if native backend is not available.
1677
+ */
1678
+ convertAutomergeToJS(doc) {
1679
+ // Check if this document has a native Automerge handle attached
1680
+ // The native implementation attaches metadata with Symbol.for('_am_meta')
1681
+ const STATE = Symbol.for('_am_meta');
1682
+ const meta = doc[STATE];
1683
+ if (meta && meta.handle && typeof meta.handle.materialize === 'function') {
1684
+ // Use native materialize() which properly converts Text objects to strings
1685
+ try {
1686
+ const materialized = meta.handle.materialize('/');
1687
+ return materialized;
1688
+ }
1689
+ catch (error) {
1690
+ console.error('[MindooDB] Failed to materialize document:', error);
1691
+ // Fall through to direct access
1692
+ }
1693
+ }
1694
+ // Fallback: direct access (for WASM or if native fails)
1695
+ const result = {};
1696
+ const keys = Object.keys(doc);
1697
+ for (const key of keys) {
1698
+ const value = doc[key];
1699
+ if (value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Uint8Array)) {
1700
+ result[key] = this.convertAutomergeToJS(value);
1701
+ }
1702
+ else if (Array.isArray(value)) {
1703
+ result[key] = value.map(item => {
1704
+ if (item !== null && typeof item === 'object' && !Array.isArray(item) && !(item instanceof Uint8Array)) {
1705
+ return this.convertAutomergeToJS(item);
1706
+ }
1707
+ return item;
1708
+ });
1709
+ }
1710
+ else {
1711
+ result[key] = value;
1712
+ }
1713
+ }
1714
+ return result;
1715
+ }
1597
1716
  /**
1598
1717
  * Wrap an internal document in the MindooDoc interface.
1599
1718
  * This is the read-only wrapper - write methods throw errors.
@@ -1626,7 +1745,11 @@ class BaseMindooDB {
1626
1745
  getCreatedAt: () => internalDoc.createdAt,
1627
1746
  getLastModified: () => internalDoc.lastModified,
1628
1747
  isDeleted: () => internalDoc.isDeleted,
1629
- getData: () => createReadOnlyProxy(internalDoc.doc),
1748
+ getData: () => {
1749
+ // Convert Automerge document to plain JS object, converting Text objects to strings
1750
+ const jsDoc = this.convertAutomergeToJS(internalDoc.doc);
1751
+ return createReadOnlyProxy(jsDoc);
1752
+ },
1630
1753
  // ========== Attachment Write Methods ==========
1631
1754
  // These throw errors in the read-only wrapper
1632
1755
  addAttachment: async () => {
@@ -2019,27 +2142,16 @@ class BaseMindooDB {
2019
2142
  throw new Error(`[BaseMindooDB] Cannot pull entries from the incompatible store ${this.store.getId()}`);
2020
2143
  }
2021
2144
  this.logger.info(`Pulling entries from remote store ${remoteStore.getId()}`);
2022
- // Get all entry IDs we already have in our local store
2023
- const localEntryIds = await this.store.getAllIds();
2024
- this.logger.debug(`Local store has ${localEntryIds.length} entry IDs`);
2025
- // Find entries in the remote store that we don't have
2026
- const newEntryMetadata = await remoteStore.findNewEntries(localEntryIds);
2027
- this.logger.debug(`Found ${newEntryMetadata.length} new entries in remote store`);
2028
- if (newEntryMetadata.length === 0) {
2145
+ const transferred = await this.syncEntriesFromStore(remoteStore, this.store);
2146
+ this.logger.debug(`Transferred ${transferred} entries from remote store`);
2147
+ if (transferred === 0) {
2029
2148
  this.logger.debug(`No new entries to pull`);
2030
2149
  return;
2031
2150
  }
2032
- // Get the full entries from the remote store
2033
- const newEntries = await remoteStore.getEntries(newEntryMetadata.map(em => em.id));
2034
- this.logger.debug(`Retrieved ${newEntries.length} entries from remote store`);
2035
- // Store all entries in our local store
2036
- // The putEntries method handles deduplication (no-op if entry already exists)
2037
- await this.store.putEntries(newEntries);
2038
- this.logger.debug(`Stored ${newEntries.length} entries in local store`);
2039
2151
  // Sync the local store to process the new entries
2040
2152
  // This will update the index, cache, and processedEntryIds
2041
2153
  await this.syncStoreChanges();
2042
- this.logger.info(`Pull complete, synced ${newEntries.length} entries`);
2154
+ this.logger.info(`Pull complete, synced ${transferred} entries`);
2043
2155
  }
2044
2156
  /**
2045
2157
  * Push changes to a remote content-addressed store.
@@ -2057,23 +2169,13 @@ class BaseMindooDB {
2057
2169
  throw new Error(`[BaseMindooDB] Cannot push entries to the incompatible store ${this.store.getId()}`);
2058
2170
  }
2059
2171
  this.logger.info(`Pushing entries to remote store ${remoteStore.getId()}`);
2060
- // Get all entry IDs the remote store already has
2061
- const remoteEntryIds = await remoteStore.getAllIds();
2062
- this.logger.debug(`Remote store has ${remoteEntryIds.length} entry IDs`);
2063
- // Find entries in our local store that the remote doesn't have
2064
- const newEntryMetadata = await this.store.findNewEntries(remoteEntryIds);
2065
- this.logger.debug(`Found ${newEntryMetadata.length} new entries to push`);
2066
- if (newEntryMetadata.length === 0) {
2172
+ const transferred = await this.syncEntriesFromStore(this.store, remoteStore);
2173
+ this.logger.debug(`Transferred ${transferred} entries to remote store`);
2174
+ if (transferred === 0) {
2067
2175
  this.logger.debug(`No new entries to push`);
2068
2176
  return;
2069
2177
  }
2070
- // Get the full entries from our local store
2071
- const newEntries = await this.store.getEntries(newEntryMetadata.map(em => em.id));
2072
- this.logger.debug(`Retrieved ${newEntries.length} entries from local store`);
2073
- // Store all entries in the remote store
2074
- // The putEntries method handles deduplication (no-op if entry already exists)
2075
- await remoteStore.putEntries(newEntries);
2076
- this.logger.info(`Pushed ${newEntries.length} entries to remote store`);
2178
+ this.logger.info(`Pushed ${transferred} entries to remote store`);
2077
2179
  }
2078
2180
  }
2079
2181
  exports.BaseMindooDB = BaseMindooDB;