@fireproof/core 0.4.0 → 0.5.0

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 (53) hide show
  1. package/README.md +20 -22
  2. package/dist/src/fireproof.d.ts +45 -15
  3. package/dist/src/fireproof.js +97 -27
  4. package/dist/src/fireproof.js.map +1 -1
  5. package/dist/src/fireproof.mjs +97 -28
  6. package/dist/src/fireproof.mjs.map +1 -1
  7. package/package.json +2 -2
  8. package/src/database.js +31 -13
  9. package/src/db-index.js +19 -9
  10. package/src/fireproof.js +45 -5
  11. package/src/prolly.js +2 -1
  12. package/src/valet.js +3 -2
  13. package/dist/blockstore.js +0 -242
  14. package/dist/clock.js +0 -355
  15. package/dist/crypto.js +0 -59
  16. package/dist/database.js +0 -308
  17. package/dist/db-index.js +0 -314
  18. package/dist/fireproof.js +0 -83
  19. package/dist/hooks/use-fireproof.js +0 -100
  20. package/dist/listener.js +0 -110
  21. package/dist/main.js +0 -2
  22. package/dist/main.js.LICENSE.txt +0 -17
  23. package/dist/prolly.js +0 -316
  24. package/dist/sha1.js +0 -74
  25. package/dist/src/blockstore.js +0 -242
  26. package/dist/src/clock.js +0 -355
  27. package/dist/src/crypto.js +0 -59
  28. package/dist/src/database.js +0 -312
  29. package/dist/src/db-index.js +0 -314
  30. package/dist/src/index.d.ts +0 -321
  31. package/dist/src/index.js +0 -38936
  32. package/dist/src/index.js.map +0 -1
  33. package/dist/src/index.mjs +0 -38931
  34. package/dist/src/index.mjs.map +0 -1
  35. package/dist/src/listener.js +0 -108
  36. package/dist/src/prolly.js +0 -319
  37. package/dist/src/sha1.js +0 -74
  38. package/dist/src/utils.js +0 -16
  39. package/dist/src/valet.js +0 -262
  40. package/dist/test/block.js +0 -57
  41. package/dist/test/clock.test.js +0 -556
  42. package/dist/test/db-index.test.js +0 -231
  43. package/dist/test/fireproof.test.js +0 -444
  44. package/dist/test/fulltext.test.js +0 -61
  45. package/dist/test/helpers.js +0 -39
  46. package/dist/test/hydrator.test.js +0 -142
  47. package/dist/test/listener.test.js +0 -103
  48. package/dist/test/prolly.test.js +0 -162
  49. package/dist/test/proofs.test.js +0 -45
  50. package/dist/test/reproduce-fixture-bug.test.js +0 -57
  51. package/dist/test/valet.test.js +0 -56
  52. package/dist/utils.js +0 -16
  53. package/dist/valet.js +0 -262
package/README.md CHANGED
@@ -8,9 +8,28 @@ to offer a new kind of database that:
8
8
 
9
9
  Learn more about the [concepts and architecture behind Fireproof](https://fireproof.storage/documentation/how-the-database-engine-works/), or jump to the [quick start](#quick-start) for React and server-side examples.
10
10
 
11
+ ## Quick Start
12
+
13
+ Look in the `examples/` directory for projects using the database, or see [examples on CodePen](https://codepen.io/jchrisa/pen/GRYJJEM). If you are adding Fireproof to an existing page, just install it and try some operations.
14
+
15
+ ```sh
16
+ npm install @fireproof/core
17
+ ```
18
+
19
+ In your `app.js` or `app.tsx` file:
20
+
21
+ ```js
22
+ import { Fireproof } from '@fireproof/core'
23
+ const fireproof = Fireproof.storage("my-db")
24
+ const ok = await fireproof.put({ hello: 'world' })
25
+ const doc = await fireproof.get(ok.id)
26
+ ```
27
+
28
+ 🤫 I like to drop a `window.fireproof = fireproof` in there as a development aid.
29
+
11
30
  ### Status
12
31
 
13
- Fireproof is alpha software, you should only use it if you are planning to contribute. For now, [check out our React TodoMVC implementation running in browser-local mode.](https://main--lucky-naiad-5aa507.netlify.app/) It demonstrates document persistence, index queries, and event subscriptions, and uses the [`useFireproof()` React hook.](https://github.com/fireproof-storage/fireproof/blob/main/packages/fireproof/hooks/use-fireproof.tsx)
32
+ Fireproof is alpha software, ready for you to evaluate for your future applications. For now, [check out our React TodoMVC implementation running in browser-local mode.](https://main--lucky-naiad-5aa507.netlify.app/) It demonstrates document persistence, index queries, and event subscriptions, and uses the [`useFireproof()` React hook.](https://github.com/fireproof-storage/fireproof/blob/main/packages/fireproof/hooks/use-fireproof.tsx)
14
33
 
15
34
  [![Test](https://github.com/jchris/fireproof/actions/workflows/test.yml/badge.svg)](https://github.com/jchris/fireproof/actions/workflows/test.yml)
16
35
  [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
@@ -118,27 +137,6 @@ Fireproof is a synthesis of work done by people in the web community over the ye
118
137
 
119
138
  Thanks to Alan Shaw and Mikeal Rogers without whom this project would have never got started. The core Merkle hash-tree clock is based on [Alan's Pail](https://github.com/alanshaw/pail), and you can see the repository history goes all the way back to work begun as a branch of that repo. Mikeal wrote [the prolly trees implementation](https://github.com/mikeal/prolly-trees).
120
139
 
121
- ## Quick Start
122
-
123
- Look in the `examples/` directory for projects using the database. It's not picky how you use it, but we want to provide convenient jumping off places. Think of the examples as great to fork when starting your next project.
124
-
125
- If are adding Fireproof to an existing page, just install it and try some operations.
126
-
127
- ```sh
128
- npm install @fireproof/core
129
- ```
130
-
131
- In your `app.js` or `app.tsx` file:
132
-
133
- ```js
134
- import { Fireproof } from '@fireproof/core'
135
- const fireproof = Fireproof.storage()
136
- const ok = await fireproof.put({ hello: 'world' })
137
- const doc = await fireproof.get(ok.id)
138
- ```
139
-
140
- 🤫 I like to drop a `window.fireproof = fireproof` in there as a development aid.
141
-
142
140
  # Contributing
143
141
 
144
142
  Feel free to join in. All welcome. [Open an issue](https://github.com/jchris/fireproof/issues)!
@@ -1,3 +1,5 @@
1
+ import * as multiformats from 'multiformats';
2
+
1
3
  /**
2
4
  * Represents an DbIndex for a Fireproof database.
3
5
  *
@@ -15,7 +17,7 @@ declare class DbIndex {
15
17
  clock: any;
16
18
  name: any;
17
19
  }): DbIndex;
18
- constructor(database: any, mapFn: any, clock: any, opts?: {});
20
+ constructor(database: any, name: any, mapFn: any, clock?: any, opts?: {});
19
21
  database: any;
20
22
  mapFnString: any;
21
23
  mapFn: any;
@@ -30,7 +32,7 @@ declare class DbIndex {
30
32
  };
31
33
  dbHead: any;
32
34
  instanceId: string;
33
- updateIndexPromise: Promise<void>;
35
+ updateIndexPromise: Promise<any>;
34
36
  makeName(): any;
35
37
  toJSON(): {
36
38
  name: any;
@@ -54,7 +56,7 @@ declare class DbIndex {
54
56
  * @memberof DbIndex
55
57
  * @instance
56
58
  */
57
- query(query: {
59
+ query(query?: {
58
60
  /**
59
61
  * - The range to query.
60
62
  */
@@ -73,7 +75,7 @@ declare class DbIndex {
73
75
  * @returns {Promise<void>}
74
76
  */
75
77
  private updateIndex;
76
- innerUpdateIndex(inBlocks: any): Promise<void>;
78
+ innerUpdateIndex(inBlocks: any): Promise<any>;
77
79
  }
78
80
  /**
79
81
  * JDoc for the result row type.
@@ -105,7 +107,7 @@ type ChangeEvent = {
105
107
  * @param {object} [authCtx] - Optional authorization context object to use for any authentication checks.
106
108
  *
107
109
  */
108
- declare class Database$1 {
110
+ declare class Database {
109
111
  constructor(blocks: any, clock: any, config?: {});
110
112
  listeners: Set<any>;
111
113
  name: any;
@@ -165,6 +167,7 @@ declare class Database$1 {
165
167
  clock: string[];
166
168
  proof: any[];
167
169
  }>;
170
+ allCIDs(): Promise<any[]>;
168
171
  /**
169
172
  * Runs validation on the specified document using the Fireproof instance's configuration. Throws an error if the document is invalid.
170
173
  *
@@ -188,12 +191,13 @@ declare class Database$1 {
188
191
  _id: string;
189
192
  }>;
190
193
  /**
191
- * @typedef {any} Document
192
- * @property {string} _id - The ID of the document (required)
193
- * @property {string} [_proof] - The proof of the document (optional)
194
- * @property {string} [_clock] - The clock of the document (optional)
195
- * @property {any} [key: string] - Index signature notation to allow any other unknown fields
196
- */
194
+ * @typedef {Object} Document
195
+ * @property {string} _id - The ID of the document (required)
196
+ * @property {string} [_proof] - The proof of the document (optional)
197
+ * @property {string} [_clock] - The clock of the document (optional)
198
+ * @property {any} [key: string] - Index signature notation to allow any other unknown fields
199
+ * * @property {Object.<string, any>} [otherProperties] - Any other unknown properties (optional)
200
+ */
197
201
  /**
198
202
  * Adds a new document to the database, or updates an existing document. Returns the ID of the document and the new clock head.
199
203
  *
@@ -202,7 +206,31 @@ declare class Database$1 {
202
206
  * @memberof Fireproof
203
207
  * @instance
204
208
  */
205
- put({ _id, _proof, ...doc }: any): Promise<{
209
+ put({ _id, _proof, ...doc }: {
210
+ /**
211
+ * - The ID of the document (required)
212
+ */
213
+ _id: string;
214
+ /**
215
+ * - The proof of the document (optional)
216
+ */
217
+ _proof?: string;
218
+ /**
219
+ * - The clock of the document (optional)
220
+ */
221
+ _clock?: string;
222
+ /**
223
+ * : string] - Index signature notation to allow any other unknown fields
224
+ * *
225
+ */
226
+ key?: any;
227
+ /**
228
+ * - Any other unknown properties (optional)
229
+ */
230
+ otherProperties?: {
231
+ [x: string]: any;
232
+ };
233
+ }): Promise<{
206
234
  id: string;
207
235
  clock: CID[];
208
236
  }>;
@@ -224,6 +252,7 @@ declare class Database$1 {
224
252
  * @returns {Promise<{ proof:{}, id: string, clock: CID[] }>} - The result of adding the event to storage
225
253
  */
226
254
  private putToProllyTree;
255
+ applyClock(prevClock: any, newClock: any): void;
227
256
  vis(): AsyncGenerator<any, {
228
257
  cids: any;
229
258
  result: any;
@@ -272,10 +301,10 @@ declare class Listener {
272
301
  * @param {import('./database.js').Database} database
273
302
  * @param {(_: any, emit: any) => void} routingFn
274
303
  */
275
- constructor(database: Database$1, routingFn?: (_: any, emit: any) => void);
304
+ constructor(database: Database, routingFn?: (_: any, emit: any) => void);
276
305
  subcribers: Map<any, any>;
277
306
  doStopListening: any;
278
- database: Database$1;
307
+ database: Database;
279
308
  /**
280
309
  * The map function to apply to each entry in the database.
281
310
  * @type {Function}
@@ -314,6 +343,7 @@ declare class Fireproof {
314
343
  static fromJSON(json: any, database: any): any;
315
344
  static snapshot(database: any, clock: any): any;
316
345
  static zoom(database: any, clock: any): Promise<any>;
346
+ static makeCar(database: any, key: any): Promise<multiformats.BlockView<Uint8Array, 85, 18, 1>>;
317
347
  }
318
348
 
319
- export { Fireproof, DbIndex as Index, Listener };
349
+ export { Database, Fireproof, DbIndex as Index, Listener };
@@ -37118,6 +37118,7 @@ const blocksToCarBlock = async (lastCid, blocks) => {
37118
37118
  blocks = Array.from(blocks.entries());
37119
37119
  }
37120
37120
  for (const { cid, bytes } of blocks) {
37121
+ // console.log(cid, bytes)
37121
37122
  size += blockLength({ cid, bytes });
37122
37123
  }
37123
37124
  const buffer = new Uint8Array(size);
@@ -37697,7 +37698,8 @@ async function root (inBlocks, head) {
37697
37698
  */
37698
37699
  async function eventsSince (blocks, head, since) {
37699
37700
  if (!head.length) {
37700
- throw new Error('no head')
37701
+ // throw new Error('no head')
37702
+ return { clockCIDs: [], result: [] }
37701
37703
  }
37702
37704
  // @ts-ignore
37703
37705
  const sinceHead = [...since, ...head]; // ?
@@ -38135,7 +38137,7 @@ class Database {
38135
38137
  // console.log('change rows', this.instanceId, rows)
38136
38138
  } else {
38137
38139
  const allResp = await getAll(this.blocks, this.clock);
38138
- rows = allResp.result.map(({ key, value }) => (decodeEvent({ key, value })));
38140
+ rows = allResp.result.map(({ key, value }) => decodeEvent({ key, value }));
38139
38141
  dataCIDs = allResp.cids;
38140
38142
  // console.log('dbdoc rows', this.instanceId, rows)
38141
38143
  }
@@ -38148,7 +38150,9 @@ class Database {
38148
38150
 
38149
38151
  async allDocuments () {
38150
38152
  const allResp = await getAll(this.blocks, this.clock);
38151
- const rows = allResp.result.map(({ key, value }) => (decodeEvent({ key, value }))).map(({ key, value }) => ({ key, value: { _id: key, ...value } }));
38153
+ const rows = allResp.result
38154
+ .map(({ key, value }) => decodeEvent({ key, value }))
38155
+ .map(({ key, value }) => ({ key, value: { _id: key, ...value } }));
38152
38156
  return {
38153
38157
  rows,
38154
38158
  clock: this.clockToJSON(),
@@ -38156,6 +38160,15 @@ class Database {
38156
38160
  }
38157
38161
  }
38158
38162
 
38163
+ async allCIDs () {
38164
+ const allResp = await getAll(this.blocks, this.clock);
38165
+ const cids = await cidsToProof(allResp.cids);
38166
+ const clockCids = await cidsToProof(allResp.clockCIDs);
38167
+ // console.log('allcids', cids, clockCids)
38168
+ // todo we need to put the clock head as the last block in the encrypted car
38169
+ return [...cids, ...clockCids] // need a single block version of clock head, maybe an encoded block for it
38170
+ }
38171
+
38159
38172
  /**
38160
38173
  * Runs validation on the specified document using the Fireproof instance's configuration. Throws an error if the document is invalid.
38161
38174
  *
@@ -38168,7 +38181,7 @@ class Database {
38168
38181
  async runValidation (doc) {
38169
38182
  if (this.config && this.config.validateChange) {
38170
38183
  const oldDoc = await this.get(doc._id)
38171
- .then((doc) => doc)
38184
+ .then(doc => doc)
38172
38185
  .catch(() => ({}));
38173
38186
  this.config.validateChange(doc, oldDoc, this.authCtx);
38174
38187
  }
@@ -38203,12 +38216,13 @@ class Database {
38203
38216
  return doc
38204
38217
  }
38205
38218
  /**
38206
- * @typedef {any} Document
38207
- * @property {string} _id - The ID of the document (required)
38208
- * @property {string} [_proof] - The proof of the document (optional)
38209
- * @property {string} [_clock] - The clock of the document (optional)
38210
- * @property {any} [key: string] - Index signature notation to allow any other unknown fields
38211
- */
38219
+ * @typedef {Object} Document
38220
+ * @property {string} _id - The ID of the document (required)
38221
+ * @property {string} [_proof] - The proof of the document (optional)
38222
+ * @property {string} [_clock] - The clock of the document (optional)
38223
+ * @property {any} [key: string] - Index signature notation to allow any other unknown fields
38224
+ * * @property {Object.<string, any>} [otherProperties] - Any other unknown properties (optional)
38225
+ */
38212
38226
 
38213
38227
  /**
38214
38228
  * Adds a new document to the database, or updates an existing document. Returns the ID of the document and the new clock head.
@@ -38263,17 +38277,17 @@ class Database {
38263
38277
  throw new Error('MVCC conflict, document is changed, please reload the document and try again.')
38264
38278
  }
38265
38279
  }
38280
+ const prevClock = [...this.clock];
38266
38281
  const result = await doTransaction(
38267
38282
  'putToProllyTree',
38268
38283
  this.blocks,
38269
- async (blocks) => await put(blocks, this.clock, event)
38284
+ async blocks => await put(blocks, this.clock, event)
38270
38285
  );
38271
38286
  if (!result) {
38272
38287
  console.error('failed', event);
38273
38288
  throw new Error('failed to put at storage layer')
38274
38289
  }
38275
- // console.log('new clock head', this.instanceId, result.head.toString())
38276
- this.clock = result.head; // do we want to do this as a finally block
38290
+ this.applyClock(prevClock, result.head);
38277
38291
  await this.notifyListeners([decodedEvent]); // this type is odd
38278
38292
  return {
38279
38293
  id: decodedEvent.key,
@@ -38283,6 +38297,12 @@ class Database {
38283
38297
  // todo should include additions (or split clock)
38284
38298
  }
38285
38299
 
38300
+ applyClock (prevClock, newClock) {
38301
+ // console.log('applyClock', prevClock, newClock, this.clock)
38302
+ const removedprevCIDs = this.clock.filter(cid => prevClock.indexOf(cid) === -1);
38303
+ this.clock = removedprevCIDs.concat(newClock);
38304
+ }
38305
+
38286
38306
  // /**
38287
38307
  // * Advances the clock to the specified event and updates the root CID
38288
38308
  // * Will be used by replication
@@ -38341,7 +38361,7 @@ class Database {
38341
38361
  async function cidsToProof (cids) {
38342
38362
  if (!cids || !cids.all) return []
38343
38363
  const all = await cids.all();
38344
- return [...all].map((cid) => cid.toString())
38364
+ return [...all].map(cid => cid.toString())
38345
38365
  }
38346
38366
 
38347
38367
  function decodeEvent (event) {
@@ -38651,10 +38671,10 @@ const indexEntriesForChanges = (changes, mapFn) => {
38651
38671
  changes.forEach(({ key, value, del }) => {
38652
38672
  if (del || !value) return
38653
38673
  mapFn(makeDoc({ key, value }), (k, v) => {
38654
- if (typeof v === 'undefined' || typeof k === 'undefined') return
38674
+ if (typeof k === 'undefined') return
38655
38675
  indexEntries.push({
38656
38676
  key: [charwise.encode(k), key],
38657
- value: v
38677
+ value: v || null
38658
38678
  });
38659
38679
  });
38660
38680
  });
@@ -38672,7 +38692,7 @@ const indexEntriesForChanges = (changes, mapFn) => {
38672
38692
  *
38673
38693
  */
38674
38694
  class DbIndex {
38675
- constructor (database, mapFn, clock, opts = {}) {
38695
+ constructor (database, name, mapFn, clock = null, opts = {}) {
38676
38696
  this.database = database;
38677
38697
  if (!database.indexBlocks) {
38678
38698
  database.indexBlocks = new TransactionBlockstore(database?.name + '.indexes', database.blocks.valet?.getKeyMaterial());
@@ -38688,7 +38708,7 @@ class DbIndex {
38688
38708
  this.mapFn = mapFn;
38689
38709
  this.mapFnString = mapFn.toString();
38690
38710
  }
38691
- this.name = opts.name || this.makeName();
38711
+ this.name = name || this.makeName();
38692
38712
  this.indexById = { root: null, cid: null };
38693
38713
  this.indexByKey = { root: null, cid: null };
38694
38714
  this.dbHead = null;
@@ -38738,7 +38758,7 @@ class DbIndex {
38738
38758
 
38739
38759
  static fromJSON (database, { code, clock, name }) {
38740
38760
  // console.log('DbIndex.fromJSON', database.constructor.name, code, clock)
38741
- return new DbIndex(database, code, clock, { name })
38761
+ return new DbIndex(database, name, code, clock)
38742
38762
  }
38743
38763
 
38744
38764
  /**
@@ -38755,7 +38775,7 @@ class DbIndex {
38755
38775
  * @memberof DbIndex
38756
38776
  * @instance
38757
38777
  */
38758
- async query (query, update = true) {
38778
+ async query (query = {}, update = true) {
38759
38779
  // const callId = Math.random().toString(36).substring(2, 7)
38760
38780
  // todo pass a root to query a snapshot
38761
38781
  // console.time(callId + '.updateIndex')
@@ -38782,7 +38802,12 @@ class DbIndex {
38782
38802
  async updateIndex (blocks) {
38783
38803
  // todo this could enqueue the request and give fresh ones to all second comers -- right now it gives out stale promises while working
38784
38804
  // what would it do in a world where all indexes provide a database snapshot to query?
38785
- if (this.updateIndexPromise) return this.updateIndexPromise
38805
+ if (this.updateIndexPromise) {
38806
+ return this.updateIndexPromise.then(() => {
38807
+ this.updateIndexPromise = null;
38808
+ return this.updateIndex(blocks)
38809
+ })
38810
+ }
38786
38811
  this.updateIndexPromise = this.innerUpdateIndex(blocks);
38787
38812
  this.updateIndexPromise.finally(() => { this.updateIndexPromise = null; });
38788
38813
  return this.updateIndexPromise
@@ -38803,7 +38828,7 @@ class DbIndex {
38803
38828
  this.dbHead = result.clock;
38804
38829
  return
38805
38830
  }
38806
- await doTransaction('updateIndex', inBlocks, async (blocks) => {
38831
+ const didT = await doTransaction('updateIndex', inBlocks, async (blocks) => {
38807
38832
  let oldIndexEntries = [];
38808
38833
  let removeByIdIndexEntries = [];
38809
38834
  await loadIndex(blocks, this.indexById, idIndexOpts);
@@ -38825,6 +38850,7 @@ class DbIndex {
38825
38850
  this.database.notifyExternal('dbIndex');
38826
38851
  // console.timeEnd(callTag + '.doTransactionupdateIndex')
38827
38852
  // console.log(`updateIndex ${callTag} <`, this.instanceId, this.dbHead?.toString(), this.indexByKey.cid?.toString(), this.indexById.cid?.toString())
38853
+ return didT
38828
38854
  }
38829
38855
  }
38830
38856
 
@@ -38867,7 +38893,11 @@ async function bulkIndex (blocks, inIndex, indexEntries, opts) {
38867
38893
  async function loadIndex (blocks, index, indexOpts) {
38868
38894
  if (!index.root) {
38869
38895
  const cid = index.cid;
38870
- if (!cid) return
38896
+ if (!cid) {
38897
+ // console.log('no cid', index)
38898
+ // throw new Error('cannot load index')
38899
+ return null
38900
+ }
38871
38901
  const { getBlock } = makeGetBlock(blocks);
38872
38902
  index.root = await load({ cid, get: getBlock, ...indexOpts });
38873
38903
  }
@@ -38894,7 +38924,7 @@ async function doIndexQuery (blocks, indexByKey, query = {}) {
38894
38924
  }
38895
38925
  }
38896
38926
 
38897
- const parseCID = cid => typeof cid === 'string' ? CID$1.parse(cid) : cid;
38927
+ const parseCID = cid => (typeof cid === 'string' ? CID$1.parse(cid) : cid);
38898
38928
 
38899
38929
  class Fireproof {
38900
38930
  /**
@@ -38925,7 +38955,11 @@ class Fireproof {
38925
38955
  static fromJSON (json, database) {
38926
38956
  database.hydrate({ clock: json.clock.map(c => parseCID(c)), name: json.name, key: json.key });
38927
38957
  if (json.indexes) {
38928
- for (const { name, code, clock: { byId, byKey, db } } of json.indexes) {
38958
+ for (const {
38959
+ name,
38960
+ code,
38961
+ clock: { byId, byKey, db }
38962
+ } of json.indexes) {
38929
38963
  DbIndex.fromJSON(database, {
38930
38964
  clock: {
38931
38965
  byId: byId ? parseCID(byId) : null,
@@ -38952,14 +38986,14 @@ class Fireproof {
38952
38986
  });
38953
38987
  }
38954
38988
  const snappedDb = this.fromJSON(definition, withBlocks)
38955
- ;([...database.indexes.values()]).forEach(index => {
38989
+ ;[...database.indexes.values()].forEach(index => {
38956
38990
  snappedDb.indexes.get(index.mapFnString).mapFn = index.mapFn;
38957
38991
  });
38958
38992
  return snappedDb
38959
38993
  }
38960
38994
 
38961
38995
  static async zoom (database, clock) {
38962
- ([...database.indexes.values()]).forEach(index => {
38996
+ [...database.indexes.values()].forEach(index => {
38963
38997
  index.indexById = { root: null, cid: null };
38964
38998
  index.indexByKey = { root: null, cid: null };
38965
38999
  index.dbHead = null;
@@ -38968,8 +39002,44 @@ class Fireproof {
38968
39002
  await database.notifyReset(); // hmm... indexes should listen to this? might be more complex than worth it. so far this is the only caller
38969
39003
  return database
38970
39004
  }
39005
+
39006
+ // get all the cids
39007
+ // tell valet to make a file
39008
+ static async makeCar (database, key) {
39009
+ const allCIDs = await database.allCIDs();
39010
+ const blocks = database.blocks;
39011
+
39012
+ const rootCid = CID$1.parse(allCIDs[allCIDs.length - 1]);
39013
+ if (typeof key === 'undefined') {
39014
+ key = blocks.valet?.getKeyMaterial();
39015
+ }
39016
+ if (key) {
39017
+ return blocksToEncryptedCarBlock(
39018
+ rootCid,
39019
+ {
39020
+ entries: () => allCIDs.map(cid => ({ cid })),
39021
+ get: async cid => await blocks.get(cid)
39022
+ },
39023
+ key
39024
+ )
39025
+ } else {
39026
+ const carBlocks = await Promise.all(
39027
+ allCIDs.map(async c => {
39028
+ const b = await blocks.get(c);
39029
+ // console.log('block', b)
39030
+ if (typeof b.cid === 'string') { b.cid = CID$1.parse(b.cid); }
39031
+ // if (b.bytes.constructor.name === 'Buffer') console.log('conver vbuff')
39032
+ return b
39033
+ })
39034
+ );
39035
+ return blocksToCarBlock(rootCid, {
39036
+ entries: () => carBlocks
39037
+ })
39038
+ }
39039
+ }
38971
39040
  }
38972
39041
 
39042
+ exports.Database = Database;
38973
39043
  exports.Fireproof = Fireproof;
38974
39044
  exports.Index = DbIndex;
38975
39045
  exports.Listener = Listener;