@fireproof/core 0.8.0 → 0.10.1-dev

Sign up to get free protection for your applications and to get access to all the features.
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
- }