@fireproof/core 0.4.1 → 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.
@@ -37116,6 +37116,7 @@ const blocksToCarBlock = async (lastCid, blocks) => {
37116
37116
  blocks = Array.from(blocks.entries());
37117
37117
  }
37118
37118
  for (const { cid, bytes } of blocks) {
37119
+ // console.log(cid, bytes)
37119
37120
  size += blockLength({ cid, bytes });
37120
37121
  }
37121
37122
  const buffer = new Uint8Array(size);
@@ -37695,7 +37696,8 @@ async function root (inBlocks, head) {
37695
37696
  */
37696
37697
  async function eventsSince (blocks, head, since) {
37697
37698
  if (!head.length) {
37698
- throw new Error('no head')
37699
+ // throw new Error('no head')
37700
+ return { clockCIDs: [], result: [] }
37699
37701
  }
37700
37702
  // @ts-ignore
37701
37703
  const sinceHead = [...since, ...head]; // ?
@@ -38133,7 +38135,7 @@ class Database {
38133
38135
  // console.log('change rows', this.instanceId, rows)
38134
38136
  } else {
38135
38137
  const allResp = await getAll(this.blocks, this.clock);
38136
- rows = allResp.result.map(({ key, value }) => (decodeEvent({ key, value })));
38138
+ rows = allResp.result.map(({ key, value }) => decodeEvent({ key, value }));
38137
38139
  dataCIDs = allResp.cids;
38138
38140
  // console.log('dbdoc rows', this.instanceId, rows)
38139
38141
  }
@@ -38146,7 +38148,9 @@ class Database {
38146
38148
 
38147
38149
  async allDocuments () {
38148
38150
  const allResp = await getAll(this.blocks, this.clock);
38149
- const rows = allResp.result.map(({ key, value }) => (decodeEvent({ key, value }))).map(({ key, value }) => ({ key, value: { _id: key, ...value } }));
38151
+ const rows = allResp.result
38152
+ .map(({ key, value }) => decodeEvent({ key, value }))
38153
+ .map(({ key, value }) => ({ key, value: { _id: key, ...value } }));
38150
38154
  return {
38151
38155
  rows,
38152
38156
  clock: this.clockToJSON(),
@@ -38154,6 +38158,15 @@ class Database {
38154
38158
  }
38155
38159
  }
38156
38160
 
38161
+ async allCIDs () {
38162
+ const allResp = await getAll(this.blocks, this.clock);
38163
+ const cids = await cidsToProof(allResp.cids);
38164
+ const clockCids = await cidsToProof(allResp.clockCIDs);
38165
+ // console.log('allcids', cids, clockCids)
38166
+ // todo we need to put the clock head as the last block in the encrypted car
38167
+ return [...cids, ...clockCids] // need a single block version of clock head, maybe an encoded block for it
38168
+ }
38169
+
38157
38170
  /**
38158
38171
  * Runs validation on the specified document using the Fireproof instance's configuration. Throws an error if the document is invalid.
38159
38172
  *
@@ -38166,7 +38179,7 @@ class Database {
38166
38179
  async runValidation (doc) {
38167
38180
  if (this.config && this.config.validateChange) {
38168
38181
  const oldDoc = await this.get(doc._id)
38169
- .then((doc) => doc)
38182
+ .then(doc => doc)
38170
38183
  .catch(() => ({}));
38171
38184
  this.config.validateChange(doc, oldDoc, this.authCtx);
38172
38185
  }
@@ -38201,13 +38214,13 @@ class Database {
38201
38214
  return doc
38202
38215
  }
38203
38216
  /**
38204
- * @typedef {Object} Document
38205
- * @property {string} _id - The ID of the document (required)
38206
- * @property {string} [_proof] - The proof of the document (optional)
38207
- * @property {string} [_clock] - The clock of the document (optional)
38208
- * @property {any} [key: string] - Index signature notation to allow any other unknown fields
38209
- * * @property {Object.<string, any>} [otherProperties] - Any other unknown properties (optional)
38210
- */
38217
+ * @typedef {Object} Document
38218
+ * @property {string} _id - The ID of the document (required)
38219
+ * @property {string} [_proof] - The proof of the document (optional)
38220
+ * @property {string} [_clock] - The clock of the document (optional)
38221
+ * @property {any} [key: string] - Index signature notation to allow any other unknown fields
38222
+ * * @property {Object.<string, any>} [otherProperties] - Any other unknown properties (optional)
38223
+ */
38211
38224
 
38212
38225
  /**
38213
38226
  * Adds a new document to the database, or updates an existing document. Returns the ID of the document and the new clock head.
@@ -38262,17 +38275,17 @@ class Database {
38262
38275
  throw new Error('MVCC conflict, document is changed, please reload the document and try again.')
38263
38276
  }
38264
38277
  }
38278
+ const prevClock = [...this.clock];
38265
38279
  const result = await doTransaction(
38266
38280
  'putToProllyTree',
38267
38281
  this.blocks,
38268
- async (blocks) => await put(blocks, this.clock, event)
38282
+ async blocks => await put(blocks, this.clock, event)
38269
38283
  );
38270
38284
  if (!result) {
38271
38285
  console.error('failed', event);
38272
38286
  throw new Error('failed to put at storage layer')
38273
38287
  }
38274
- // console.log('new clock head', this.instanceId, result.head.toString())
38275
- this.clock = result.head; // do we want to do this as a finally block
38288
+ this.applyClock(prevClock, result.head);
38276
38289
  await this.notifyListeners([decodedEvent]); // this type is odd
38277
38290
  return {
38278
38291
  id: decodedEvent.key,
@@ -38282,6 +38295,12 @@ class Database {
38282
38295
  // todo should include additions (or split clock)
38283
38296
  }
38284
38297
 
38298
+ applyClock (prevClock, newClock) {
38299
+ // console.log('applyClock', prevClock, newClock, this.clock)
38300
+ const removedprevCIDs = this.clock.filter(cid => prevClock.indexOf(cid) === -1);
38301
+ this.clock = removedprevCIDs.concat(newClock);
38302
+ }
38303
+
38285
38304
  // /**
38286
38305
  // * Advances the clock to the specified event and updates the root CID
38287
38306
  // * Will be used by replication
@@ -38340,7 +38359,7 @@ class Database {
38340
38359
  async function cidsToProof (cids) {
38341
38360
  if (!cids || !cids.all) return []
38342
38361
  const all = await cids.all();
38343
- return [...all].map((cid) => cid.toString())
38362
+ return [...all].map(cid => cid.toString())
38344
38363
  }
38345
38364
 
38346
38365
  function decodeEvent (event) {
@@ -38650,10 +38669,10 @@ const indexEntriesForChanges = (changes, mapFn) => {
38650
38669
  changes.forEach(({ key, value, del }) => {
38651
38670
  if (del || !value) return
38652
38671
  mapFn(makeDoc({ key, value }), (k, v) => {
38653
- if (typeof v === 'undefined' || typeof k === 'undefined') return
38672
+ if (typeof k === 'undefined') return
38654
38673
  indexEntries.push({
38655
38674
  key: [charwise.encode(k), key],
38656
- value: v
38675
+ value: v || null
38657
38676
  });
38658
38677
  });
38659
38678
  });
@@ -38671,7 +38690,7 @@ const indexEntriesForChanges = (changes, mapFn) => {
38671
38690
  *
38672
38691
  */
38673
38692
  class DbIndex {
38674
- constructor (database, mapFn, clock, opts = {}) {
38693
+ constructor (database, name, mapFn, clock = null, opts = {}) {
38675
38694
  this.database = database;
38676
38695
  if (!database.indexBlocks) {
38677
38696
  database.indexBlocks = new TransactionBlockstore(database?.name + '.indexes', database.blocks.valet?.getKeyMaterial());
@@ -38687,7 +38706,7 @@ class DbIndex {
38687
38706
  this.mapFn = mapFn;
38688
38707
  this.mapFnString = mapFn.toString();
38689
38708
  }
38690
- this.name = opts.name || this.makeName();
38709
+ this.name = name || this.makeName();
38691
38710
  this.indexById = { root: null, cid: null };
38692
38711
  this.indexByKey = { root: null, cid: null };
38693
38712
  this.dbHead = null;
@@ -38737,7 +38756,7 @@ class DbIndex {
38737
38756
 
38738
38757
  static fromJSON (database, { code, clock, name }) {
38739
38758
  // console.log('DbIndex.fromJSON', database.constructor.name, code, clock)
38740
- return new DbIndex(database, code, clock, { name })
38759
+ return new DbIndex(database, name, code, clock)
38741
38760
  }
38742
38761
 
38743
38762
  /**
@@ -38754,7 +38773,7 @@ class DbIndex {
38754
38773
  * @memberof DbIndex
38755
38774
  * @instance
38756
38775
  */
38757
- async query (query, update = true) {
38776
+ async query (query = {}, update = true) {
38758
38777
  // const callId = Math.random().toString(36).substring(2, 7)
38759
38778
  // todo pass a root to query a snapshot
38760
38779
  // console.time(callId + '.updateIndex')
@@ -38781,7 +38800,12 @@ class DbIndex {
38781
38800
  async updateIndex (blocks) {
38782
38801
  // todo this could enqueue the request and give fresh ones to all second comers -- right now it gives out stale promises while working
38783
38802
  // what would it do in a world where all indexes provide a database snapshot to query?
38784
- if (this.updateIndexPromise) return this.updateIndexPromise
38803
+ if (this.updateIndexPromise) {
38804
+ return this.updateIndexPromise.then(() => {
38805
+ this.updateIndexPromise = null;
38806
+ return this.updateIndex(blocks)
38807
+ })
38808
+ }
38785
38809
  this.updateIndexPromise = this.innerUpdateIndex(blocks);
38786
38810
  this.updateIndexPromise.finally(() => { this.updateIndexPromise = null; });
38787
38811
  return this.updateIndexPromise
@@ -38802,7 +38826,7 @@ class DbIndex {
38802
38826
  this.dbHead = result.clock;
38803
38827
  return
38804
38828
  }
38805
- await doTransaction('updateIndex', inBlocks, async (blocks) => {
38829
+ const didT = await doTransaction('updateIndex', inBlocks, async (blocks) => {
38806
38830
  let oldIndexEntries = [];
38807
38831
  let removeByIdIndexEntries = [];
38808
38832
  await loadIndex(blocks, this.indexById, idIndexOpts);
@@ -38824,6 +38848,7 @@ class DbIndex {
38824
38848
  this.database.notifyExternal('dbIndex');
38825
38849
  // console.timeEnd(callTag + '.doTransactionupdateIndex')
38826
38850
  // console.log(`updateIndex ${callTag} <`, this.instanceId, this.dbHead?.toString(), this.indexByKey.cid?.toString(), this.indexById.cid?.toString())
38851
+ return didT
38827
38852
  }
38828
38853
  }
38829
38854
 
@@ -38866,7 +38891,11 @@ async function bulkIndex (blocks, inIndex, indexEntries, opts) {
38866
38891
  async function loadIndex (blocks, index, indexOpts) {
38867
38892
  if (!index.root) {
38868
38893
  const cid = index.cid;
38869
- if (!cid) return
38894
+ if (!cid) {
38895
+ // console.log('no cid', index)
38896
+ // throw new Error('cannot load index')
38897
+ return null
38898
+ }
38870
38899
  const { getBlock } = makeGetBlock(blocks);
38871
38900
  index.root = await load({ cid, get: getBlock, ...indexOpts });
38872
38901
  }
@@ -38893,7 +38922,7 @@ async function doIndexQuery (blocks, indexByKey, query = {}) {
38893
38922
  }
38894
38923
  }
38895
38924
 
38896
- const parseCID = cid => typeof cid === 'string' ? CID$1.parse(cid) : cid;
38925
+ const parseCID = cid => (typeof cid === 'string' ? CID$1.parse(cid) : cid);
38897
38926
 
38898
38927
  class Fireproof {
38899
38928
  /**
@@ -38924,7 +38953,11 @@ class Fireproof {
38924
38953
  static fromJSON (json, database) {
38925
38954
  database.hydrate({ clock: json.clock.map(c => parseCID(c)), name: json.name, key: json.key });
38926
38955
  if (json.indexes) {
38927
- for (const { name, code, clock: { byId, byKey, db } } of json.indexes) {
38956
+ for (const {
38957
+ name,
38958
+ code,
38959
+ clock: { byId, byKey, db }
38960
+ } of json.indexes) {
38928
38961
  DbIndex.fromJSON(database, {
38929
38962
  clock: {
38930
38963
  byId: byId ? parseCID(byId) : null,
@@ -38951,14 +38984,14 @@ class Fireproof {
38951
38984
  });
38952
38985
  }
38953
38986
  const snappedDb = this.fromJSON(definition, withBlocks)
38954
- ;([...database.indexes.values()]).forEach(index => {
38987
+ ;[...database.indexes.values()].forEach(index => {
38955
38988
  snappedDb.indexes.get(index.mapFnString).mapFn = index.mapFn;
38956
38989
  });
38957
38990
  return snappedDb
38958
38991
  }
38959
38992
 
38960
38993
  static async zoom (database, clock) {
38961
- ([...database.indexes.values()]).forEach(index => {
38994
+ [...database.indexes.values()].forEach(index => {
38962
38995
  index.indexById = { root: null, cid: null };
38963
38996
  index.indexByKey = { root: null, cid: null };
38964
38997
  index.dbHead = null;
@@ -38967,7 +39000,42 @@ class Fireproof {
38967
39000
  await database.notifyReset(); // hmm... indexes should listen to this? might be more complex than worth it. so far this is the only caller
38968
39001
  return database
38969
39002
  }
39003
+
39004
+ // get all the cids
39005
+ // tell valet to make a file
39006
+ static async makeCar (database, key) {
39007
+ const allCIDs = await database.allCIDs();
39008
+ const blocks = database.blocks;
39009
+
39010
+ const rootCid = CID$1.parse(allCIDs[allCIDs.length - 1]);
39011
+ if (typeof key === 'undefined') {
39012
+ key = blocks.valet?.getKeyMaterial();
39013
+ }
39014
+ if (key) {
39015
+ return blocksToEncryptedCarBlock(
39016
+ rootCid,
39017
+ {
39018
+ entries: () => allCIDs.map(cid => ({ cid })),
39019
+ get: async cid => await blocks.get(cid)
39020
+ },
39021
+ key
39022
+ )
39023
+ } else {
39024
+ const carBlocks = await Promise.all(
39025
+ allCIDs.map(async c => {
39026
+ const b = await blocks.get(c);
39027
+ // console.log('block', b)
39028
+ if (typeof b.cid === 'string') { b.cid = CID$1.parse(b.cid); }
39029
+ // if (b.bytes.constructor.name === 'Buffer') console.log('conver vbuff')
39030
+ return b
39031
+ })
39032
+ );
39033
+ return blocksToCarBlock(rootCid, {
39034
+ entries: () => carBlocks
39035
+ })
39036
+ }
39037
+ }
38970
39038
  }
38971
39039
 
38972
- export { Fireproof, DbIndex as Index, Listener };
39040
+ export { Database, Fireproof, DbIndex as Index, Listener };
38973
39041
  //# sourceMappingURL=fireproof.mjs.map