@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.
- package/README.md +20 -22
- package/dist/src/fireproof.d.ts +45 -15
- package/dist/src/fireproof.js +97 -27
- package/dist/src/fireproof.js.map +1 -1
- package/dist/src/fireproof.mjs +97 -28
- package/dist/src/fireproof.mjs.map +1 -1
- package/package.json +2 -2
- package/src/database.js +31 -13
- package/src/db-index.js +19 -9
- package/src/fireproof.js +45 -5
- package/src/prolly.js +2 -1
- package/src/valet.js +3 -2
- package/dist/blockstore.js +0 -242
- package/dist/clock.js +0 -355
- package/dist/crypto.js +0 -59
- package/dist/database.js +0 -308
- package/dist/db-index.js +0 -314
- package/dist/fireproof.js +0 -83
- package/dist/hooks/use-fireproof.js +0 -100
- package/dist/listener.js +0 -110
- package/dist/main.js +0 -2
- package/dist/main.js.LICENSE.txt +0 -17
- package/dist/prolly.js +0 -316
- package/dist/sha1.js +0 -74
- package/dist/src/blockstore.js +0 -242
- package/dist/src/clock.js +0 -355
- package/dist/src/crypto.js +0 -59
- package/dist/src/database.js +0 -312
- package/dist/src/db-index.js +0 -314
- package/dist/src/index.d.ts +0 -321
- package/dist/src/index.js +0 -38936
- package/dist/src/index.js.map +0 -1
- package/dist/src/index.mjs +0 -38931
- package/dist/src/index.mjs.map +0 -1
- package/dist/src/listener.js +0 -108
- package/dist/src/prolly.js +0 -319
- package/dist/src/sha1.js +0 -74
- package/dist/src/utils.js +0 -16
- package/dist/src/valet.js +0 -262
- package/dist/test/block.js +0 -57
- package/dist/test/clock.test.js +0 -556
- package/dist/test/db-index.test.js +0 -231
- package/dist/test/fireproof.test.js +0 -444
- package/dist/test/fulltext.test.js +0 -61
- package/dist/test/helpers.js +0 -39
- package/dist/test/hydrator.test.js +0 -142
- package/dist/test/listener.test.js +0 -103
- package/dist/test/prolly.test.js +0 -162
- package/dist/test/proofs.test.js +0 -45
- package/dist/test/reproduce-fixture-bug.test.js +0 -57
- package/dist/test/valet.test.js +0 -56
- package/dist/utils.js +0 -16
- package/dist/valet.js +0 -262
package/dist/src/fireproof.mjs
CHANGED
@@ -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 }) =>
|
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
|
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(
|
38182
|
+
.then(doc => doc)
|
38170
38183
|
.catch(() => ({}));
|
38171
38184
|
this.config.validateChange(doc, oldDoc, this.authCtx);
|
38172
38185
|
}
|
@@ -38201,12 +38214,13 @@ class Database {
|
|
38201
38214
|
return doc
|
38202
38215
|
}
|
38203
38216
|
/**
|
38204
|
-
|
38205
|
-
|
38206
|
-
|
38207
|
-
|
38208
|
-
|
38209
|
-
|
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
|
+
*/
|
38210
38224
|
|
38211
38225
|
/**
|
38212
38226
|
* Adds a new document to the database, or updates an existing document. Returns the ID of the document and the new clock head.
|
@@ -38261,17 +38275,17 @@ class Database {
|
|
38261
38275
|
throw new Error('MVCC conflict, document is changed, please reload the document and try again.')
|
38262
38276
|
}
|
38263
38277
|
}
|
38278
|
+
const prevClock = [...this.clock];
|
38264
38279
|
const result = await doTransaction(
|
38265
38280
|
'putToProllyTree',
|
38266
38281
|
this.blocks,
|
38267
|
-
async
|
38282
|
+
async blocks => await put(blocks, this.clock, event)
|
38268
38283
|
);
|
38269
38284
|
if (!result) {
|
38270
38285
|
console.error('failed', event);
|
38271
38286
|
throw new Error('failed to put at storage layer')
|
38272
38287
|
}
|
38273
|
-
|
38274
|
-
this.clock = result.head; // do we want to do this as a finally block
|
38288
|
+
this.applyClock(prevClock, result.head);
|
38275
38289
|
await this.notifyListeners([decodedEvent]); // this type is odd
|
38276
38290
|
return {
|
38277
38291
|
id: decodedEvent.key,
|
@@ -38281,6 +38295,12 @@ class Database {
|
|
38281
38295
|
// todo should include additions (or split clock)
|
38282
38296
|
}
|
38283
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
|
+
|
38284
38304
|
// /**
|
38285
38305
|
// * Advances the clock to the specified event and updates the root CID
|
38286
38306
|
// * Will be used by replication
|
@@ -38339,7 +38359,7 @@ class Database {
|
|
38339
38359
|
async function cidsToProof (cids) {
|
38340
38360
|
if (!cids || !cids.all) return []
|
38341
38361
|
const all = await cids.all();
|
38342
|
-
return [...all].map(
|
38362
|
+
return [...all].map(cid => cid.toString())
|
38343
38363
|
}
|
38344
38364
|
|
38345
38365
|
function decodeEvent (event) {
|
@@ -38649,10 +38669,10 @@ const indexEntriesForChanges = (changes, mapFn) => {
|
|
38649
38669
|
changes.forEach(({ key, value, del }) => {
|
38650
38670
|
if (del || !value) return
|
38651
38671
|
mapFn(makeDoc({ key, value }), (k, v) => {
|
38652
|
-
if (typeof
|
38672
|
+
if (typeof k === 'undefined') return
|
38653
38673
|
indexEntries.push({
|
38654
38674
|
key: [charwise.encode(k), key],
|
38655
|
-
value: v
|
38675
|
+
value: v || null
|
38656
38676
|
});
|
38657
38677
|
});
|
38658
38678
|
});
|
@@ -38670,7 +38690,7 @@ const indexEntriesForChanges = (changes, mapFn) => {
|
|
38670
38690
|
*
|
38671
38691
|
*/
|
38672
38692
|
class DbIndex {
|
38673
|
-
constructor (database, mapFn, clock, opts = {}) {
|
38693
|
+
constructor (database, name, mapFn, clock = null, opts = {}) {
|
38674
38694
|
this.database = database;
|
38675
38695
|
if (!database.indexBlocks) {
|
38676
38696
|
database.indexBlocks = new TransactionBlockstore(database?.name + '.indexes', database.blocks.valet?.getKeyMaterial());
|
@@ -38686,7 +38706,7 @@ class DbIndex {
|
|
38686
38706
|
this.mapFn = mapFn;
|
38687
38707
|
this.mapFnString = mapFn.toString();
|
38688
38708
|
}
|
38689
|
-
this.name =
|
38709
|
+
this.name = name || this.makeName();
|
38690
38710
|
this.indexById = { root: null, cid: null };
|
38691
38711
|
this.indexByKey = { root: null, cid: null };
|
38692
38712
|
this.dbHead = null;
|
@@ -38736,7 +38756,7 @@ class DbIndex {
|
|
38736
38756
|
|
38737
38757
|
static fromJSON (database, { code, clock, name }) {
|
38738
38758
|
// console.log('DbIndex.fromJSON', database.constructor.name, code, clock)
|
38739
|
-
return new DbIndex(database, code, clock
|
38759
|
+
return new DbIndex(database, name, code, clock)
|
38740
38760
|
}
|
38741
38761
|
|
38742
38762
|
/**
|
@@ -38753,7 +38773,7 @@ class DbIndex {
|
|
38753
38773
|
* @memberof DbIndex
|
38754
38774
|
* @instance
|
38755
38775
|
*/
|
38756
|
-
async query (query, update = true) {
|
38776
|
+
async query (query = {}, update = true) {
|
38757
38777
|
// const callId = Math.random().toString(36).substring(2, 7)
|
38758
38778
|
// todo pass a root to query a snapshot
|
38759
38779
|
// console.time(callId + '.updateIndex')
|
@@ -38780,7 +38800,12 @@ class DbIndex {
|
|
38780
38800
|
async updateIndex (blocks) {
|
38781
38801
|
// todo this could enqueue the request and give fresh ones to all second comers -- right now it gives out stale promises while working
|
38782
38802
|
// what would it do in a world where all indexes provide a database snapshot to query?
|
38783
|
-
if (this.updateIndexPromise)
|
38803
|
+
if (this.updateIndexPromise) {
|
38804
|
+
return this.updateIndexPromise.then(() => {
|
38805
|
+
this.updateIndexPromise = null;
|
38806
|
+
return this.updateIndex(blocks)
|
38807
|
+
})
|
38808
|
+
}
|
38784
38809
|
this.updateIndexPromise = this.innerUpdateIndex(blocks);
|
38785
38810
|
this.updateIndexPromise.finally(() => { this.updateIndexPromise = null; });
|
38786
38811
|
return this.updateIndexPromise
|
@@ -38801,7 +38826,7 @@ class DbIndex {
|
|
38801
38826
|
this.dbHead = result.clock;
|
38802
38827
|
return
|
38803
38828
|
}
|
38804
|
-
await doTransaction('updateIndex', inBlocks, async (blocks) => {
|
38829
|
+
const didT = await doTransaction('updateIndex', inBlocks, async (blocks) => {
|
38805
38830
|
let oldIndexEntries = [];
|
38806
38831
|
let removeByIdIndexEntries = [];
|
38807
38832
|
await loadIndex(blocks, this.indexById, idIndexOpts);
|
@@ -38823,6 +38848,7 @@ class DbIndex {
|
|
38823
38848
|
this.database.notifyExternal('dbIndex');
|
38824
38849
|
// console.timeEnd(callTag + '.doTransactionupdateIndex')
|
38825
38850
|
// console.log(`updateIndex ${callTag} <`, this.instanceId, this.dbHead?.toString(), this.indexByKey.cid?.toString(), this.indexById.cid?.toString())
|
38851
|
+
return didT
|
38826
38852
|
}
|
38827
38853
|
}
|
38828
38854
|
|
@@ -38865,7 +38891,11 @@ async function bulkIndex (blocks, inIndex, indexEntries, opts) {
|
|
38865
38891
|
async function loadIndex (blocks, index, indexOpts) {
|
38866
38892
|
if (!index.root) {
|
38867
38893
|
const cid = index.cid;
|
38868
|
-
if (!cid)
|
38894
|
+
if (!cid) {
|
38895
|
+
// console.log('no cid', index)
|
38896
|
+
// throw new Error('cannot load index')
|
38897
|
+
return null
|
38898
|
+
}
|
38869
38899
|
const { getBlock } = makeGetBlock(blocks);
|
38870
38900
|
index.root = await load({ cid, get: getBlock, ...indexOpts });
|
38871
38901
|
}
|
@@ -38892,7 +38922,7 @@ async function doIndexQuery (blocks, indexByKey, query = {}) {
|
|
38892
38922
|
}
|
38893
38923
|
}
|
38894
38924
|
|
38895
|
-
const parseCID = cid => typeof cid === 'string' ? CID$1.parse(cid) : cid;
|
38925
|
+
const parseCID = cid => (typeof cid === 'string' ? CID$1.parse(cid) : cid);
|
38896
38926
|
|
38897
38927
|
class Fireproof {
|
38898
38928
|
/**
|
@@ -38923,7 +38953,11 @@ class Fireproof {
|
|
38923
38953
|
static fromJSON (json, database) {
|
38924
38954
|
database.hydrate({ clock: json.clock.map(c => parseCID(c)), name: json.name, key: json.key });
|
38925
38955
|
if (json.indexes) {
|
38926
|
-
for (const {
|
38956
|
+
for (const {
|
38957
|
+
name,
|
38958
|
+
code,
|
38959
|
+
clock: { byId, byKey, db }
|
38960
|
+
} of json.indexes) {
|
38927
38961
|
DbIndex.fromJSON(database, {
|
38928
38962
|
clock: {
|
38929
38963
|
byId: byId ? parseCID(byId) : null,
|
@@ -38950,14 +38984,14 @@ class Fireproof {
|
|
38950
38984
|
});
|
38951
38985
|
}
|
38952
38986
|
const snappedDb = this.fromJSON(definition, withBlocks)
|
38953
|
-
;
|
38987
|
+
;[...database.indexes.values()].forEach(index => {
|
38954
38988
|
snappedDb.indexes.get(index.mapFnString).mapFn = index.mapFn;
|
38955
38989
|
});
|
38956
38990
|
return snappedDb
|
38957
38991
|
}
|
38958
38992
|
|
38959
38993
|
static async zoom (database, clock) {
|
38960
|
-
|
38994
|
+
[...database.indexes.values()].forEach(index => {
|
38961
38995
|
index.indexById = { root: null, cid: null };
|
38962
38996
|
index.indexByKey = { root: null, cid: null };
|
38963
38997
|
index.dbHead = null;
|
@@ -38966,7 +39000,42 @@ class Fireproof {
|
|
38966
39000
|
await database.notifyReset(); // hmm... indexes should listen to this? might be more complex than worth it. so far this is the only caller
|
38967
39001
|
return database
|
38968
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
|
+
}
|
38969
39038
|
}
|
38970
39039
|
|
38971
|
-
export { Fireproof, DbIndex as Index, Listener };
|
39040
|
+
export { Database, Fireproof, DbIndex as Index, Listener };
|
38972
39041
|
//# sourceMappingURL=fireproof.mjs.map
|