@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,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