@fireproof/core 0.7.3-dev.1 → 0.8.0-dev
Sign up to get free protection for your applications and to get access to all the features.
- 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()
|