mindoodb 0.0.1 → 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 (206) hide show
  1. package/README.md +97 -24
  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 +19 -2
  15. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
  16. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +133 -22
  17. package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
  18. package/dist/appendonlystores/network/HttpTransport.d.ts +20 -3
  19. package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
  20. package/dist/appendonlystores/network/HttpTransport.js +136 -21
  21. package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
  22. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +33 -3
  23. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
  24. package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +148 -27
  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 +38 -4
  42. package/dist/core/BaseMindooDB.d.ts.map +1 -1
  43. package/dist/core/BaseMindooDB.js +810 -329
  44. package/dist/core/BaseMindooDB.js.map +1 -1
  45. package/dist/core/BaseMindooTenant.d.ts +42 -6
  46. package/dist/core/BaseMindooTenant.d.ts.map +1 -1
  47. package/dist/core/BaseMindooTenant.js +259 -93
  48. package/dist/core/BaseMindooTenant.js.map +1 -1
  49. package/dist/core/BaseMindooTenantDirectory.d.ts +3 -1
  50. package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
  51. package/dist/core/BaseMindooTenantDirectory.js +50 -40
  52. package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
  53. package/dist/core/BaseMindooTenantFactory.d.ts +25 -29
  54. package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
  55. package/dist/core/BaseMindooTenantFactory.js +175 -73
  56. package/dist/core/BaseMindooTenantFactory.js.map +1 -1
  57. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +68 -0
  58. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -0
  59. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js +659 -0
  60. package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -0
  61. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +50 -4
  62. package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
  63. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +204 -39
  64. package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
  65. package/dist/core/appendonlystores/bloom.d.ts +85 -0
  66. package/dist/core/appendonlystores/bloom.d.ts.map +1 -0
  67. package/dist/core/appendonlystores/bloom.js +228 -0
  68. package/dist/core/appendonlystores/bloom.js.map +1 -0
  69. package/dist/core/appendonlystores/network/AuthenticationService.d.ts +3 -0
  70. package/dist/core/appendonlystores/network/AuthenticationService.d.ts.map +1 -1
  71. package/dist/core/appendonlystores/network/AuthenticationService.js +21 -17
  72. package/dist/core/appendonlystores/network/AuthenticationService.js.map +1 -1
  73. package/dist/core/appendonlystores/network/NetworkTransport.d.ts +36 -2
  74. package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
  75. package/dist/core/appendonlystores/network/types.d.ts +10 -0
  76. package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
  77. package/dist/core/appendonlystores/network/types.js.map +1 -1
  78. package/dist/core/appendonlystores/types.d.ts +137 -1
  79. package/dist/core/appendonlystores/types.d.ts.map +1 -1
  80. package/dist/core/automerge-adapter.d.ts +15 -0
  81. package/dist/core/automerge-adapter.d.ts.map +1 -0
  82. package/dist/core/automerge-adapter.js +73 -0
  83. package/dist/core/automerge-adapter.js.map +1 -0
  84. package/dist/core/crypto/MindooDocSigner.d.ts +3 -1
  85. package/dist/core/crypto/MindooDocSigner.d.ts.map +1 -1
  86. package/dist/core/crypto/MindooDocSigner.js +9 -5
  87. package/dist/core/crypto/MindooDocSigner.js.map +1 -1
  88. package/dist/core/crypto/RSAEncryption.d.ts +3 -1
  89. package/dist/core/crypto/RSAEncryption.d.ts.map +1 -1
  90. package/dist/core/crypto/RSAEncryption.js +13 -9
  91. package/dist/core/crypto/RSAEncryption.js.map +1 -1
  92. package/dist/core/crypto/pbkdf2Iterations.d.ts +12 -0
  93. package/dist/core/crypto/pbkdf2Iterations.d.ts.map +1 -0
  94. package/dist/core/crypto/pbkdf2Iterations.js +55 -0
  95. package/dist/core/crypto/pbkdf2Iterations.js.map +1 -0
  96. package/dist/core/index.d.ts +7 -2
  97. package/dist/core/index.d.ts.map +1 -1
  98. package/dist/core/index.js +30 -1
  99. package/dist/core/index.js.map +1 -1
  100. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts +1 -1
  101. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js +2 -2
  102. package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js.map +1 -1
  103. package/dist/core/indexing/virtualviews/index.d.ts +1 -1
  104. package/dist/core/indexing/virtualviews/index.js +1 -1
  105. package/dist/core/keys/KeyBag.d.ts +36 -13
  106. package/dist/core/keys/KeyBag.d.ts.map +1 -1
  107. package/dist/core/keys/KeyBag.js +96 -31
  108. package/dist/core/keys/KeyBag.js.map +1 -1
  109. package/dist/core/keys/KeyContext.d.ts +4 -0
  110. package/dist/core/keys/KeyContext.d.ts.map +1 -0
  111. package/dist/core/keys/KeyContext.js +11 -0
  112. package/dist/core/keys/KeyContext.js.map +1 -0
  113. package/dist/core/logging/LogLevel.d.ts +21 -0
  114. package/dist/core/logging/LogLevel.d.ts.map +1 -0
  115. package/dist/core/logging/LogLevel.js +56 -0
  116. package/dist/core/logging/LogLevel.js.map +1 -0
  117. package/dist/core/logging/Logger.d.ts +37 -0
  118. package/dist/core/logging/Logger.d.ts.map +1 -0
  119. package/dist/core/logging/Logger.js +3 -0
  120. package/dist/core/logging/Logger.js.map +1 -0
  121. package/dist/core/logging/MindooLogger.d.ts +28 -0
  122. package/dist/core/logging/MindooLogger.d.ts.map +1 -0
  123. package/dist/core/logging/MindooLogger.js +217 -0
  124. package/dist/core/logging/MindooLogger.js.map +1 -0
  125. package/dist/core/logging/index.d.ts +4 -0
  126. package/dist/core/logging/index.d.ts.map +1 -0
  127. package/dist/core/logging/index.js +10 -0
  128. package/dist/core/logging/index.js.map +1 -0
  129. package/dist/core/types.d.ts +313 -77
  130. package/dist/core/types.d.ts.map +1 -1
  131. package/dist/core/types.js +2 -0
  132. package/dist/core/types.js.map +1 -1
  133. package/dist/core/uri/MindooURI.d.ts +58 -0
  134. package/dist/core/uri/MindooURI.d.ts.map +1 -0
  135. package/dist/core/uri/MindooURI.js +169 -0
  136. package/dist/core/uri/MindooURI.js.map +1 -0
  137. package/dist/core/userid/index.d.ts +0 -10
  138. package/dist/core/userid/index.d.ts.map +1 -1
  139. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +541 -0
  140. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -0
  141. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +1334 -0
  142. package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -0
  143. package/dist/node/index.d.ts +1 -0
  144. package/dist/node/index.d.ts.map +1 -1
  145. package/dist/node/index.js +5 -1
  146. package/dist/node/index.js.map +1 -1
  147. package/dist/reactnative/crypto/AESAdapter.d.ts +18 -0
  148. package/dist/reactnative/crypto/AESAdapter.d.ts.map +1 -0
  149. package/dist/reactnative/crypto/AESAdapter.js +112 -0
  150. package/dist/reactnative/crypto/AESAdapter.js.map +1 -0
  151. package/dist/reactnative/crypto/Ed25519Adapter.d.ts +34 -0
  152. package/dist/reactnative/crypto/Ed25519Adapter.d.ts.map +1 -0
  153. package/dist/reactnative/crypto/Ed25519Adapter.js +386 -0
  154. package/dist/reactnative/crypto/Ed25519Adapter.js.map +1 -0
  155. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.d.ts +23 -0
  156. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.d.ts.map +1 -0
  157. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.js +51 -0
  158. package/dist/reactnative/crypto/ExpoGoCryptoAdapter.js.map +1 -0
  159. package/dist/reactnative/crypto/HMACAdapter.d.ts +13 -0
  160. package/dist/reactnative/crypto/HMACAdapter.d.ts.map +1 -0
  161. package/dist/reactnative/crypto/HMACAdapter.js +50 -0
  162. package/dist/reactnative/crypto/HMACAdapter.js.map +1 -0
  163. package/dist/reactnative/crypto/KeyFormatConverter.d.ts +21 -0
  164. package/dist/reactnative/crypto/KeyFormatConverter.d.ts.map +1 -0
  165. package/dist/reactnative/crypto/KeyFormatConverter.js +72 -0
  166. package/dist/reactnative/crypto/KeyFormatConverter.js.map +1 -0
  167. package/dist/reactnative/crypto/PBKDF2Adapter.d.ts +19 -0
  168. package/dist/reactnative/crypto/PBKDF2Adapter.d.ts.map +1 -0
  169. package/dist/reactnative/crypto/PBKDF2Adapter.js +67 -0
  170. package/dist/reactnative/crypto/PBKDF2Adapter.js.map +1 -0
  171. package/dist/reactnative/crypto/QuickCryptoAdapter.d.ts +37 -0
  172. package/dist/reactnative/crypto/QuickCryptoAdapter.d.ts.map +1 -0
  173. package/dist/reactnative/crypto/QuickCryptoAdapter.js +72 -0
  174. package/dist/reactnative/crypto/QuickCryptoAdapter.js.map +1 -0
  175. package/dist/reactnative/crypto/RSAAdapter.d.ts +38 -0
  176. package/dist/reactnative/crypto/RSAAdapter.d.ts.map +1 -0
  177. package/dist/reactnative/crypto/RSAAdapter.js +184 -0
  178. package/dist/reactnative/crypto/RSAAdapter.js.map +1 -0
  179. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.d.ts +33 -0
  180. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.d.ts.map +1 -0
  181. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.js +61 -0
  182. package/dist/reactnative/crypto/ReactNativeCryptoAdapter.js.map +1 -0
  183. package/dist/reactnative/crypto/SHA256Adapter.d.ts +9 -0
  184. package/dist/reactnative/crypto/SHA256Adapter.d.ts.map +1 -0
  185. package/dist/reactnative/crypto/SHA256Adapter.js +29 -0
  186. package/dist/reactnative/crypto/SHA256Adapter.js.map +1 -0
  187. package/dist/reactnative/crypto/SubtleCryptoPolyfill.d.ts +63 -0
  188. package/dist/reactnative/crypto/SubtleCryptoPolyfill.d.ts.map +1 -0
  189. package/dist/reactnative/crypto/SubtleCryptoPolyfill.js +350 -0
  190. package/dist/reactnative/crypto/SubtleCryptoPolyfill.js.map +1 -0
  191. package/dist/reactnative/index.d.ts +8 -0
  192. package/dist/reactnative/index.d.ts.map +1 -0
  193. package/dist/reactnative/index.js +38 -0
  194. package/dist/reactnative/index.js.map +1 -0
  195. package/package.json +51 -6
  196. package/patches/PATCHES.md +111 -0
  197. package/patches/react-native+0.76.9.patch +34 -0
  198. package/patches/react-native-quick-crypto+1.0.7.patch +42 -0
  199. package/scripts/cli.js +21 -0
  200. package/scripts/setup-react-native.js +228 -0
  201. package/templates/reactnative/App.js +252 -0
  202. package/templates/reactnative/app.json +29 -0
  203. package/templates/reactnative/babel.config.js +6 -0
  204. package/templates/reactnative/index.js +26 -0
  205. package/templates/reactnative/metro.config.snippet.js +39 -0
  206. package/templates/reactnative/mindoodb-polyfills.js +116 -0
package/README.md CHANGED
@@ -44,7 +44,7 @@ Traditional databases trust the server. If your hosting provider is compromised,
44
44
  └──────────────────────────────────────────────────────────────────┘
45
45
  ```
46
46
 
47
- **Sync happens through content-addressed stores**: clients exchange only the encrypted entries they're missing. Works peer-to-peer, client-server, or any combination.
47
+ **Sync happens through content-addressed stores**: clients exchange only the encrypted entries they're missing. Works peer-to-peer, client-server, or any combination - for documents and attached files.
48
48
 
49
49
  ## Key Features
50
50
 
@@ -65,37 +65,58 @@ Traditional databases trust the server. If your hosting provider is compromised,
65
65
  npm install mindoodb
66
66
  ```
67
67
 
68
+ > 📱 **React Native / Expo?** See the [React Native setup guide](./docs/reactnative.md) for mobile-specific instructions with native performance.
69
+
70
+ ### Pick Your Runtime
71
+
72
+ | Runtime | Fastest start | Recommended path |
73
+ |---------|---------------|------------------|
74
+ | Node.js | Use `mindoodb` directly in a Node script | [Getting Started](./docs/getting-started.md#nodejs) |
75
+ | Web | Import from `mindoodb/browser` | [Getting Started](./docs/getting-started.md#web-browser) |
76
+ | React Native / Expo | Run `npx mindoodb setup-react-native` in your app root | [React Native Guide](./docs/reactnative.md) |
77
+
78
+ ### React Native Recommendation
79
+
80
+ - Use **native Automerge** (`react-native-automerge-generated`) and native crypto for production.
81
+ - Treat Expo Go / JS fallback as a convenience path for prototyping, not the default production runtime.
82
+
68
83
  ### Create a Tenant and Start Working
69
84
 
70
85
  ```typescript
71
86
  import {
72
87
  BaseMindooTenantFactory,
73
- InMemoryAppendOnlyStoreFactory,
74
- KeyBag
88
+ InMemoryContentAddressedStoreFactory,
89
+ KeyBag,
90
+ PUBLIC_INFOS_KEY_ID
75
91
  } from "mindoodb";
76
92
 
77
93
  // 1. Set up storage (in-memory for demo; use file/server-backed for production)
78
- const storeFactory = new InMemoryAppendOnlyStoreFactory();
94
+ const storeFactory = new InMemoryContentAddressedStoreFactory();
79
95
  const factory = new BaseMindooTenantFactory(storeFactory);
80
96
 
81
97
  // 2. Create a user (generates signing + encryption key pairs)
82
98
  const user = await factory.createUserId("CN=alice/O=acme", "user-password");
83
99
  const keyBag = new KeyBag(user.userEncryptionKeyPair.privateKey, "user-password");
84
100
 
85
- // 3. Create admin keys (for managing users)
86
- const adminKeyPair = await factory.createSigningKeyPair("admin-password");
101
+ // 3. Create admin user (signing + encryption keys used for tenant administration)
102
+ const adminUser = await factory.createUserId("CN=admin/O=acme", "admin-password");
103
+
104
+ // 4. Create required tenant keys directly in KeyBag (canonical key source)
105
+ const tenantId = "acme-corp";
106
+ await keyBag.createTenantKey(tenantId);
107
+ await keyBag.createDocKey(PUBLIC_INFOS_KEY_ID);
87
108
 
88
- // 4. Create a tenant (an organization that shares documents)
89
- const tenant = await factory.createTenant(
90
- "acme-corp",
91
- adminKeyPair.publicKey,
92
- "tenant-key-password",
109
+ // 5. Open tenant
110
+ const tenant = await factory.openTenant(
111
+ tenantId,
112
+ adminUser.userSigningKeyPair.publicKey,
113
+ adminUser.userEncryptionKeyPair.publicKey,
93
114
  user,
94
115
  "user-password",
95
116
  keyBag
96
117
  );
97
118
 
98
- // 5. Open a database and create documents
119
+ // 6. Open a database and create documents
99
120
  const db = await tenant.openDB("contacts");
100
121
  const doc = await db.createDocument();
101
122
 
@@ -105,7 +126,7 @@ await db.changeDoc(doc, async (d) => {
105
126
  data.email = "john@example.com";
106
127
  });
107
128
 
108
- // 6. Read it back
129
+ // 7. Read it back
109
130
  const contacts = await db.getAllDocumentIds();
110
131
  const loaded = await db.getDocument(contacts[0]);
111
132
  console.log(loaded.getData()); // { name: "John Doe", email: "john@example.com" }
@@ -158,7 +179,7 @@ A special **directory** database stores user registrations (admin-only).
158
179
  [Automerge](https://automerge.org/) CRDTs with full history:
159
180
  - Every change is signed and encrypted
160
181
  - Automatic conflict resolution for concurrent edits
161
- - Time travel: reconstruct any historical state of documents (e.g. run queries on historic data)
182
+ - Time travel: reconstruct any historical state of documents (e.g. run queries on historic data) — see [Time Travel Documentation](./docs/timetravel.md)
162
183
 
163
184
  ### Attachments
164
185
  Files attached to documents:
@@ -179,15 +200,14 @@ MindooDB provides a flexible, **incremental indexing** facility:
179
200
  // Incremental indexing: process only what's new
180
201
  let cursor = null;
181
202
  while (true) {
182
- const { documents, cursor: newCursor } = await db.processChangesSince(cursor);
183
- for (const doc of documents) {
203
+ for await (const { doc, cursor: newCursor } of db.iterateChangesSince(cursor)) {
184
204
  if (doc.isDeleted()) {
185
- mySearchIndex.remove(doc.id);
205
+ mySearchIndex.remove(doc.getId());
186
206
  } else {
187
207
  mySearchIndex.update(doc); // Flexsearch, Lunr, or custom
188
208
  }
209
+ cursor = newCursor;
189
210
  }
190
- cursor = newCursor;
191
211
  await sleep(1000);
192
212
  }
193
213
  ```
@@ -201,20 +221,20 @@ All encryption keys are stored in the **KeyBag**—a local, password-protected k
201
221
  | **`default` key** | Used when no other key is specified | All tenant members |
202
222
  | **Named keys** | Fine-grained access for sensitive docs | Only users you share it with |
203
223
 
204
- Keys are distributed offline (email, phone, in-person). The `default` key is typically shared during onboarding; named keys are shared as needed for specific documents.
224
+ Keys are distributed offline (e.g. password protected via email or a shared drive). The `default` key is typically shared during onboarding; named keys are shared as needed for specific documents.
205
225
 
206
226
  ## Security
207
227
 
208
228
  ### Cryptographic Guarantees
209
- - **Signatures**: Ed25519 on every change—proves who wrote it
210
- - **Encryption**: AES-256-GCM—servers see only ciphertext
211
- - **Integrity**: Changes are hash-chained—tampering breaks the chain
229
+ - **Signatures**: Ed25519 on every change - proves who wrote it
230
+ - **Encryption**: AES-256-GCM - servers see only ciphertext
231
+ - **Integrity**: Changes are hash-chained - tampering breaks the chain
212
232
 
213
233
  ### User Revocation
214
234
  Revoked users:
215
235
  - ❌ Cannot sync with peers or servers
216
236
  - ❌ Cannot make new changes (signatures rejected)
217
- - ⚠️ Can still read previously-synced data (fundamental trade-off of E2E encryption)
237
+ - ⚠️ Can currently read previously-synced local data (planned: data wipe on first connect after revocation)
218
238
 
219
239
  MindooDB includes **revocation timestamp protection** to prevent backdated changes from revoked users. See: [Revocation Protection](./docs/revocation-timestamp-protection.md)
220
240
 
@@ -224,6 +244,13 @@ Append-only storage means nothing is ever deleted:
224
244
  - Cryptographic proof of all operations
225
245
  - GDPR compliance via `purgeDocHistory()` when legally required
226
246
 
247
+ ## Supported Platforms
248
+
249
+ - ✅ **Node.js** - Server-side and desktop apps
250
+ - ✅ **Web Browsers** - Progressive web apps with Web Crypto API
251
+ - ✅ **React Native / Expo** - iOS and Android with native Automerge (Rust via JSI)
252
+ - ✅ **Electron** - Cross-platform desktop apps
253
+
227
254
  ## Use Cases
228
255
 
229
256
  - **Multi-Tenant SaaS**: Each customer isolated with encrypted data
@@ -231,20 +258,66 @@ Append-only storage means nothing is ever deleted:
231
258
  - **Secure File Sharing**: Named keys for need-to-know access
232
259
  - **Audit-Critical Systems**: Tamperproof history meets compliance requirements
233
260
  - **Offline-First Apps**: Full functionality without network; sync when connected
261
+ - **Mobile Apps**: End-to-end encrypted sync with native performance
234
262
 
235
263
  See: [Use Cases Documentation](./docs/usecases/README.md)
236
264
 
237
265
  ## Documentation
238
266
 
267
+ - [Getting Started](./docs/getting-started.md) — Fast setup for Node.js, Web, and React Native
268
+ - [Example Snippets](./docs/examples/README.md) — Copy-paste Todo starters for all runtimes
239
269
  - [Architecture Specification](./docs/specification.md) — Full technical details
270
+ - [React Native Guide](./docs/reactnative.md) — Native Automerge setup and troubleshooting
240
271
  - [Virtual Views](./docs/virtualview.md) — Aggregations and cross-database views
241
272
  - [Data Indexing](./docs/dataindexing.md) — Incremental indexing and search integration
273
+ - [Time Travel](./docs/timetravel.md) — Historical document retrieval and history traversal
242
274
  - [P2P Sync](./docs/p2psync.md) — Peer-to-peer synchronization
243
275
  - [Attachments](./docs/attachments.md) — File storage and streaming
244
276
 
277
+ ## Testing
278
+
279
+ Run tests from the command line:
280
+
281
+ ```bash
282
+ # Node.js unit/integration tests (Jest)
283
+ npm test
284
+
285
+ # Install Chromium once for browser tests
286
+ npm run test:browser:install
287
+
288
+ # Real browser runtime tests (Playwright + headless Chromium)
289
+ npm run test:browser
290
+
291
+ # Run Node + browser lanes
292
+ npm run test:all
293
+ ```
294
+
295
+ ### Test coverage by environment
296
+
297
+ | Environment | Command | What is covered today |
298
+ |-------------|---------|------------------------|
299
+ | Node.js | `npm test` | Full Jest suite for core APIs (documents, sync logic, indexing, virtual views, settings, trust model, attachments, etc.) |
300
+ | Browser | `npm run test:browser` | Real Chromium runtime via Playwright, including browser entrypoint usage, document lifecycle, real HTTP sync endpoint flows, and browser Virtual View update behavior |
301
+ | React Native / Expo | `npm test -- ReactNativeCrypto.test.ts` | Crypto adapter behavior in Jest (uses `src/__mocks__/expo-standard-web-crypto.ts`), not a device/simulator E2E run |
302
+
303
+ ### Browser sync test behavior
304
+
305
+ - Browser tests run in headless Chromium and execute MindooDB browser code in a real page runtime.
306
+ - During test setup, an ephemeral HTTP server is started automatically and exposes the real sync endpoints.
307
+ - Sync assertions use real HTTP requests against that temporary endpoint (no mocked transport for sync tests).
308
+ - The server binds to an OS-assigned free port and is shut down after the suite completes.
309
+
310
+ ### Current parity status
311
+
312
+ - The package exports and core API shape are aligned across Node.js, browser, and React Native entrypoints.
313
+ - Node and browser now have executable CLI lanes with runtime validation.
314
+ - React Native coverage is currently adapter-focused in Jest and does not yet validate full app-level behavior inside a real React Native runtime.
315
+ - For high confidence in three-environment parity, add a React Native integration lane (Expo/Detox or RN test app) that exercises document lifecycle, sync, and virtual view updates on device/simulator.
316
+ - For Expo Go / JS fallback scenarios, PBKDF2 iterations can be tuned at runtime; native RN builds should keep strong defaults.
317
+
245
318
  ## Support
246
319
 
247
- Need help, have questions, or want to request a feature? We're here to help! :-)
320
+ Need commercial support, have questions, or want to request a feature? We're here to help! :-)
248
321
 
249
322
  - 🐛 **Bug Reports**: [Open an issue on GitHub](https://github.com/klehmann/mindoodb/issues)
250
323
  - 💬 **Questions & Discussions**: [GitHub Discussions](https://github.com/klehmann/mindoodb/discussions)
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Mock for expo-standard-web-crypto
3
+ * Uses Node.js crypto for getRandomValues in tests
4
+ */
5
+ export declare function getRandomValues(array: Uint8Array): Uint8Array;
6
+ declare const _default: {
7
+ getRandomValues: typeof getRandomValues;
8
+ };
9
+ export default _default;
10
+ //# sourceMappingURL=expo-standard-web-crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo-standard-web-crypto.d.ts","sourceRoot":"","sources":["../../src/__mocks__/expo-standard-web-crypto.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAI7D;;;;AAGD,wBAEE"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /**
3
+ * Mock for expo-standard-web-crypto
4
+ * Uses Node.js crypto for getRandomValues in tests
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.getRandomValues = getRandomValues;
11
+ const crypto_1 = __importDefault(require("crypto"));
12
+ // Export getRandomValues directly for CommonJS compatibility
13
+ function getRandomValues(array) {
14
+ const randomBytes = crypto_1.default.randomBytes(array.length);
15
+ array.set(randomBytes);
16
+ return array;
17
+ }
18
+ // Also export as default for ESM compatibility
19
+ exports.default = {
20
+ getRandomValues,
21
+ };
22
+ //# sourceMappingURL=expo-standard-web-crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo-standard-web-crypto.js","sourceRoot":"","sources":["../../src/__mocks__/expo-standard-web-crypto.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AAKH,0CAIC;AAPD,oDAA4B;AAE5B,6DAA6D;AAC7D,SAAgB,eAAe,CAAC,KAAiB;IAC/C,MAAM,WAAW,GAAG,gBAAM,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrD,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+CAA+C;AAC/C,kBAAe;IACb,eAAe;CAChB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { ContentAddressedStoreFactory, CreateStoreResult, OpenStoreOptions } from "../core/types";
2
+ /**
3
+ * Factory for creating persistent on-disk content-addressed stores.
4
+ */
5
+ export declare class BasicOnDiskContentAddressedStoreFactory implements ContentAddressedStoreFactory {
6
+ createStore(dbId: string, options?: OpenStoreOptions): CreateStoreResult;
7
+ }
8
+ //# sourceMappingURL=BasicOnDiskContentAddressedStoreFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BasicOnDiskContentAddressedStoreFactory.d.ts","sourceRoot":"","sources":["../../src/appendonlystores/BasicOnDiskContentAddressedStoreFactory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAElG;;GAEG;AACH,qBAAa,uCAAwC,YAAW,4BAA4B;IAC1F,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,iBAAiB;CAKzE"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BasicOnDiskContentAddressedStoreFactory = void 0;
4
+ const BasicOnDiskContentAddressedStore_1 = require("../node/appendonlystores/BasicOnDiskContentAddressedStore");
5
+ /**
6
+ * Factory for creating persistent on-disk content-addressed stores.
7
+ */
8
+ class BasicOnDiskContentAddressedStoreFactory {
9
+ createStore(dbId, options) {
10
+ return {
11
+ docStore: new BasicOnDiskContentAddressedStore_1.BasicOnDiskContentAddressedStore(dbId, undefined, options),
12
+ };
13
+ }
14
+ }
15
+ exports.BasicOnDiskContentAddressedStoreFactory = BasicOnDiskContentAddressedStoreFactory;
16
+ //# sourceMappingURL=BasicOnDiskContentAddressedStoreFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BasicOnDiskContentAddressedStoreFactory.js","sourceRoot":"","sources":["../../src/appendonlystores/BasicOnDiskContentAddressedStoreFactory.ts"],"names":[],"mappings":";;;AAAA,gHAA6G;AAG7G;;GAEG;AACH,MAAa,uCAAuC;IAClD,WAAW,CAAC,IAAY,EAAE,OAA0B;QAClD,OAAO;YACL,QAAQ,EAAE,IAAI,mEAAgC,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC;SACzE,CAAC;IACJ,CAAC;CACF;AAND,0FAMC"}
@@ -1,5 +1,5 @@
1
1
  import { ContentAddressedStoreFactory, CreateStoreResult, OpenStoreOptions } from "../core/types";
2
2
  export declare class InMemoryContentAddressedStoreFactory implements ContentAddressedStoreFactory {
3
- createStore(dbId: string, _options?: OpenStoreOptions): CreateStoreResult;
3
+ createStore(dbId: string, options?: OpenStoreOptions): CreateStoreResult;
4
4
  }
5
5
  //# sourceMappingURL=InMemoryContentAddressedStoreFactory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InMemoryContentAddressedStoreFactory.d.ts","sourceRoot":"","sources":["../../src/appendonlystores/InMemoryContentAddressedStoreFactory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAElG,qBAAa,oCAAqC,YAAW,4BAA4B;IACvF,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,iBAAiB;CAS1E"}
1
+ {"version":3,"file":"InMemoryContentAddressedStoreFactory.d.ts","sourceRoot":"","sources":["../../src/appendonlystores/InMemoryContentAddressedStoreFactory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAElG,qBAAa,oCAAqC,YAAW,4BAA4B;IACvF,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,iBAAiB;CASzE"}
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InMemoryContentAddressedStoreFactory = void 0;
4
4
  const InMemoryContentAddressedStore_1 = require("../core/appendonlystores/InMemoryContentAddressedStore");
5
5
  class InMemoryContentAddressedStoreFactory {
6
- createStore(dbId, _options) {
6
+ createStore(dbId, options) {
7
7
  // For in-memory stores, we use a single store for both documents and attachments
8
8
  // (no separate attachment store needed for simple/test scenarios)
9
9
  // Note: options are ignored for in-memory stores but accepted for interface compatibility
10
10
  return {
11
- docStore: new InMemoryContentAddressedStore_1.InMemoryContentAddressedStore(dbId),
11
+ docStore: new InMemoryContentAddressedStore_1.InMemoryContentAddressedStore(dbId, undefined, options),
12
12
  // attachmentStore not provided - will use docStore for attachments
13
13
  };
14
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"InMemoryContentAddressedStoreFactory.js","sourceRoot":"","sources":["../../src/appendonlystores/InMemoryContentAddressedStoreFactory.ts"],"names":[],"mappings":";;;AAAA,0GAAuG;AAGvG,MAAa,oCAAoC;IAC/C,WAAW,CAAC,IAAY,EAAE,QAA2B;QACnD,iFAAiF;QACjF,kEAAkE;QAClE,0FAA0F;QAC1F,OAAO;YACL,QAAQ,EAAE,IAAI,6DAA6B,CAAC,IAAI,CAAC;YACjD,mEAAmE;SACpE,CAAC;IACJ,CAAC;CACF;AAVD,oFAUC"}
1
+ {"version":3,"file":"InMemoryContentAddressedStoreFactory.js","sourceRoot":"","sources":["../../src/appendonlystores/InMemoryContentAddressedStoreFactory.ts"],"names":[],"mappings":";;;AAAA,0GAAuG;AAGvG,MAAa,oCAAoC;IAC/C,WAAW,CAAC,IAAY,EAAE,OAA0B;QAClD,iFAAiF;QACjF,kEAAkE;QAClE,0FAA0F;QAC1F,OAAO;YACL,QAAQ,EAAE,IAAI,6DAA6B,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC;YACrE,mEAAmE;SACpE,CAAC;IACJ,CAAC;CACF;AAVD,oFAUC"}
@@ -1,7 +1,9 @@
1
1
  import type { ContentAddressedStore } from "../../core/types";
2
- import type { StoreEntry, StoreEntryMetadata } from "../../core/types";
2
+ import type { StoreEntry, StoreEntryMetadata, StoreEntryType, StoreScanCursor, StoreScanFilters, StoreScanResult, StoreIdBloomSummary, StoreCompactionStatus } from "../../core/types";
3
3
  import type { CryptoAdapter } from "../../core/crypto/CryptoAdapter";
4
4
  import type { NetworkTransport } from "../../core/appendonlystores/network/NetworkTransport";
5
+ import type { NetworkSyncCapabilities } from "../../core/appendonlystores/network/types";
6
+ import { Logger } from "../../core/logging";
5
7
  /**
6
8
  * Client-side network ContentAddressedStore that forwards all operations to a remote server.
7
9
  *
@@ -26,6 +28,8 @@ export declare class ClientNetworkContentAddressedStore implements ContentAddres
26
28
  private cryptoAdapter;
27
29
  private accessToken;
28
30
  private tokenExpiry;
31
+ private logger;
32
+ private capabilitiesCache;
29
33
  /**
30
34
  * Create a new ClientNetworkContentAddressedStore.
31
35
  *
@@ -35,8 +39,9 @@ export declare class ClientNetworkContentAddressedStore implements ContentAddres
35
39
  * @param username The username for authentication
36
40
  * @param signingKey The user's private signing key (for signing challenges)
37
41
  * @param privateEncryptionKey The user's private RSA key (for decrypting received entries)
42
+ * @param logger Optional logger instance
38
43
  */
39
- constructor(dbId: string, transport: NetworkTransport, cryptoAdapter: CryptoAdapter, username: string, signingKey: CryptoKey, privateEncryptionKey: CryptoKey | string);
44
+ constructor(dbId: string, transport: NetworkTransport, cryptoAdapter: CryptoAdapter, username: string, signingKey: CryptoKey, privateEncryptionKey: CryptoKey | string, logger?: Logger);
40
45
  getId(): string;
41
46
  /**
42
47
  * Store entries to the remote store.
@@ -68,11 +73,23 @@ export declare class ClientNetworkContentAddressedStore implements ContentAddres
68
73
  * Find new entries for a specific document from the remote store.
69
74
  */
70
75
  findNewEntriesForDoc(knownIds: string[], docId: string): Promise<StoreEntryMetadata[]>;
76
+ /**
77
+ * Find entries by type and creation date range from the remote store.
78
+ */
79
+ findEntries(type: StoreEntryType, creationDateFrom: number | null, creationDateUntil: number | null): Promise<StoreEntryMetadata[]>;
71
80
  /**
72
81
  * Get all entry IDs from the remote store.
73
82
  * Used for synchronization to identify which entries the remote has.
74
83
  */
75
84
  getAllIds(): Promise<string[]>;
85
+ /**
86
+ * Cursor-based metadata scan from the remote store.
87
+ * Uses transport-native scan support when available, with a compatibility fallback.
88
+ */
89
+ scanEntriesSince(cursor: StoreScanCursor | null, limit?: number, filters?: StoreScanFilters): Promise<StoreScanResult>;
90
+ getIdBloomSummary(): Promise<StoreIdBloomSummary>;
91
+ getCapabilities(): Promise<NetworkSyncCapabilities>;
92
+ getCompactionStatus(): Promise<StoreCompactionStatus>;
76
93
  /**
77
94
  * Resolve dependencies for an entry.
78
95
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ClientNetworkContentAddressedStore.d.ts","sourceRoot":"","sources":["../../../src/appendonlystores/network/ClientNetworkContentAddressedStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sDAAsD,CAAC;AAK7F;;;;;;;;;;;;;GAaG;AACH,qBAAa,kCAAmC,YAAW,qBAAqB;IAC9E,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,oBAAoB,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,aAAa,CAAgB;IAGrC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,WAAW,CAAa;IAEhC;;;;;;;;;OASG;gBAED,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,gBAAgB,EAC3B,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,SAAS,EACrB,oBAAoB,EAAE,SAAS,GAAG,MAAM;IAW1C,KAAK,IAAI,MAAM;IAIf;;;OAGG;IACG,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAatD;;;;;OAKG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAmBtD;;;;;OAKG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAclD;;;;;OAKG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAUvE;;OAEG;IACG,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAU5F;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAUpC;;;;OAIG;IACG,mBAAmB,CACvB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,MAAM,EAAE,CAAC;IAUpB;;;;;;;;OAQG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;OAEG;YACW,mBAAmB;IA8CjC;;OAEG;YACW,aAAa;IAa3B;;;OAGG;YACW,qBAAqB;IAkCnC;;;OAGG;IACH,cAAc,IAAI,IAAI;CAIvB"}
1
+ {"version":3,"file":"ClientNetworkContentAddressedStore.d.ts","sourceRoot":"","sources":["../../../src/appendonlystores/network/ClientNetworkContentAddressedStore.ts"],"names":[],"mappings":"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"}