@fireproof/core 0.7.3-dev.2 → 0.8.0-dev.2
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/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
|
)
|