@fireproof/core 0.7.3-dev.2 → 0.8.0-dev.2
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/crypto.js +5 -1
- package/dist/database.js +14 -7
- package/dist/fireproof.js +1 -0
- package/dist/loader.js +0 -4
- package/dist/prolly.js +1 -1
- package/dist/remote.js +102 -0
- package/dist/src/fireproof.d.ts +6 -5
- package/dist/src/fireproof.js +65878 -29050
- package/dist/src/fireproof.js.map +1 -1
- package/dist/src/fireproof.mjs +65878 -29050
- package/dist/src/fireproof.mjs.map +1 -1
- package/dist/storage/base.js +177 -262
- package/dist/storage/blocksToEncryptedCarBlock.js +144 -0
- package/dist/storage/browser.js +1 -1
- package/dist/storage/filesystem.js +2 -3
- package/dist/storage/rest.js +1 -2
- package/dist/storage/ucan.js +0 -40
- package/dist/storage/utils.js +144 -0
- package/dist/sync.js +1 -1
- package/dist/valet.js +9 -3
- package/package.json +3 -5
- package/src/blockstore.js +4 -0
- package/src/crypto.js +5 -1
- package/src/database.js +14 -9
- package/src/fireproof.js +1 -0
- package/src/loader.js +0 -5
- package/src/prolly.js +1 -1
- package/src/remote.js +113 -0
- package/src/storage/base.js +194 -275
- package/src/storage/browser.js +1 -1
- package/src/storage/filesystem.js +2 -3
- package/src/storage/rest.js +1 -2
- package/src/storage/ucan.js +0 -45
- package/src/storage/utils.js +152 -0
- package/src/sync.js +1 -1
- package/src/valet.js +9 -3
@@ -0,0 +1,144 @@
|
|
1
|
+
import * as CBW from '@ipld/car/buffer-writer';
|
2
|
+
import * as raw from 'multiformats/codecs/raw';
|
3
|
+
import { encrypt, decrypt } from '../crypto.js';
|
4
|
+
import { parse } from 'multiformats/link';
|
5
|
+
import { sha256 } from 'multiformats/hashes/sha2';
|
6
|
+
import * as Block from 'multiformats/block';
|
7
|
+
import { Buffer } from 'buffer';
|
8
|
+
// @ts-ignore
|
9
|
+
import { bf } from 'prolly-trees/utils';
|
10
|
+
// @ts-ignore
|
11
|
+
import { nocache as cache } from 'prolly-trees/cache';
|
12
|
+
const chunker = bf(30);
|
13
|
+
export async function getEmptyLoader() {
|
14
|
+
const theseWriteableBlocks = new VMemoryBlockstore();
|
15
|
+
return {
|
16
|
+
blocks: theseWriteableBlocks,
|
17
|
+
put: async (cid, bytes) => {
|
18
|
+
return await theseWriteableBlocks.put(cid, bytes);
|
19
|
+
},
|
20
|
+
get: async (cid) => {
|
21
|
+
const got = await theseWriteableBlocks.get(cid);
|
22
|
+
return got.bytes;
|
23
|
+
}
|
24
|
+
};
|
25
|
+
}
|
26
|
+
export class VMemoryBlockstore {
|
27
|
+
/** @type {Map<string, Uint8Array>} */
|
28
|
+
blocks = new Map();
|
29
|
+
instanceId = Math.random().toString(36).slice(2);
|
30
|
+
async get(cid) {
|
31
|
+
const bytes = this.blocks.get(cid.toString());
|
32
|
+
if (!bytes)
|
33
|
+
throw new Error('block not found ' + cid.toString());
|
34
|
+
return { cid, bytes };
|
35
|
+
}
|
36
|
+
/**
|
37
|
+
* @param {any} cid
|
38
|
+
* @param {Uint8Array} bytes
|
39
|
+
*/
|
40
|
+
async put(cid, bytes) {
|
41
|
+
this.blocks.set(cid.toString(), bytes);
|
42
|
+
}
|
43
|
+
*entries() {
|
44
|
+
for (const [str, bytes] of this.blocks) {
|
45
|
+
yield { cid: parse(str), bytes };
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
export const blocksToCarBlock = async (rootCids, blocks) => {
|
50
|
+
// console.log('blocksToCarBlock', rootCids, blocks.constructor.name)
|
51
|
+
let size = 0;
|
52
|
+
if (!Array.isArray(rootCids)) {
|
53
|
+
rootCids = [rootCids];
|
54
|
+
}
|
55
|
+
const headerSize = CBW.headerLength({ roots: rootCids });
|
56
|
+
size += headerSize;
|
57
|
+
if (!Array.isArray(blocks)) {
|
58
|
+
blocks = Array.from(blocks.entries());
|
59
|
+
}
|
60
|
+
for (const { cid, bytes } of blocks) {
|
61
|
+
// console.log(cid, bytes)
|
62
|
+
size += CBW.blockLength({ cid, bytes });
|
63
|
+
}
|
64
|
+
const buffer = new Uint8Array(size);
|
65
|
+
const writer = await CBW.createWriter(buffer, { headerSize });
|
66
|
+
for (const cid of rootCids) {
|
67
|
+
writer.addRoot(cid);
|
68
|
+
}
|
69
|
+
for (const { cid, bytes } of blocks) {
|
70
|
+
writer.write({ cid, bytes });
|
71
|
+
}
|
72
|
+
await writer.close();
|
73
|
+
return await Block.encode({ value: writer.bytes, hasher: sha256, codec: raw });
|
74
|
+
};
|
75
|
+
export const blocksToEncryptedCarBlock = async (innerBlockStoreClockRootCid, blocks, keyMaterial, cids) => {
|
76
|
+
const encryptionKey = Buffer.from(keyMaterial, 'hex');
|
77
|
+
const encryptedBlocks = [];
|
78
|
+
const theCids = cids;
|
79
|
+
// console.trace('blocksToEncryptedCarBlock', blocks)
|
80
|
+
// for (const { cid } of blocks.entries()) {
|
81
|
+
// theCids.push(cid.toString())
|
82
|
+
// }
|
83
|
+
// console.log(
|
84
|
+
// 'encrypting',
|
85
|
+
// theCids.length,
|
86
|
+
// 'blocks',
|
87
|
+
// theCids.includes(innerBlockStoreClockRootCid.toString()),
|
88
|
+
// keyMaterial
|
89
|
+
// )
|
90
|
+
// console.log('cids', theCids, innerBlockStoreClockRootCid.toString())
|
91
|
+
let last;
|
92
|
+
for await (const block of encrypt({
|
93
|
+
cids: theCids,
|
94
|
+
get: async (cid) => {
|
95
|
+
// console.log('getencrypt', cid)
|
96
|
+
const got = blocks.get(cid);
|
97
|
+
// console.log('got', got)
|
98
|
+
return got.block ? ({ cid, bytes: got.block }) : got;
|
99
|
+
},
|
100
|
+
key: encryptionKey,
|
101
|
+
hasher: sha256,
|
102
|
+
chunker,
|
103
|
+
cache,
|
104
|
+
// codec: dagcbor, // should be crypto?
|
105
|
+
root: innerBlockStoreClockRootCid
|
106
|
+
})) {
|
107
|
+
encryptedBlocks.push(block);
|
108
|
+
last = block;
|
109
|
+
}
|
110
|
+
// console.log('last', last.cid.toString(), 'for clock', innerBlockStoreClockRootCid.toString())
|
111
|
+
const encryptedCar = await blocksToCarBlock(last.cid, encryptedBlocks);
|
112
|
+
return encryptedCar;
|
113
|
+
};
|
114
|
+
// { root, get, key, cache, chunker, hasher }
|
115
|
+
const memoizeDecryptedCarBlocks = new Map();
|
116
|
+
export const blocksFromEncryptedCarBlock = async (cid, get, keyMaterial) => {
|
117
|
+
if (memoizeDecryptedCarBlocks.has(cid.toString())) {
|
118
|
+
return memoizeDecryptedCarBlocks.get(cid.toString());
|
119
|
+
}
|
120
|
+
else {
|
121
|
+
const blocksPromise = (async () => {
|
122
|
+
const decryptionKey = Buffer.from(keyMaterial, 'hex');
|
123
|
+
// console.log('decrypting', keyMaterial, cid.toString())
|
124
|
+
const cids = new Set();
|
125
|
+
const decryptedBlocks = [];
|
126
|
+
for await (const block of decrypt({
|
127
|
+
root: cid,
|
128
|
+
get,
|
129
|
+
key: decryptionKey,
|
130
|
+
chunker,
|
131
|
+
hasher: sha256,
|
132
|
+
cache
|
133
|
+
// codec: dagcbor
|
134
|
+
})) {
|
135
|
+
// console.log('decrypted', block.cid.toString())
|
136
|
+
decryptedBlocks.push(block);
|
137
|
+
cids.add(block.cid.toString());
|
138
|
+
}
|
139
|
+
return { blocks: decryptedBlocks, cids };
|
140
|
+
})();
|
141
|
+
memoizeDecryptedCarBlocks.set(cid.toString(), blocksPromise);
|
142
|
+
return blocksPromise;
|
143
|
+
}
|
144
|
+
};
|
package/dist/storage/browser.js
CHANGED
@@ -40,12 +40,11 @@ export class Filesystem extends Base {
|
|
40
40
|
return JSON.parse(header);
|
41
41
|
}
|
42
42
|
async writeHeader(branch, header) {
|
43
|
-
// console.log('saveHeader',
|
43
|
+
// console.log('saveHeader fs', header)
|
44
44
|
if (this.config.readonly)
|
45
45
|
return;
|
46
|
-
const pHeader = this.prepareHeader(header);
|
47
46
|
// console.log('writeHeader fs', branch, pHeader)
|
48
|
-
await writeSync(this.headerFilename(branch),
|
47
|
+
await writeSync(this.headerFilename(branch), header);
|
49
48
|
}
|
50
49
|
headerFilename(branch = 'main') {
|
51
50
|
// console.log('headerFilename', this.config.dataDir, this.name)
|
package/dist/storage/rest.js
CHANGED
@@ -45,11 +45,10 @@ export class Rest extends Base {
|
|
45
45
|
async writeHeader(branch, header) {
|
46
46
|
if (this.config.readonly)
|
47
47
|
return;
|
48
|
-
const pHeader = this.prepareHeader(header);
|
49
48
|
// console.log('writeHeader rt', branch, pHeader)
|
50
49
|
const response = await fetch(this.headerURL(branch), {
|
51
50
|
method: 'PUT',
|
52
|
-
body:
|
51
|
+
body: header,
|
53
52
|
headers: { 'Content-Type': 'application/json' }
|
54
53
|
});
|
55
54
|
if (!response.ok)
|
package/dist/storage/ucan.js
CHANGED
@@ -1,40 +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
|
-
console.log(`write UCAN ${cid}, ${bytes.length} bytes`);
|
16
|
-
const upCid = await this.config.upload(bytes);
|
17
|
-
console.log(`wrote UCAN ${cid}, ${upCid}`);
|
18
|
-
// if (!response.ok) throw new Error(`An error occurred: ${response.statusText}`)
|
19
|
-
}
|
20
|
-
}
|
21
|
-
async readCar(carCid) {
|
22
|
-
const carURL = this.config.url(carCid);
|
23
|
-
const response = await fetch(carURL);
|
24
|
-
if (!response.ok)
|
25
|
-
throw new Error(`An error occurred: ${response.statusText}`);
|
26
|
-
const got = await response.arrayBuffer();
|
27
|
-
return new Uint8Array(got);
|
28
|
-
}
|
29
|
-
async loadHeader(branch = 'main') {
|
30
|
-
return headerMock.get(branch);
|
31
|
-
}
|
32
|
-
async writeHeader(branch, header) {
|
33
|
-
if (this.config.readonly)
|
34
|
-
return;
|
35
|
-
const pHeader = this.prepareHeader(header);
|
36
|
-
// console.log('writeHeader rt', branch, pHeader)
|
37
|
-
headerMock.set(branch, pHeader);
|
38
|
-
}
|
39
|
-
}
|
40
|
-
const headerMock = new Map();
|
@@ -0,0 +1,144 @@
|
|
1
|
+
import * as CBW from '@ipld/car/buffer-writer';
|
2
|
+
import * as raw from 'multiformats/codecs/raw';
|
3
|
+
import { encrypt, decrypt } from '../crypto.js';
|
4
|
+
import { parse } from 'multiformats/link';
|
5
|
+
import { sha256 } from 'multiformats/hashes/sha2';
|
6
|
+
import * as Block from 'multiformats/block';
|
7
|
+
import { Buffer } from 'buffer';
|
8
|
+
// @ts-ignore
|
9
|
+
import { bf } from 'prolly-trees/utils';
|
10
|
+
// @ts-ignore
|
11
|
+
import { nocache as cache } from 'prolly-trees/cache';
|
12
|
+
const chunker = bf(30);
|
13
|
+
export async function getEmptyLoader() {
|
14
|
+
const theseWriteableBlocks = new VMemoryBlockstore();
|
15
|
+
return {
|
16
|
+
blocks: theseWriteableBlocks,
|
17
|
+
put: async (cid, bytes) => {
|
18
|
+
return await theseWriteableBlocks.put(cid, bytes);
|
19
|
+
},
|
20
|
+
get: async (cid) => {
|
21
|
+
const got = await theseWriteableBlocks.get(cid);
|
22
|
+
return got.bytes;
|
23
|
+
}
|
24
|
+
};
|
25
|
+
}
|
26
|
+
export class VMemoryBlockstore {
|
27
|
+
/** @type {Map<string, Uint8Array>} */
|
28
|
+
blocks = new Map();
|
29
|
+
instanceId = Math.random().toString(36).slice(2);
|
30
|
+
async get(cid) {
|
31
|
+
const bytes = this.blocks.get(cid.toString());
|
32
|
+
if (!bytes)
|
33
|
+
throw new Error('block not found ' + cid.toString());
|
34
|
+
return { cid, bytes };
|
35
|
+
}
|
36
|
+
/**
|
37
|
+
* @param {any} cid
|
38
|
+
* @param {Uint8Array} bytes
|
39
|
+
*/
|
40
|
+
async put(cid, bytes) {
|
41
|
+
this.blocks.set(cid.toString(), bytes);
|
42
|
+
}
|
43
|
+
*entries() {
|
44
|
+
for (const [str, bytes] of this.blocks) {
|
45
|
+
yield { cid: parse(str), bytes };
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
export const blocksToCarBlock = async (rootCids, blocks) => {
|
50
|
+
// console.log('blocksToCarBlock', rootCids, blocks.constructor.name)
|
51
|
+
let size = 0;
|
52
|
+
if (!Array.isArray(rootCids)) {
|
53
|
+
rootCids = [rootCids];
|
54
|
+
}
|
55
|
+
const headerSize = CBW.headerLength({ roots: rootCids });
|
56
|
+
size += headerSize;
|
57
|
+
if (!Array.isArray(blocks)) {
|
58
|
+
blocks = Array.from(blocks.entries());
|
59
|
+
}
|
60
|
+
for (const { cid, bytes } of blocks) {
|
61
|
+
// console.log(cid, bytes)
|
62
|
+
size += CBW.blockLength({ cid, bytes });
|
63
|
+
}
|
64
|
+
const buffer = new Uint8Array(size);
|
65
|
+
const writer = await CBW.createWriter(buffer, { headerSize });
|
66
|
+
for (const cid of rootCids) {
|
67
|
+
writer.addRoot(cid);
|
68
|
+
}
|
69
|
+
for (const { cid, bytes } of blocks) {
|
70
|
+
writer.write({ cid, bytes });
|
71
|
+
}
|
72
|
+
await writer.close();
|
73
|
+
return await Block.encode({ value: writer.bytes, hasher: sha256, codec: raw });
|
74
|
+
};
|
75
|
+
export const blocksToEncryptedCarBlock = async (innerBlockStoreClockRootCid, blocks, keyMaterial, cids) => {
|
76
|
+
const encryptionKey = Buffer.from(keyMaterial, 'hex');
|
77
|
+
const encryptedBlocks = [];
|
78
|
+
const theCids = cids;
|
79
|
+
// console.trace('blocksToEncryptedCarBlock', blocks)
|
80
|
+
// for (const { cid } of blocks.entries()) {
|
81
|
+
// theCids.push(cid.toString())
|
82
|
+
// }
|
83
|
+
// console.log(
|
84
|
+
// 'encrypting',
|
85
|
+
// theCids.length,
|
86
|
+
// 'blocks',
|
87
|
+
// theCids.includes(innerBlockStoreClockRootCid.toString()),
|
88
|
+
// keyMaterial
|
89
|
+
// )
|
90
|
+
// console.log('cids', theCids, innerBlockStoreClockRootCid.toString())
|
91
|
+
let last;
|
92
|
+
for await (const block of encrypt({
|
93
|
+
cids: theCids,
|
94
|
+
get: async (cid) => {
|
95
|
+
// console.log('getencrypt', cid)
|
96
|
+
const got = blocks.get(cid);
|
97
|
+
// console.log('got', got)
|
98
|
+
return got.block ? ({ cid, bytes: got.block }) : got;
|
99
|
+
},
|
100
|
+
key: encryptionKey,
|
101
|
+
hasher: sha256,
|
102
|
+
chunker,
|
103
|
+
cache,
|
104
|
+
// codec: dagcbor, // should be crypto?
|
105
|
+
root: innerBlockStoreClockRootCid
|
106
|
+
})) {
|
107
|
+
encryptedBlocks.push(block);
|
108
|
+
last = block;
|
109
|
+
}
|
110
|
+
// console.log('last', last.cid.toString(), 'for clock', innerBlockStoreClockRootCid.toString())
|
111
|
+
const encryptedCar = await blocksToCarBlock(last.cid, encryptedBlocks);
|
112
|
+
return encryptedCar;
|
113
|
+
};
|
114
|
+
// { root, get, key, cache, chunker, hasher }
|
115
|
+
const memoizeDecryptedCarBlocks = new Map();
|
116
|
+
export const blocksFromEncryptedCarBlock = async (cid, get, keyMaterial) => {
|
117
|
+
if (memoizeDecryptedCarBlocks.has(cid.toString())) {
|
118
|
+
return memoizeDecryptedCarBlocks.get(cid.toString());
|
119
|
+
}
|
120
|
+
else {
|
121
|
+
const blocksPromise = (async () => {
|
122
|
+
const decryptionKey = Buffer.from(keyMaterial, 'hex');
|
123
|
+
// console.log('decrypting', keyMaterial, cid.toString())
|
124
|
+
const cids = new Set();
|
125
|
+
const decryptedBlocks = [];
|
126
|
+
for await (const block of decrypt({
|
127
|
+
root: cid,
|
128
|
+
get,
|
129
|
+
key: decryptionKey,
|
130
|
+
chunker,
|
131
|
+
hasher: sha256,
|
132
|
+
cache
|
133
|
+
// codec: dagcbor
|
134
|
+
})) {
|
135
|
+
// console.log('decrypted', block.cid.toString())
|
136
|
+
decryptedBlocks.push(block);
|
137
|
+
cids.add(block.cid.toString());
|
138
|
+
}
|
139
|
+
return { blocks: decryptedBlocks, cids };
|
140
|
+
})();
|
141
|
+
memoizeDecryptedCarBlocks.set(cid.toString(), blocksPromise);
|
142
|
+
return blocksPromise;
|
143
|
+
}
|
144
|
+
};
|
package/dist/sync.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import SimplePeer from 'simple-peer';
|
2
2
|
import { parseCID } from './database.js';
|
3
3
|
import { decodeEventBlock } from './clock.js';
|
4
|
-
import { blocksToCarBlock, blocksToEncryptedCarBlock } from './storage/
|
4
|
+
import { blocksToCarBlock, blocksToEncryptedCarBlock } from './storage/utils.js';
|
5
5
|
import { CarReader } from '@ipld/car';
|
6
6
|
/**
|
7
7
|
* @typedef {import('./database.js').Database} Database
|
package/dist/valet.js
CHANGED
@@ -75,16 +75,22 @@ export class Valet {
|
|
75
75
|
if (this.secondary) {
|
76
76
|
// console.log('getValetBlock secondary', dataCID)
|
77
77
|
try {
|
78
|
+
// eslint-disable-next-line
|
78
79
|
const { block, reader } = await this.secondary.getLoaderBlock(dataCID);
|
80
|
+
const writeableCarReader = await this.primary.getWriteableCarReader(reader);
|
81
|
+
// console.log('getValetBlock secondary', dataCID, block.length)
|
82
|
+
// eslint-disable-next-line
|
79
83
|
const cids = new Set();
|
80
84
|
for await (const { cid } of reader.entries()) {
|
81
85
|
// console.log(cid, bytes)
|
82
86
|
cids.add(cid.toString());
|
83
87
|
}
|
84
|
-
reader.get = reader.gat
|
88
|
+
// reader.get = reader.gat // some consumers prefer get
|
85
89
|
// console.log('replicating', reader.root)
|
86
|
-
|
87
|
-
|
90
|
+
writeableCarReader.lastCid = reader.root.cid;
|
91
|
+
writeableCarReader.head = [];
|
92
|
+
await this.primary.parkCar(writeableCarReader, cids).catch(e => console.error('parkCar error', e));
|
93
|
+
// console.log('FIX THIS', did)
|
88
94
|
return block;
|
89
95
|
}
|
90
96
|
catch (e) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fireproof/core",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.8.0-dev.2",
|
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,8 @@
|
|
42
42
|
"@ipld/car": "^5.1.0",
|
43
43
|
"@ipld/dag-cbor": "^9.0.0",
|
44
44
|
"@jsonlines/core": "^1.0.2",
|
45
|
-
"@
|
46
|
-
"@
|
47
|
-
"@ucanto/transport": "^8.0.0",
|
48
|
-
"@ucanto/validator": "^8.0.0",
|
45
|
+
"@web3-storage/clock": "^0.3.0",
|
46
|
+
"@web3-storage/w3up-client": "^7.0.0",
|
49
47
|
"async": "^3.2.4",
|
50
48
|
"charwise": "^3.0.1",
|
51
49
|
"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/crypto.js
CHANGED
@@ -16,7 +16,11 @@ const encrypt = async function * ({ get, cids, hasher, key, cache, chunker, root
|
|
16
16
|
let eroot
|
17
17
|
for (const string of cids) {
|
18
18
|
const cid = CID.parse(string)
|
19
|
-
|
19
|
+
let unencrypted = await get(cid)
|
20
|
+
if (!unencrypted.cid) {
|
21
|
+
unencrypted = { cid, bytes: unencrypted }
|
22
|
+
}
|
23
|
+
// console.log('unencrypted', unencrypted)
|
20
24
|
const block = await encode({ ...await codec.encrypt({ ...unencrypted, key }), codec, hasher })
|
21
25
|
// console.log(`encrypting ${string} as ${block.cid}`)
|
22
26
|
yield block
|
package/src/database.js
CHANGED
@@ -5,6 +5,8 @@ import charwise from 'charwise'
|
|
5
5
|
import { CID } from 'multiformats'
|
6
6
|
import { DbIndex as Index } from './db-index.js'
|
7
7
|
|
8
|
+
import { Remote } from './remote.js'
|
9
|
+
|
8
10
|
// TypeScript Types
|
9
11
|
// eslint-disable-next-line no-unused-vars
|
10
12
|
// import { CID } from 'multiformats/dist/types/src/cid.js'
|
@@ -29,14 +31,15 @@ export class Database {
|
|
29
31
|
indexes = new Map()
|
30
32
|
rootCache = null
|
31
33
|
eventsCache = new Map()
|
32
|
-
|
34
|
+
remote = null
|
35
|
+
name = ''
|
33
36
|
constructor (name, config = {}) {
|
34
37
|
this.name = name
|
35
38
|
this.clock = []
|
36
39
|
this.instanceId = `fp.${this.name}.${Math.random().toString(36).substring(2, 7)}`
|
37
40
|
this.blocks = new TransactionBlockstore(name, config)
|
38
41
|
this.indexBlocks = new TransactionBlockstore(name ? name + '.indexes' : null, { primary: config.index })
|
39
|
-
|
42
|
+
this.remote = new Remote(this, name, config)
|
40
43
|
this.config = config
|
41
44
|
// todo we can wait for index blocks elsewhere
|
42
45
|
this.ready = Promise.all([this.blocks.ready, this.indexBlocks.ready]).then(([blocksReady, indexReady]) => {
|
@@ -52,7 +55,7 @@ export class Database {
|
|
52
55
|
clock.add(cid)
|
53
56
|
}
|
54
57
|
if (header.index) {
|
55
|
-
this.indexBlocks.valet.primary.
|
58
|
+
this.indexBlocks.valet.primary.setLastCar(header.index.car)
|
56
59
|
this.indexBlocks.valet.primary.setKeyMaterial(header.index.key)
|
57
60
|
}
|
58
61
|
if (header.indexes) {
|
@@ -92,11 +95,11 @@ export class Database {
|
|
92
95
|
|
93
96
|
toHeader () {
|
94
97
|
return {
|
95
|
-
clock: this.clockToJSON(),
|
98
|
+
// clock: this.clockToJSON(),
|
96
99
|
name: this.name,
|
97
100
|
index: {
|
98
101
|
key: this.indexBlocks.valet?.primary.keyMaterial,
|
99
|
-
car: this.indexBlocks.valet?.primary.
|
102
|
+
car: this.indexBlocks.valet?.primary.lastCar?.toString()
|
100
103
|
},
|
101
104
|
indexes: [...this.indexes.values()].map(index => index.toJSON())
|
102
105
|
}
|
@@ -112,9 +115,9 @@ export class Database {
|
|
112
115
|
return (clock || this.clock).map(cid => cid.toString())
|
113
116
|
}
|
114
117
|
|
115
|
-
maybeSaveClock () {
|
118
|
+
async maybeSaveClock () {
|
116
119
|
if (this.name && this.blocks.valet) {
|
117
|
-
this.blocks.valet.saveHeader(this.toHeader())
|
120
|
+
await this.blocks.valet.saveHeader(this.toHeader())
|
118
121
|
}
|
119
122
|
}
|
120
123
|
|
@@ -277,11 +280,13 @@ export class Database {
|
|
277
280
|
* @memberof Fireproof
|
278
281
|
* @instance
|
279
282
|
*/
|
280
|
-
async put ({ _id, _proof, ...doc }) {
|
283
|
+
async put ({ _id, _proof, _clock, ...doc }) {
|
281
284
|
await this.ready
|
282
285
|
const id = _id || 'f' + Math.random().toString(36).slice(2)
|
286
|
+
doc = JSON.parse(JSON.stringify(doc))
|
287
|
+
if (_clock) doc._clock = _clock
|
283
288
|
await this.runValidation({ _id: id, ...doc })
|
284
|
-
return await this.putToProllyTree({ key: id, value: doc },
|
289
|
+
return await this.putToProllyTree({ key: id, value: doc }, _clock)
|
285
290
|
}
|
286
291
|
|
287
292
|
/**
|
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
|
)
|