@fireproof/core 0.7.3-dev.1 → 0.8.0-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.
- package/dist/blockstore.js +6 -0
- package/dist/database.js +6 -3
- package/dist/fireproof.js +1 -0
- package/dist/loader.js +0 -4
- package/dist/prolly.js +1 -1
- package/dist/remote.js +46 -0
- package/dist/src/fireproof.d.ts +2 -2
- package/dist/src/fireproof.js +74 -68
- package/dist/src/fireproof.js.map +1 -1
- package/dist/src/fireproof.mjs +74 -68
- package/dist/src/fireproof.mjs.map +1 -1
- package/dist/storage/base.js +53 -15
- package/dist/storage/ucan.js +0 -39
- package/package.json +1 -5
- package/src/blockstore.js +4 -0
- package/src/database.js +5 -3
- package/src/fireproof.js +1 -0
- package/src/loader.js +0 -5
- package/src/prolly.js +1 -1
- package/src/storage/base.js +61 -15
- package/src/storage/ucan.js +0 -44
package/dist/storage/base.js
CHANGED
@@ -91,10 +91,11 @@ export class Base {
|
|
91
91
|
}
|
92
92
|
cidMap.clear();
|
93
93
|
const blocks = {
|
94
|
+
head: clock,
|
94
95
|
lastCid: clock[0],
|
95
96
|
get: cid => allBlocks.get(cid.toString())
|
96
97
|
};
|
97
|
-
console.log('compact', this.instanceId, this.name, blocks.lastCid.toString(), dataCids.length)
|
98
|
+
// console.log('compact', this.instanceId, this.name, blocks.lastCid.toString(), dataCids.length)
|
98
99
|
await this.parkCar(blocks, dataCids);
|
99
100
|
}
|
100
101
|
async parkCar(innerBlockstore, cids) {
|
@@ -111,10 +112,10 @@ export class Base {
|
|
111
112
|
newCar = await blocksToCarBlock(innerBlockstore.lastCid, innerBlockstore);
|
112
113
|
}
|
113
114
|
// console.log('new car', newCar.cid.toString())
|
114
|
-
return await this.saveCar(newCar.cid.toString(), newCar.bytes, cids);
|
115
|
+
return await this.saveCar(newCar.cid.toString(), newCar.bytes, cids, innerBlockstore.head);
|
115
116
|
}
|
116
|
-
async saveCar(carCid, value, cids) {
|
117
|
-
const newValetCidCar = await this.updateCarCidMap(carCid, cids);
|
117
|
+
async saveCar(carCid, value, cids, head = null) {
|
118
|
+
const newValetCidCar = await this.updateCarCidMap(carCid, cids, head);
|
118
119
|
// console.log('writeCars', carCid.toString(), newValetCidCar.cid.toString())
|
119
120
|
const carList = [
|
120
121
|
{
|
@@ -134,7 +135,7 @@ export class Base {
|
|
134
135
|
// console.trace('saved car', this.instanceId, this.name, newValetCidCar.cid.toString())
|
135
136
|
return newValetCidCar;
|
136
137
|
}
|
137
|
-
applyHeaders(headers) {
|
138
|
+
async applyHeaders(headers) {
|
138
139
|
// console.log('applyHeaders', headers.index)
|
139
140
|
this.headers = headers;
|
140
141
|
// console.log('before applied', this.instanceId, this.name, this.keyMaterial, this.valetRootCarCid)
|
@@ -143,6 +144,9 @@ export class Base {
|
|
143
144
|
// console.log('applyHeaders', this.instanceId, this.name, header.key, header.car)
|
144
145
|
header.key && this.setKeyMaterial(header.key);
|
145
146
|
this.setCarCidMapCarCid(header.car);
|
147
|
+
const { clock } = await this.readHeaderCar(header.car);
|
148
|
+
// console.log('stored clock', this.name, branch, clock, header)
|
149
|
+
header.clock = clock.map(c => c.toString());
|
146
150
|
}
|
147
151
|
}
|
148
152
|
if (!this.valetRootCarCid) {
|
@@ -163,18 +167,28 @@ export class Base {
|
|
163
167
|
const headers = {};
|
164
168
|
for (const [branch] of Object.entries(this.config.branches)) {
|
165
169
|
const got = await this.loadHeader(branch);
|
170
|
+
// const carCid = got.car
|
166
171
|
// console.log('getHeaders', this.name, branch, got)
|
172
|
+
// if (got && got.car) {
|
173
|
+
// const { clock } = await this.readHeaderCar(got.car)
|
174
|
+
// console.log('stored clock', this.name, branch, clock)
|
175
|
+
// }
|
167
176
|
headers[branch] = got;
|
168
177
|
}
|
169
|
-
this.applyHeaders(headers);
|
178
|
+
await this.applyHeaders(headers);
|
170
179
|
return headers;
|
171
180
|
}
|
172
181
|
loadHeader(branch = 'main') {
|
173
|
-
|
182
|
+
if (NOT_IMPL)
|
183
|
+
throw new Error('not implemented');
|
184
|
+
return {};
|
185
|
+
}
|
186
|
+
async getStoredClock(carCid) {
|
174
187
|
}
|
175
188
|
async saveHeader(header) {
|
189
|
+
// this.clock = header.clock
|
176
190
|
// for each branch, save the header
|
177
|
-
// console.log('saveHeader',
|
191
|
+
// console.log('saveHeader', header.clock)
|
178
192
|
// for (const branch of this.branches) {
|
179
193
|
// await this.saveBranchHeader(branch)
|
180
194
|
// }
|
@@ -233,8 +247,10 @@ export class Base {
|
|
233
247
|
async mapForIPLDHashmapCarCid(carCid) {
|
234
248
|
// console.log('mapForIPLDHashmapCarCid', carCid)
|
235
249
|
// todo why is this writeable?
|
236
|
-
const carMapReader = await this.
|
237
|
-
|
250
|
+
const { cars, reader: carMapReader } = await this.readHeaderCar(carCid);
|
251
|
+
// this.clock = clock
|
252
|
+
// console.log('mapForIPLDHashmapCarCid', cars)
|
253
|
+
const indexNode = await load(carMapReader, cars, {
|
238
254
|
blockHasher: blockOpts.hasher,
|
239
255
|
blockCodec: blockOpts.codec
|
240
256
|
});
|
@@ -245,9 +261,20 @@ export class Base {
|
|
245
261
|
}
|
246
262
|
return theCarMap;
|
247
263
|
}
|
264
|
+
async readHeaderCar(carCid) {
|
265
|
+
const carMapReader = await this.getWriteableCarReader(carCid);
|
266
|
+
// console.log('readHeaderCar', carCid, carMapReader)
|
267
|
+
// now when we load the root cid from the car, we get our new custom root node
|
268
|
+
const bytes = await carMapReader.get(carMapReader.root.cid);
|
269
|
+
const decoded = await Block.decode({ bytes, hasher: blockOpts.hasher, codec: blockOpts.codec });
|
270
|
+
// @ts-ignore
|
271
|
+
const { fp: { cars, clock } } = decoded.value;
|
272
|
+
return { cars, clock, reader: carMapReader };
|
273
|
+
}
|
248
274
|
async getWriteableCarReader(carCid) {
|
249
275
|
// console.log('getWriteableCarReader', carCid)
|
250
276
|
const carMapReader = await this.getCarReader(carCid);
|
277
|
+
// console.log('getWriteableCarReader', carCid, carMapReader)
|
251
278
|
const theseWriteableBlocks = new VMemoryBlockstore();
|
252
279
|
const combinedReader = {
|
253
280
|
blocks: theseWriteableBlocks,
|
@@ -283,12 +310,16 @@ export class Base {
|
|
283
310
|
}
|
284
311
|
async getCarReaderImpl(carCid) {
|
285
312
|
carCid = carCid.toString();
|
313
|
+
// console.log('getCarReaderImpl', carCid)
|
286
314
|
const carBytes = await this.readCar(carCid);
|
287
315
|
// console.log('getCarReader', this.constructor.name, carCid, carBytes.length)
|
288
316
|
const reader = await CarReader.fromBytes(carBytes);
|
317
|
+
// console.log('getCarReader', carCid, reader._header)
|
289
318
|
if (this.keyMaterial) {
|
290
319
|
const roots = await reader.getRoots();
|
320
|
+
// let count = 0
|
291
321
|
const readerGetWithCodec = async (cid) => {
|
322
|
+
// console.log('readerGetWithCodec', count++, cid)
|
292
323
|
const got = await reader.get(cid);
|
293
324
|
let useCodec = codec;
|
294
325
|
if (cid.toString().indexOf('bafy') === 0) {
|
@@ -343,16 +374,16 @@ export class Base {
|
|
343
374
|
}
|
344
375
|
}
|
345
376
|
writeCars(cars) { }
|
346
|
-
async updateCarCidMap(carCid, cids) {
|
377
|
+
async updateCarCidMap(carCid, cids, head) {
|
347
378
|
// this hydrates the map if it has not been hydrated
|
348
379
|
const theCarMap = await this.getCidCarMap();
|
349
380
|
for (const cid of cids) {
|
350
381
|
theCarMap.set(cid, carCid);
|
351
382
|
}
|
352
383
|
// todo can we debounce this? -- maybe put it into a queue so we can batch it
|
353
|
-
return await this.persistCarMap(theCarMap);
|
384
|
+
return await this.persistCarMap(theCarMap, head);
|
354
385
|
}
|
355
|
-
async persistCarMap(theCarMap) {
|
386
|
+
async persistCarMap(theCarMap, head) {
|
356
387
|
const ipldLoader = await getEmptyLoader();
|
357
388
|
const indexNode = await create(ipldLoader, {
|
358
389
|
bitWidth: 4,
|
@@ -363,14 +394,20 @@ export class Base {
|
|
363
394
|
for (const [key, value] of theCarMap.entries()) {
|
364
395
|
await indexNode.set(key, value);
|
365
396
|
}
|
397
|
+
// console.log('persistCarMap', indexNode.cid, head)
|
398
|
+
const value = { fp: { cars: indexNode.cid, clock: head } };
|
399
|
+
const header = await Block.encode({ value, hasher: blockOpts.hasher, codec: blockOpts.codec });
|
400
|
+
ipldLoader.blocks.put(header.cid, header.bytes);
|
366
401
|
let newValetCidCar;
|
367
402
|
if (this.keyMaterial) {
|
368
403
|
const cids = [...ipldLoader.blocks.blocks.keys()];
|
369
404
|
// console.log('persistCarMap', cids)
|
370
|
-
|
405
|
+
// store the clock head and a link to the indexNode.cid in a custom root?
|
406
|
+
newValetCidCar = await blocksToEncryptedCarBlock(header.cid, ipldLoader.blocks, this.keyMaterial, cids);
|
407
|
+
// then put this carcid into the header / w3clock
|
371
408
|
}
|
372
409
|
else {
|
373
|
-
newValetCidCar = await blocksToCarBlock(
|
410
|
+
newValetCidCar = await blocksToCarBlock(header.cid, ipldLoader.blocks);
|
374
411
|
}
|
375
412
|
return newValetCidCar;
|
376
413
|
}
|
@@ -497,6 +534,7 @@ export const blocksFromEncryptedCarBlock = async (cid, get, keyMaterial) => {
|
|
497
534
|
cache
|
498
535
|
// codec: dagcbor
|
499
536
|
})) {
|
537
|
+
// console.log('decrypted', block.cid.toString())
|
500
538
|
decryptedBlocks.push(block);
|
501
539
|
cids.add(block.cid.toString());
|
502
540
|
}
|
package/dist/storage/ucan.js
CHANGED
@@ -1,39 +0,0 @@
|
|
1
|
-
import fetch from 'cross-fetch';
|
2
|
-
import { Base } from './base.js';
|
3
|
-
const defaultConfig = {
|
4
|
-
upload: () => { },
|
5
|
-
url: (cid) => `https://${cid}.ipfs.w3s.link/`
|
6
|
-
};
|
7
|
-
export class UCAN extends Base {
|
8
|
-
constructor(name, config = {}) {
|
9
|
-
super(name, Object.assign({}, defaultConfig, config));
|
10
|
-
}
|
11
|
-
async writeCars(cars) {
|
12
|
-
if (this.config.readonly)
|
13
|
-
return;
|
14
|
-
for (const { cid, bytes } of cars) {
|
15
|
-
const upCid = await this.config.upload(bytes);
|
16
|
-
console.log('writeCar UCAN', cid, upCid);
|
17
|
-
// if (!response.ok) throw new Error(`An error occurred: ${response.statusText}`)
|
18
|
-
}
|
19
|
-
}
|
20
|
-
async readCar(carCid) {
|
21
|
-
const carURL = this.config.url(carCid);
|
22
|
-
const response = await fetch(carURL);
|
23
|
-
if (!response.ok)
|
24
|
-
throw new Error(`An error occurred: ${response.statusText}`);
|
25
|
-
const got = await response.arrayBuffer();
|
26
|
-
return new Uint8Array(got);
|
27
|
-
}
|
28
|
-
async loadHeader(branch = 'main') {
|
29
|
-
return headerMock.get(branch);
|
30
|
-
}
|
31
|
-
async writeHeader(branch, header) {
|
32
|
-
if (this.config.readonly)
|
33
|
-
return;
|
34
|
-
const pHeader = this.prepareHeader(header);
|
35
|
-
// console.log('writeHeader rt', branch, pHeader)
|
36
|
-
headerMock.set(branch, pHeader);
|
37
|
-
}
|
38
|
-
}
|
39
|
-
const headerMock = new Map();
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fireproof/core",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.8.0-dev",
|
4
4
|
"description": "Live data for React, accelerated by proofs, powered by IPFS",
|
5
5
|
"main": "dist/src/fireproof.js",
|
6
6
|
"module": "dist/src/fireproof.mjs",
|
@@ -42,10 +42,6 @@
|
|
42
42
|
"@ipld/car": "^5.1.0",
|
43
43
|
"@ipld/dag-cbor": "^9.0.0",
|
44
44
|
"@jsonlines/core": "^1.0.2",
|
45
|
-
"@ucanto/principal": "^8.0.0",
|
46
|
-
"@ucanto/server": "^8.0.1",
|
47
|
-
"@ucanto/transport": "^8.0.0",
|
48
|
-
"@ucanto/validator": "^8.0.0",
|
49
45
|
"async": "^3.2.4",
|
50
46
|
"charwise": "^3.0.1",
|
51
47
|
"cross-fetch": "^3.1.6",
|
package/src/blockstore.js
CHANGED
@@ -221,6 +221,9 @@ export const doTransaction = async (label, blockstore, doFun, doSync = true) =>
|
|
221
221
|
const innerBlockstore = blockstore.begin(label)
|
222
222
|
try {
|
223
223
|
const result = await doFun(innerBlockstore)
|
224
|
+
// console.log('doTransaction', label, 'result', result.head)
|
225
|
+
if (result && result.head) { innerBlockstore.head = result.head }
|
226
|
+
// pass the latest clock head for writing to the valet
|
224
227
|
// @ts-ignore
|
225
228
|
await blockstore.commit(innerBlockstore, doSync)
|
226
229
|
return result
|
@@ -236,6 +239,7 @@ export const doTransaction = async (label, blockstore, doFun, doSync = true) =>
|
|
236
239
|
export class InnerBlockstore {
|
237
240
|
/** @type {Map<string, Uint8Array>} */
|
238
241
|
blocks = new Map()
|
242
|
+
head = []
|
239
243
|
lastCid = null
|
240
244
|
label = ''
|
241
245
|
parentBlockstore = null
|
package/src/database.js
CHANGED
@@ -92,7 +92,7 @@ export class Database {
|
|
92
92
|
|
93
93
|
toHeader () {
|
94
94
|
return {
|
95
|
-
clock: this.clockToJSON(),
|
95
|
+
// clock: this.clockToJSON(),
|
96
96
|
name: this.name,
|
97
97
|
index: {
|
98
98
|
key: this.indexBlocks.valet?.primary.keyMaterial,
|
@@ -277,11 +277,13 @@ export class Database {
|
|
277
277
|
* @memberof Fireproof
|
278
278
|
* @instance
|
279
279
|
*/
|
280
|
-
async put ({ _id, _proof, ...doc }) {
|
280
|
+
async put ({ _id, _proof, _clock, ...doc }) {
|
281
281
|
await this.ready
|
282
282
|
const id = _id || 'f' + Math.random().toString(36).slice(2)
|
283
|
+
doc = JSON.parse(JSON.stringify(doc))
|
284
|
+
if (_clock) doc._clock = _clock
|
283
285
|
await this.runValidation({ _id: id, ...doc })
|
284
|
-
return await this.putToProllyTree({ key: id, value: doc },
|
286
|
+
return await this.putToProllyTree({ key: id, value: doc }, _clock)
|
285
287
|
}
|
286
288
|
|
287
289
|
/**
|
package/src/fireproof.js
CHANGED
package/src/loader.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import { Browser } from './storage/browser.js'
|
2
2
|
import { Rest } from './storage/rest.js'
|
3
|
-
import { UCAN } from './storage/ucan.js'
|
4
3
|
|
5
4
|
export const Loader = {
|
6
5
|
appropriate: (name, config = {}) => {
|
@@ -12,10 +11,6 @@ export const Loader = {
|
|
12
11
|
return new Rest(name, config)
|
13
12
|
}
|
14
13
|
|
15
|
-
if (config.type === 'ucan') {
|
16
|
-
return new UCAN(name, config)
|
17
|
-
}
|
18
|
-
|
19
14
|
return new Browser(name, config)
|
20
15
|
}
|
21
16
|
}
|
package/src/prolly.js
CHANGED
@@ -307,7 +307,7 @@ export async function root (inBlocks, head, doFull = false) {
|
|
307
307
|
bigPut(nb)
|
308
308
|
}
|
309
309
|
// console.log('root root', newProllyRootNode.constructor.name, newProllyRootNode)
|
310
|
-
return { clockCIDs, node: newProllyRootNode }
|
310
|
+
return { clockCIDs, node: newProllyRootNode, head }
|
311
311
|
},
|
312
312
|
false
|
313
313
|
)
|
package/src/storage/base.js
CHANGED
@@ -101,10 +101,11 @@ export class Base {
|
|
101
101
|
}
|
102
102
|
cidMap.clear()
|
103
103
|
const blocks = {
|
104
|
+
head: clock,
|
104
105
|
lastCid: clock[0],
|
105
106
|
get: cid => allBlocks.get(cid.toString())
|
106
107
|
}
|
107
|
-
console.log('compact', this.instanceId, this.name, blocks.lastCid.toString(), dataCids.length)
|
108
|
+
// console.log('compact', this.instanceId, this.name, blocks.lastCid.toString(), dataCids.length)
|
108
109
|
await this.parkCar(blocks, dataCids)
|
109
110
|
}
|
110
111
|
|
@@ -120,11 +121,11 @@ export class Base {
|
|
120
121
|
newCar = await blocksToCarBlock(innerBlockstore.lastCid, innerBlockstore)
|
121
122
|
}
|
122
123
|
// console.log('new car', newCar.cid.toString())
|
123
|
-
return await this.saveCar(newCar.cid.toString(), newCar.bytes, cids)
|
124
|
+
return await this.saveCar(newCar.cid.toString(), newCar.bytes, cids, innerBlockstore.head)
|
124
125
|
}
|
125
126
|
|
126
|
-
async saveCar (carCid, value, cids) {
|
127
|
-
const newValetCidCar = await this.updateCarCidMap(carCid, cids)
|
127
|
+
async saveCar (carCid, value, cids, head = null) {
|
128
|
+
const newValetCidCar = await this.updateCarCidMap(carCid, cids, head)
|
128
129
|
// console.log('writeCars', carCid.toString(), newValetCidCar.cid.toString())
|
129
130
|
const carList = [
|
130
131
|
{
|
@@ -146,7 +147,7 @@ export class Base {
|
|
146
147
|
return newValetCidCar
|
147
148
|
}
|
148
149
|
|
149
|
-
applyHeaders (headers) {
|
150
|
+
async applyHeaders (headers) {
|
150
151
|
// console.log('applyHeaders', headers.index)
|
151
152
|
this.headers = headers
|
152
153
|
// console.log('before applied', this.instanceId, this.name, this.keyMaterial, this.valetRootCarCid)
|
@@ -155,6 +156,9 @@ export class Base {
|
|
155
156
|
// console.log('applyHeaders', this.instanceId, this.name, header.key, header.car)
|
156
157
|
header.key && this.setKeyMaterial(header.key)
|
157
158
|
this.setCarCidMapCarCid(header.car)
|
159
|
+
const { clock } = await this.readHeaderCar(header.car)
|
160
|
+
// console.log('stored clock', this.name, branch, clock, header)
|
161
|
+
header.clock = clock.map(c => c.toString())
|
158
162
|
}
|
159
163
|
}
|
160
164
|
if (!this.valetRootCarCid) {
|
@@ -175,20 +179,32 @@ export class Base {
|
|
175
179
|
const headers = {}
|
176
180
|
for (const [branch] of Object.entries(this.config.branches)) {
|
177
181
|
const got = await this.loadHeader(branch)
|
182
|
+
// const carCid = got.car
|
178
183
|
// console.log('getHeaders', this.name, branch, got)
|
184
|
+
// if (got && got.car) {
|
185
|
+
// const { clock } = await this.readHeaderCar(got.car)
|
186
|
+
// console.log('stored clock', this.name, branch, clock)
|
187
|
+
// }
|
188
|
+
|
179
189
|
headers[branch] = got
|
180
190
|
}
|
181
|
-
this.applyHeaders(headers)
|
191
|
+
await this.applyHeaders(headers)
|
182
192
|
return headers
|
183
193
|
}
|
184
194
|
|
185
195
|
loadHeader (branch = 'main') {
|
186
|
-
throw new Error('not implemented')
|
196
|
+
if (NOT_IMPL) throw new Error('not implemented')
|
197
|
+
return {}
|
198
|
+
}
|
199
|
+
|
200
|
+
async getStoredClock (carCid) {
|
201
|
+
|
187
202
|
}
|
188
203
|
|
189
204
|
async saveHeader (header) {
|
205
|
+
// this.clock = header.clock
|
190
206
|
// for each branch, save the header
|
191
|
-
// console.log('saveHeader',
|
207
|
+
// console.log('saveHeader', header.clock)
|
192
208
|
// for (const branch of this.branches) {
|
193
209
|
// await this.saveBranchHeader(branch)
|
194
210
|
// }
|
@@ -251,8 +267,13 @@ export class Base {
|
|
251
267
|
async mapForIPLDHashmapCarCid (carCid) {
|
252
268
|
// console.log('mapForIPLDHashmapCarCid', carCid)
|
253
269
|
// todo why is this writeable?
|
254
|
-
const carMapReader = await this.
|
255
|
-
|
270
|
+
const { cars, reader: carMapReader } = await this.readHeaderCar(carCid)
|
271
|
+
|
272
|
+
// this.clock = clock
|
273
|
+
|
274
|
+
// console.log('mapForIPLDHashmapCarCid', cars)
|
275
|
+
|
276
|
+
const indexNode = await load(carMapReader, cars, {
|
256
277
|
blockHasher: blockOpts.hasher,
|
257
278
|
blockCodec: blockOpts.codec
|
258
279
|
})
|
@@ -264,9 +285,21 @@ export class Base {
|
|
264
285
|
return theCarMap
|
265
286
|
}
|
266
287
|
|
288
|
+
async readHeaderCar (carCid) {
|
289
|
+
const carMapReader = await this.getWriteableCarReader(carCid)
|
290
|
+
// console.log('readHeaderCar', carCid, carMapReader)
|
291
|
+
// now when we load the root cid from the car, we get our new custom root node
|
292
|
+
const bytes = await carMapReader.get(carMapReader.root.cid)
|
293
|
+
const decoded = await Block.decode({ bytes, hasher: blockOpts.hasher, codec: blockOpts.codec })
|
294
|
+
// @ts-ignore
|
295
|
+
const { fp: { cars, clock } } = decoded.value
|
296
|
+
return { cars, clock, reader: carMapReader }
|
297
|
+
}
|
298
|
+
|
267
299
|
async getWriteableCarReader (carCid) {
|
268
300
|
// console.log('getWriteableCarReader', carCid)
|
269
301
|
const carMapReader = await this.getCarReader(carCid)
|
302
|
+
// console.log('getWriteableCarReader', carCid, carMapReader)
|
270
303
|
const theseWriteableBlocks = new VMemoryBlockstore()
|
271
304
|
const combinedReader = {
|
272
305
|
blocks: theseWriteableBlocks,
|
@@ -303,12 +336,16 @@ export class Base {
|
|
303
336
|
|
304
337
|
async getCarReaderImpl (carCid) {
|
305
338
|
carCid = carCid.toString()
|
339
|
+
// console.log('getCarReaderImpl', carCid)
|
306
340
|
const carBytes = await this.readCar(carCid)
|
307
341
|
// console.log('getCarReader', this.constructor.name, carCid, carBytes.length)
|
308
342
|
const reader = await CarReader.fromBytes(carBytes)
|
343
|
+
// console.log('getCarReader', carCid, reader._header)
|
309
344
|
if (this.keyMaterial) {
|
310
345
|
const roots = await reader.getRoots()
|
346
|
+
// let count = 0
|
311
347
|
const readerGetWithCodec = async cid => {
|
348
|
+
// console.log('readerGetWithCodec', count++, cid)
|
312
349
|
const got = await reader.get(cid)
|
313
350
|
let useCodec = codec
|
314
351
|
if (cid.toString().indexOf('bafy') === 0) {
|
@@ -365,17 +402,17 @@ export class Base {
|
|
365
402
|
|
366
403
|
writeCars (cars) {}
|
367
404
|
|
368
|
-
async updateCarCidMap (carCid, cids) {
|
405
|
+
async updateCarCidMap (carCid, cids, head) {
|
369
406
|
// this hydrates the map if it has not been hydrated
|
370
407
|
const theCarMap = await this.getCidCarMap()
|
371
408
|
for (const cid of cids) {
|
372
409
|
theCarMap.set(cid, carCid)
|
373
410
|
}
|
374
411
|
// todo can we debounce this? -- maybe put it into a queue so we can batch it
|
375
|
-
return await this.persistCarMap(theCarMap)
|
412
|
+
return await this.persistCarMap(theCarMap, head)
|
376
413
|
}
|
377
414
|
|
378
|
-
async persistCarMap (theCarMap) {
|
415
|
+
async persistCarMap (theCarMap, head) {
|
379
416
|
const ipldLoader = await getEmptyLoader()
|
380
417
|
const indexNode = await create(ipldLoader, {
|
381
418
|
bitWidth: 4,
|
@@ -388,13 +425,21 @@ export class Base {
|
|
388
425
|
await indexNode.set(key, value)
|
389
426
|
}
|
390
427
|
|
428
|
+
// console.log('persistCarMap', indexNode.cid, head)
|
429
|
+
const value = { fp: { cars: indexNode.cid, clock: head } }
|
430
|
+
const header = await Block.encode({ value, hasher: blockOpts.hasher, codec: blockOpts.codec })
|
431
|
+
ipldLoader.blocks.put(header.cid, header.bytes)
|
432
|
+
|
391
433
|
let newValetCidCar
|
392
434
|
if (this.keyMaterial) {
|
393
435
|
const cids = [...ipldLoader.blocks.blocks.keys()]
|
394
436
|
// console.log('persistCarMap', cids)
|
395
|
-
|
437
|
+
// store the clock head and a link to the indexNode.cid in a custom root?
|
438
|
+
|
439
|
+
newValetCidCar = await blocksToEncryptedCarBlock(header.cid, ipldLoader.blocks, this.keyMaterial, cids)
|
440
|
+
// then put this carcid into the header / w3clock
|
396
441
|
} else {
|
397
|
-
newValetCidCar = await blocksToCarBlock(
|
442
|
+
newValetCidCar = await blocksToCarBlock(header.cid, ipldLoader.blocks)
|
398
443
|
}
|
399
444
|
return newValetCidCar
|
400
445
|
}
|
@@ -529,6 +574,7 @@ export const blocksFromEncryptedCarBlock = async (cid, get, keyMaterial) => {
|
|
529
574
|
cache
|
530
575
|
// codec: dagcbor
|
531
576
|
})) {
|
577
|
+
// console.log('decrypted', block.cid.toString())
|
532
578
|
decryptedBlocks.push(block)
|
533
579
|
cids.add(block.cid.toString())
|
534
580
|
}
|
package/src/storage/ucan.js
CHANGED
@@ -1,44 +0,0 @@
|
|
1
|
-
import fetch from 'cross-fetch'
|
2
|
-
import { Base } from './base.js'
|
3
|
-
|
4
|
-
const defaultConfig = {
|
5
|
-
upload: () => {},
|
6
|
-
url: (cid) => `https://${cid}.ipfs.w3s.link/`
|
7
|
-
}
|
8
|
-
|
9
|
-
export class UCAN extends Base {
|
10
|
-
constructor (name, config = {}) {
|
11
|
-
super(name, Object.assign({}, defaultConfig, config))
|
12
|
-
}
|
13
|
-
|
14
|
-
async writeCars (cars) {
|
15
|
-
if (this.config.readonly) return
|
16
|
-
for (const { cid, bytes } of cars) {
|
17
|
-
const upCid = await this.config.upload(bytes)
|
18
|
-
console.log('writeCar UCAN', cid, upCid)
|
19
|
-
// if (!response.ok) throw new Error(`An error occurred: ${response.statusText}`)
|
20
|
-
}
|
21
|
-
}
|
22
|
-
|
23
|
-
async readCar (carCid) {
|
24
|
-
const carURL = this.config.url(carCid)
|
25
|
-
const response = await fetch(carURL)
|
26
|
-
if (!response.ok) throw new Error(`An error occurred: ${response.statusText}`)
|
27
|
-
const got = await response.arrayBuffer()
|
28
|
-
return new Uint8Array(got)
|
29
|
-
}
|
30
|
-
|
31
|
-
async loadHeader (branch = 'main') {
|
32
|
-
return headerMock.get(branch)
|
33
|
-
}
|
34
|
-
|
35
|
-
async writeHeader (branch, header) {
|
36
|
-
if (this.config.readonly) return
|
37
|
-
const pHeader = this.prepareHeader(header)
|
38
|
-
// console.log('writeHeader rt', branch, pHeader)
|
39
|
-
|
40
|
-
headerMock.set(branch, pHeader)
|
41
|
-
}
|
42
|
-
}
|
43
|
-
|
44
|
-
const headerMock = new Map()
|