@fireproof/core 0.8.0 → 0.10.1-dev

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 (57) hide show
  1. package/README.md +5 -184
  2. package/dist/fireproof.browser.js +18879 -0
  3. package/dist/fireproof.browser.js.map +7 -0
  4. package/dist/fireproof.cjs.js +9305 -0
  5. package/dist/fireproof.cjs.js.map +7 -0
  6. package/dist/fireproof.esm.js +9295 -0
  7. package/dist/fireproof.esm.js.map +7 -0
  8. package/package.json +57 -105
  9. package/dist/blockstore.js +0 -268
  10. package/dist/clock.js +0 -459
  11. package/dist/crypto.js +0 -63
  12. package/dist/database.js +0 -434
  13. package/dist/db-index.js +0 -403
  14. package/dist/encrypted-block.js +0 -48
  15. package/dist/fireproof.js +0 -84
  16. package/dist/import.js +0 -29
  17. package/dist/listener.js +0 -111
  18. package/dist/loader.js +0 -13
  19. package/dist/prolly.js +0 -405
  20. package/dist/remote.js +0 -102
  21. package/dist/sha1.js +0 -74
  22. package/dist/src/fireproof.d.ts +0 -472
  23. package/dist/src/fireproof.js +0 -81191
  24. package/dist/src/fireproof.js.map +0 -1
  25. package/dist/src/fireproof.mjs +0 -81186
  26. package/dist/src/fireproof.mjs.map +0 -1
  27. package/dist/storage/base.js +0 -426
  28. package/dist/storage/blocksToEncryptedCarBlock.js +0 -144
  29. package/dist/storage/browser.js +0 -62
  30. package/dist/storage/filesystem.js +0 -67
  31. package/dist/storage/rest.js +0 -57
  32. package/dist/storage/ucan.js +0 -0
  33. package/dist/storage/utils.js +0 -144
  34. package/dist/sync.js +0 -218
  35. package/dist/utils.js +0 -16
  36. package/dist/valet.js +0 -102
  37. package/src/blockstore.js +0 -283
  38. package/src/clock.js +0 -486
  39. package/src/crypto.js +0 -70
  40. package/src/database.js +0 -469
  41. package/src/db-index.js +0 -426
  42. package/src/encrypted-block.js +0 -57
  43. package/src/fireproof.js +0 -98
  44. package/src/import.js +0 -34
  45. package/src/link.d.ts +0 -3
  46. package/src/loader.js +0 -16
  47. package/src/prolly.js +0 -445
  48. package/src/remote.js +0 -113
  49. package/src/sha1.js +0 -83
  50. package/src/storage/base.js +0 -463
  51. package/src/storage/browser.js +0 -67
  52. package/src/storage/filesystem.js +0 -73
  53. package/src/storage/rest.js +0 -59
  54. package/src/storage/ucan.js +0 -0
  55. package/src/storage/utils.js +0 -152
  56. package/src/sync.js +0 -237
  57. package/src/valet.js +0 -105
@@ -1,426 +0,0 @@
1
- import randomBytes from 'randombytes';
2
- // import { randomBytes } from 'crypto'
3
- import { CarReader } from '@ipld/car';
4
- import { CID } from 'multiformats/cid';
5
- import { sha256 } from 'multiformats/hashes/sha2';
6
- import * as Block from 'multiformats/block';
7
- import * as dagcbor from '@ipld/dag-cbor';
8
- // @ts-ignore
9
- import { bf, simpleCompare as compare } from 'prolly-trees/utils';
10
- // @ts-ignore
11
- import { nocache as cache } from 'prolly-trees/cache';
12
- import { Buffer } from 'buffer';
13
- import { rawSha1 as sha1sync } from '../sha1.js';
14
- // @ts-ignore
15
- import * as codec from '../encrypted-block.js';
16
- import { blocksToEncryptedCarBlock, blocksToCarBlock, blocksFromEncryptedCarBlock, VMemoryBlockstore } from './utils.js';
17
- const chunker = bf(30);
18
- const blockOpts = { cache, chunker, codec: dagcbor, hasher: sha256, compare };
19
- const NO_ENCRYPT = typeof process !== 'undefined' && !!process.env?.NO_ENCRYPT;
20
- const NOT_IMPL = true;
21
- class Base {
22
- static format = '0.8';
23
- lastCar = null;
24
- carLog = [];
25
- keyMaterial = null;
26
- keyId = 'null';
27
- readonly = false;
28
- instanceId = Math.random().toString(36).slice(2);
29
- constructor(name, config = {}) {
30
- this.name = name;
31
- this.config = config;
32
- if (!this.config.branches) {
33
- this.config.branches = {
34
- main: { readonly: false }
35
- };
36
- }
37
- this.ready = this.getHeaders().then(blocksReady => {
38
- // console.log('blocksReady base', this.name, blocksReady)
39
- return blocksReady;
40
- });
41
- }
42
- setLastCar(car) {
43
- this.lastCar = car;
44
- this.carLog.unshift(car);
45
- }
46
- setKeyMaterial(km) {
47
- if (km && !NO_ENCRYPT) {
48
- const hex = Uint8Array.from(Buffer.from(km, 'hex'));
49
- this.keyMaterial = km;
50
- const hash = sha1sync(hex);
51
- this.keyId = Buffer.from(hash).toString('hex');
52
- }
53
- else {
54
- this.keyMaterial = null;
55
- this.keyId = 'null';
56
- }
57
- }
58
- async compact(clock) {
59
- if (this.readonly)
60
- return;
61
- if (clock.length !== 1) {
62
- throw new Error(`Compacting with clock length ${clock.length} instead of 1. To merge the clock, apply an update to the database first.`);
63
- }
64
- const cidMap = await this.getCidCarMap();
65
- const dataCids = new Set([...cidMap.keys()].filter(cid => cid[0] !== '_').map(cid => CID.parse(cid)));
66
- const allBlocks = new Map();
67
- for (const cid of dataCids) {
68
- const block = await this.getLoaderBlock(cid);
69
- allBlocks.set(cid, block.block);
70
- }
71
- cidMap.clear();
72
- let lastCid = clock[0];
73
- const blocks = {
74
- head: clock,
75
- lastCid,
76
- get: cid => allBlocks.get(cid.toString()),
77
- put: async (cid, block) => {
78
- allBlocks.set(cid.toString(), block);
79
- lastCid = cid.toString();
80
- }
81
- };
82
- // const lastCompactCar =
83
- await this.parkCar(blocks, dataCids); // todo this should remove old cars from the cid car map
84
- // console.log('compact', this.name, lastCompactCar.cid, blocks.lastCid.toString(), dataCids.length)
85
- // await this.setLastCompact(lastCompactCar.cid)
86
- }
87
- async parkCar(innerBlockstore, cids) {
88
- // console.log('parkCar', this.instanceId, this.name, this.readonly)
89
- if (this.readonly)
90
- return;
91
- // console.log('parkCar', this.name, this.carLog, innerBlockstore.head)
92
- const value = { fp: { last: innerBlockstore.lastCid, clock: innerBlockstore.head, cars: this.carLog } };
93
- const header = await Block.encode({ value, hasher: blockOpts.hasher, codec: blockOpts.codec });
94
- await innerBlockstore.put(header.cid, header.bytes);
95
- cids.add(header.cid.toString());
96
- let newCar;
97
- if (this.keyMaterial) {
98
- // console.log('encrypting car', innerBlockstore.label)
99
- newCar = await blocksToEncryptedCarBlock(innerBlockstore.lastCid, innerBlockstore, this.keyMaterial, [...cids]);
100
- }
101
- else {
102
- // todo should we pass cids in instead of iterating innerBlockstore?
103
- newCar = await blocksToCarBlock(innerBlockstore.lastCid, innerBlockstore);
104
- }
105
- return await this.saveCar(newCar.cid.toString(), newCar.bytes);
106
- }
107
- async saveCar(carCid, value) {
108
- // add the car cid to our in memory car list
109
- this.carLog.unshift(carCid);
110
- this.lastCar = carCid;
111
- // console.log('saveCar', this.name, carCid, this.carLog.length)
112
- await this.writeCars([
113
- {
114
- cid: carCid,
115
- bytes: value
116
- }
117
- ]);
118
- }
119
- async applyHeaders(headers) {
120
- // console.log('applyHeaders', headers.index)
121
- this.headers = headers;
122
- // console.log('before applied', this.instanceId, this.name, this.keyMaterial, this.valetRootCarCid)
123
- for (const [, header] of Object.entries(headers)) {
124
- if (header) {
125
- // console.log('applyHeaders', this.instanceId, this.name, header.key, header.car)
126
- header.key && this.setKeyMaterial(header.key);
127
- // this.setCarCidMapCarCid(header.car) // instead we should just extract the list of cars from the car
128
- const carHeader = await this.readHeaderCar(header.car);
129
- // console.log('carHeader', this.name, carHeader)
130
- this.carLog = carHeader.cars || [];
131
- // console.log('stored carHeader', this.name, this.config.type, this.carLog)
132
- // this.lastCar = header.car // ?
133
- if (header.car) {
134
- // console.log('header.car', header.car, this.blocks.valet.primary.carLog)
135
- this.setLastCar(header.car);
136
- }
137
- header.clock = carHeader.clock.map(c => c.toString());
138
- }
139
- }
140
- if (!this.keyMaterial) {
141
- const nullKey = this.config.key === null;
142
- if (nullKey || this.config.key) {
143
- this.setKeyMaterial(this.config.key);
144
- }
145
- else {
146
- this.setKeyMaterial(randomBytes(32).toString('hex'));
147
- }
148
- }
149
- // console.log('applied', this.instanceId, this.name, this.keyMaterial, this.valetRootCarCid)
150
- }
151
- async getHeaders() {
152
- const headers = {};
153
- for (const [branch] of Object.entries(this.config.branches)) {
154
- const got = await this.loadHeader(branch);
155
- headers[branch] = got;
156
- }
157
- await this.applyHeaders(headers);
158
- return headers;
159
- }
160
- loadHeader(branch = 'main') {
161
- if (NOT_IMPL)
162
- throw new Error('not implemented');
163
- return {};
164
- }
165
- async saveHeader(header) {
166
- // this.clock = header.clock
167
- // for each branch, save the header
168
- // console.log('saveHeader', this.config.branches)
169
- // for (const branch of this.branches) {
170
- // await this.saveBranchHeader(branch)
171
- // }
172
- for (const [branch, { readonly }] of Object.entries(this.config.branches)) {
173
- if (readonly)
174
- continue;
175
- // console.log('saveHeader', this.instanceId, this.name, branch, header)
176
- await this.writeHeader(branch, this.prepareHeader(header));
177
- }
178
- }
179
- prepareHeader(header, json = true) {
180
- header.key = this.keyMaterial;
181
- header.car = this.lastCar?.toString();
182
- // console.log('prepareHeader', this.instanceId, this.name, header)
183
- return json ? JSON.stringify(header) : header;
184
- }
185
- writeHeader(branch, header) {
186
- throw new Error('not implemented');
187
- }
188
- async getCarCIDForCID(cid) {
189
- // console.log('getCarCIDForCID', cid, this.carLog, this.config.type)
190
- // for each car in the car log
191
- for (const carCid of this.carLog) {
192
- const reader = await this.getCarReader(carCid);
193
- // console.log('getCarCIDForCID', carCid, cid)
194
- // if (reader.has(cid)) {
195
- // console.log('getCarCIDForCID found', cid)
196
- // return { result: carCid }
197
- // }
198
- for await (const block of reader.entries()) {
199
- // console.log('getCarCIDForCID', cid, block.cid.toString())
200
- // console.log('getCarCIDForCID', cid, block.cid.toString())
201
- if (block.cid.toString() === cid.toString()) {
202
- // console.log('getCarCIDForCID found', cid)
203
- return { result: carCid };
204
- }
205
- }
206
- }
207
- // console.log('getCarCIDForCID not found', cid, this.config.type)
208
- return { result: null };
209
- // return this.carLog[0]
210
- // const cidMap = await this.getCidCarMap()
211
- // const carCid = cidMap.get(cid.toString())
212
- // if (carCid) {
213
- // return { result: carCid }
214
- // }
215
- // return { result: null }
216
- }
217
- async readCar(carCid) {
218
- if (NOT_IMPL)
219
- throw new Error('not implemented');
220
- return new Uint8Array(carCid);
221
- }
222
- async getLoaderBlock(dataCID) {
223
- // console.log('getLoaderBlock', dataCID, this.config, this.carLog)
224
- const { result: carCid } = await this.getCarCIDForCID(dataCID);
225
- // console.log('gotLoaderBlock', dataCID, carCid)
226
- if (!carCid) {
227
- throw new Error('Missing car for: ' + dataCID);
228
- }
229
- const reader = await this.getCarReader(carCid);
230
- const block = await reader.get(dataCID);
231
- // console.log('gotLoaderBlock', dataCID, block.length)
232
- return { block, reader, carCid };
233
- }
234
- // async getLastSynced () {
235
- // const metadata = await this.getCidCarMap()
236
- // if (metadata.has('_last_sync_head')) {
237
- // return JSON.parse(metadata.get('_last_sync_head'))
238
- // } else {
239
- // return []
240
- // }
241
- // }
242
- // async setLastSynced (lastSynced) {
243
- // const metadata = await this.getCidCarMap()
244
- // metadata.set('_last_sync_head', JSON.stringify(lastSynced))
245
- // // await this.writeMetadata(metadata)
246
- // }
247
- // async getCompactSince (sinceHead) {
248
- // // get the car for the head
249
- // // find the location of the car in the metadata car sequence
250
- // }
251
- /** Private - internal **/
252
- async getCidCarMap() {
253
- if (this.valetCarCidMap)
254
- return this.valetCarCidMap;
255
- this.valetCarCidMap = new Map();
256
- return this.valetCarCidMap;
257
- }
258
- async readHeaderCar(carCid) {
259
- const carMapReader = await this.getCarReader(carCid);
260
- // await this.getWriteableCarReader(carCid)
261
- // console.log('readHeaderCar', carCid, carMapReader)
262
- // now when we load the root cid from the car, we get our new custom root node
263
- const bytes = await carMapReader.get(carMapReader.root.cid);
264
- const decoded = await Block.decode({ bytes, hasher: blockOpts.hasher, codec: blockOpts.codec });
265
- // @ts-ignore
266
- const { fp: { cars, clock } } = decoded.value;
267
- return { cars, clock, reader: carMapReader };
268
- }
269
- // todo this is only because parkCar wants a writable reader to put the metadata block
270
- // parkCar should handle it's own writeable wrapper, and it should love to be called with
271
- // a read only car reader
272
- async getWriteableCarReader(carReader) {
273
- // console.log('getWriteableCarReader')
274
- // const carReader = await this.getCarReader(carCid)
275
- // console.log('getWriteableCarReader', carCid, carReader)
276
- const theseWriteableBlocks = new VMemoryBlockstore();
277
- const combinedReader = {
278
- blocks: theseWriteableBlocks,
279
- root: carReader?.root,
280
- put: async (cid, bytes) => {
281
- return await theseWriteableBlocks.put(cid, bytes);
282
- },
283
- get: async (cid) => {
284
- // console.log('getWriteableCarReader get', cid)
285
- try {
286
- const got = await theseWriteableBlocks.get(cid);
287
- return got.bytes;
288
- }
289
- catch (e) {
290
- if (!carReader)
291
- throw e;
292
- const bytes = await carReader.get(cid);
293
- // console.log('getWriteableCarReader', cid, bytes)
294
- await theseWriteableBlocks.put(cid, bytes);
295
- return bytes;
296
- }
297
- }
298
- };
299
- return combinedReader;
300
- }
301
- carReaderCache = new Map();
302
- async getCarReader(carCid) {
303
- if (!this.carReaderCache.has(carCid)) {
304
- this.carReaderCache.set(carCid, this.getCarReaderImpl(carCid));
305
- }
306
- return this.carReaderCache.get(carCid);
307
- }
308
- async getCarReaderImpl(carCid) {
309
- carCid = carCid.toString();
310
- const carBytes = await this.readCar(carCid);
311
- // console.log('getCarReader', this.constructor.name, carCid, carBytes.length)
312
- const reader = await CarReader.fromBytes(carBytes);
313
- // console.log('getCarReader', carCid, reader._header)
314
- if (this.keyMaterial) {
315
- const roots = await reader.getRoots();
316
- const readerGetWithCodec = async (cid) => {
317
- const got = await reader.get(cid);
318
- let useCodec = codec;
319
- if (cid.toString().indexOf('bafy') === 0) {
320
- // @ts-ignore
321
- useCodec = dagcbor; // todo this is a dirty check
322
- }
323
- const decoded = await Block.decode({
324
- ...got,
325
- codec: useCodec,
326
- hasher: sha256
327
- });
328
- return decoded;
329
- };
330
- const { blocks } = await blocksFromEncryptedCarBlock(roots[0], readerGetWithCodec, this.keyMaterial);
331
- const rootBlock = blocks[blocks.length - 1];
332
- const blocksIterable = function* () {
333
- for (const block of blocks)
334
- yield block;
335
- };
336
- const gat = async (dataCID) => {
337
- dataCID = dataCID.toString();
338
- return blocks.find(b => b.cid.toString() === dataCID);
339
- };
340
- return {
341
- entries: blocksIterable,
342
- root: rootBlock,
343
- gat,
344
- get: async (dataCID) => {
345
- const block = await gat(dataCID);
346
- if (block) {
347
- return block.bytes;
348
- }
349
- }
350
- };
351
- }
352
- else {
353
- const gat = async (dataCID) => {
354
- return await reader.get(CID.parse(dataCID));
355
- };
356
- return {
357
- // blocks,
358
- entries: reader.blocks.bind(reader),
359
- root: reader.getRoots()[0],
360
- gat,
361
- get: async (dataCID) => {
362
- const gotBlock = await gat(dataCID);
363
- if (gotBlock) {
364
- return gotBlock.bytes;
365
- }
366
- }
367
- };
368
- }
369
- }
370
- writeCars(cars) { }
371
- // sequenceCarMapAppend (theCarMap, carCid) {
372
- // // _last_compact
373
- // // _last_sync (map per clock? you can find this by looking at a clocks car and it's position in the map)
374
- // const oldMark = theCarMap.get('_last_compact') // todo we can track _next_seq directly
375
- // // console.log('sequenceCarMapAppend oldMark', oldMark)
376
- // const lastCompact = oldMark ? charwise.decode(oldMark) : 0
377
- // // start iterating from the last compact point and find the first missing entry.
378
- // // then write the carCid to that entry
379
- // let next = lastCompact
380
- // while (true) {
381
- // const key = `_${charwise.encode(next)}`
382
- // if (!theCarMap.has(key)) {
383
- // console.log('sequenceCarMapAppend', next, key, carCid)
384
- // theCarMap.set(key, carCid.toString())
385
- // break
386
- // } else {
387
- // // const got = theCarMap.get(key)
388
- // next++
389
- // }
390
- // }
391
- // }
392
- // async setLastCompact (lastCompactCarCid) {
393
- // console.log('setLastCompact', lastCompactCarCid)
394
- // const theCarMap = await this.getCidCarMap()
395
- // const oldMark = theCarMap.get('_last_compact')
396
- // const lastCompact = oldMark ? charwise.decode(oldMark) : 0
397
- // let next = lastCompact
398
- // while (true) {
399
- // const key = `_${charwise.encode(next)}`
400
- // if (!theCarMap.has(key)) {
401
- // if (next === 0) {
402
- // theCarMap.set('_last_compact', charwise.encode(next))
403
- // break
404
- // } else {
405
- // throw new Error(`last compact point not found ${next} ${key}`)
406
- // }
407
- // } else {
408
- // const got = theCarMap.get(key)
409
- // // console.log('setLastCompact', key, got)
410
- // if (got === lastCompactCarCid) {
411
- // theCarMap.set('_last_compact', charwise.encode(next))
412
- // break
413
- // }
414
- // next++
415
- // }
416
- // }
417
- // }
418
- async updateCarCidMap(dataCarCid, cids, head) {
419
- // this hydrates the map if it has not been hydrated
420
- const theCarMap = await this.getCidCarMap();
421
- for (const cid of cids) {
422
- theCarMap.set(cid, dataCarCid);
423
- }
424
- }
425
- }
426
- export { Base };
@@ -1,144 +0,0 @@
1
- import * as CBW from '@ipld/car/buffer-writer';
2
- import * as raw from 'multiformats/codecs/raw';
3
- import { encrypt, decrypt } from '../crypto.js';
4
- import { parse } from 'multiformats/link';
5
- import { sha256 } from 'multiformats/hashes/sha2';
6
- import * as Block from 'multiformats/block';
7
- import { Buffer } from 'buffer';
8
- // @ts-ignore
9
- import { bf } from 'prolly-trees/utils';
10
- // @ts-ignore
11
- import { nocache as cache } from 'prolly-trees/cache';
12
- const chunker = bf(30);
13
- export async function getEmptyLoader() {
14
- const theseWriteableBlocks = new VMemoryBlockstore();
15
- return {
16
- blocks: theseWriteableBlocks,
17
- put: async (cid, bytes) => {
18
- return await theseWriteableBlocks.put(cid, bytes);
19
- },
20
- get: async (cid) => {
21
- const got = await theseWriteableBlocks.get(cid);
22
- return got.bytes;
23
- }
24
- };
25
- }
26
- export class VMemoryBlockstore {
27
- /** @type {Map<string, Uint8Array>} */
28
- blocks = new Map();
29
- instanceId = Math.random().toString(36).slice(2);
30
- async get(cid) {
31
- const bytes = this.blocks.get(cid.toString());
32
- if (!bytes)
33
- throw new Error('block not found ' + cid.toString());
34
- return { cid, bytes };
35
- }
36
- /**
37
- * @param {any} cid
38
- * @param {Uint8Array} bytes
39
- */
40
- async put(cid, bytes) {
41
- this.blocks.set(cid.toString(), bytes);
42
- }
43
- *entries() {
44
- for (const [str, bytes] of this.blocks) {
45
- yield { cid: parse(str), bytes };
46
- }
47
- }
48
- }
49
- export const blocksToCarBlock = async (rootCids, blocks) => {
50
- // console.log('blocksToCarBlock', rootCids, blocks.constructor.name)
51
- let size = 0;
52
- if (!Array.isArray(rootCids)) {
53
- rootCids = [rootCids];
54
- }
55
- const headerSize = CBW.headerLength({ roots: rootCids });
56
- size += headerSize;
57
- if (!Array.isArray(blocks)) {
58
- blocks = Array.from(blocks.entries());
59
- }
60
- for (const { cid, bytes } of blocks) {
61
- // console.log(cid, bytes)
62
- size += CBW.blockLength({ cid, bytes });
63
- }
64
- const buffer = new Uint8Array(size);
65
- const writer = await CBW.createWriter(buffer, { headerSize });
66
- for (const cid of rootCids) {
67
- writer.addRoot(cid);
68
- }
69
- for (const { cid, bytes } of blocks) {
70
- writer.write({ cid, bytes });
71
- }
72
- await writer.close();
73
- return await Block.encode({ value: writer.bytes, hasher: sha256, codec: raw });
74
- };
75
- export const blocksToEncryptedCarBlock = async (innerBlockStoreClockRootCid, blocks, keyMaterial, cids) => {
76
- const encryptionKey = Buffer.from(keyMaterial, 'hex');
77
- const encryptedBlocks = [];
78
- const theCids = cids;
79
- // console.trace('blocksToEncryptedCarBlock', blocks)
80
- // for (const { cid } of blocks.entries()) {
81
- // theCids.push(cid.toString())
82
- // }
83
- // console.log(
84
- // 'encrypting',
85
- // theCids.length,
86
- // 'blocks',
87
- // theCids.includes(innerBlockStoreClockRootCid.toString()),
88
- // keyMaterial
89
- // )
90
- // console.log('cids', theCids, innerBlockStoreClockRootCid.toString())
91
- let last;
92
- for await (const block of encrypt({
93
- cids: theCids,
94
- get: async (cid) => {
95
- // console.log('getencrypt', cid)
96
- const got = blocks.get(cid);
97
- // console.log('got', got)
98
- return got.block ? ({ cid, bytes: got.block }) : got;
99
- },
100
- key: encryptionKey,
101
- hasher: sha256,
102
- chunker,
103
- cache,
104
- // codec: dagcbor, // should be crypto?
105
- root: innerBlockStoreClockRootCid
106
- })) {
107
- encryptedBlocks.push(block);
108
- last = block;
109
- }
110
- // console.log('last', last.cid.toString(), 'for clock', innerBlockStoreClockRootCid.toString())
111
- const encryptedCar = await blocksToCarBlock(last.cid, encryptedBlocks);
112
- return encryptedCar;
113
- };
114
- // { root, get, key, cache, chunker, hasher }
115
- const memoizeDecryptedCarBlocks = new Map();
116
- export const blocksFromEncryptedCarBlock = async (cid, get, keyMaterial) => {
117
- if (memoizeDecryptedCarBlocks.has(cid.toString())) {
118
- return memoizeDecryptedCarBlocks.get(cid.toString());
119
- }
120
- else {
121
- const blocksPromise = (async () => {
122
- const decryptionKey = Buffer.from(keyMaterial, 'hex');
123
- // console.log('decrypting', keyMaterial, cid.toString())
124
- const cids = new Set();
125
- const decryptedBlocks = [];
126
- for await (const block of decrypt({
127
- root: cid,
128
- get,
129
- key: decryptionKey,
130
- chunker,
131
- hasher: sha256,
132
- cache
133
- // codec: dagcbor
134
- })) {
135
- // console.log('decrypted', block.cid.toString())
136
- decryptedBlocks.push(block);
137
- cids.add(block.cid.toString());
138
- }
139
- return { blocks: decryptedBlocks, cids };
140
- })();
141
- memoizeDecryptedCarBlocks.set(cid.toString(), blocksPromise);
142
- return blocksPromise;
143
- }
144
- };
@@ -1,62 +0,0 @@
1
- import { openDB } from 'idb';
2
- import { Base } from './base.js';
3
- const defaultConfig = {
4
- headerKeyPrefix: 'fp.' + Base.format
5
- };
6
- /* global localStorage */
7
- export class Browser extends Base {
8
- constructor(name, config = {}) {
9
- super(name, Object.assign({}, defaultConfig, config));
10
- }
11
- withDB = async (dbWorkFun) => {
12
- if (!this.idb) {
13
- this.idb = await openDB(`fp.${Base.format}.${this.keyId}.${this.name}.valet`, 3, {
14
- upgrade(db, oldVersion, newVersion, transaction) {
15
- if (oldVersion < 1) {
16
- db.createObjectStore('cars');
17
- }
18
- }
19
- });
20
- }
21
- return await dbWorkFun(this.idb);
22
- };
23
- async writeCars(cars) {
24
- if (this.config.readonly)
25
- return;
26
- return await this.withDB(async (db) => {
27
- const tx = db.transaction(['cars'], 'readwrite');
28
- for (const { cid, bytes, replaces } of cars) {
29
- await tx.objectStore('cars').put(bytes, cid.toString());
30
- // todo remove old maps
31
- if (replaces) {
32
- await tx.objectStore('cars').delete(replaces.toString());
33
- }
34
- }
35
- return await tx.done;
36
- });
37
- }
38
- async readCar(carCid) {
39
- return await this.withDB(async (db) => {
40
- const tx = db.transaction(['cars'], 'readonly');
41
- // console.log('getCarReader', carCid)
42
- return await tx.objectStore('cars').get(carCid);
43
- });
44
- }
45
- loadHeader(branch = 'main') {
46
- try {
47
- return JSON.parse(localStorage.getItem(this.headerKey(branch)));
48
- }
49
- catch (e) { }
50
- }
51
- async writeHeader(branch, header) {
52
- if (this.config.readonly)
53
- return;
54
- try {
55
- return localStorage.setItem(this.headerKey(branch), header);
56
- }
57
- catch (e) { }
58
- }
59
- headerKey(branch = 'main') {
60
- return this.config.headerKeyPrefix + this.name + '.' + branch;
61
- }
62
- }