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