@fireproof/core 0.8.0 → 0.10.1-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/README.md +5 -184
- package/dist/fireproof.browser.js +18879 -0
- package/dist/fireproof.browser.js.map +7 -0
- package/dist/fireproof.cjs.js +9305 -0
- package/dist/fireproof.cjs.js.map +7 -0
- package/dist/fireproof.esm.js +9295 -0
- package/dist/fireproof.esm.js.map +7 -0
- package/package.json +57 -105
- package/dist/blockstore.js +0 -268
- package/dist/clock.js +0 -459
- package/dist/crypto.js +0 -63
- package/dist/database.js +0 -434
- package/dist/db-index.js +0 -403
- package/dist/encrypted-block.js +0 -48
- package/dist/fireproof.js +0 -84
- package/dist/import.js +0 -29
- package/dist/listener.js +0 -111
- package/dist/loader.js +0 -13
- package/dist/prolly.js +0 -405
- package/dist/remote.js +0 -102
- package/dist/sha1.js +0 -74
- package/dist/src/fireproof.d.ts +0 -472
- package/dist/src/fireproof.js +0 -81191
- package/dist/src/fireproof.js.map +0 -1
- package/dist/src/fireproof.mjs +0 -81186
- package/dist/src/fireproof.mjs.map +0 -1
- package/dist/storage/base.js +0 -426
- package/dist/storage/blocksToEncryptedCarBlock.js +0 -144
- package/dist/storage/browser.js +0 -62
- package/dist/storage/filesystem.js +0 -67
- package/dist/storage/rest.js +0 -57
- package/dist/storage/ucan.js +0 -0
- package/dist/storage/utils.js +0 -144
- package/dist/sync.js +0 -218
- package/dist/utils.js +0 -16
- package/dist/valet.js +0 -102
- package/src/blockstore.js +0 -283
- package/src/clock.js +0 -486
- package/src/crypto.js +0 -70
- package/src/database.js +0 -469
- package/src/db-index.js +0 -426
- package/src/encrypted-block.js +0 -57
- package/src/fireproof.js +0 -98
- package/src/import.js +0 -34
- package/src/link.d.ts +0 -3
- package/src/loader.js +0 -16
- package/src/prolly.js +0 -445
- package/src/remote.js +0 -113
- package/src/sha1.js +0 -83
- package/src/storage/base.js +0 -463
- package/src/storage/browser.js +0 -67
- package/src/storage/filesystem.js +0 -73
- package/src/storage/rest.js +0 -59
- package/src/storage/ucan.js +0 -0
- package/src/storage/utils.js +0 -152
- package/src/sync.js +0 -237
- package/src/valet.js +0 -105
@@ -1,67 +0,0 @@
|
|
1
|
-
// import { mkdir, writeFile } from 'fs/promises'
|
2
|
-
import { join, dirname } from 'path';
|
3
|
-
import { homedir } from 'os';
|
4
|
-
import { Base } from './base.js';
|
5
|
-
// import { readFileSync } from 'node:fs'
|
6
|
-
// const { readFileSync } = require('fs')
|
7
|
-
import fs from 'fs';
|
8
|
-
const readFileSync = fs.readFileSync;
|
9
|
-
export const defaultConfig = {
|
10
|
-
dataDir: join(homedir(), '.fireproof', 'v' + Base.format)
|
11
|
-
};
|
12
|
-
export class Filesystem extends Base {
|
13
|
-
constructor(name, config = {}) {
|
14
|
-
const mergedConfig = Object.assign({}, defaultConfig, config);
|
15
|
-
// console.log('Filesystem', name, mergedConfig, header)
|
16
|
-
super(name, mergedConfig);
|
17
|
-
}
|
18
|
-
async writeCars(cars) {
|
19
|
-
if (this.config.readonly)
|
20
|
-
return;
|
21
|
-
const writes = [];
|
22
|
-
for (const { cid, bytes } of cars) {
|
23
|
-
const carFilename = join(this.config.dataDir, this.name, `${cid.toString()}.car`);
|
24
|
-
// console.log('writeCars', carFilename)
|
25
|
-
writes.push(writeSync(carFilename, bytes));
|
26
|
-
}
|
27
|
-
await Promise.all(writes);
|
28
|
-
}
|
29
|
-
async readCar(carCid) {
|
30
|
-
const carFilename = join(this.config.dataDir, this.name, `${carCid.toString()}.car`);
|
31
|
-
const got = readFileSync(carFilename);
|
32
|
-
// console.log('readCar', carFilename, got.constructor.name)
|
33
|
-
return got;
|
34
|
-
}
|
35
|
-
loadHeader(branch = 'main') {
|
36
|
-
const header = loadSync(this.headerFilename(branch));
|
37
|
-
// console.log('fs getHeader', this.headerFilename(), header, typeof header)
|
38
|
-
if (!header)
|
39
|
-
return null;
|
40
|
-
return JSON.parse(header);
|
41
|
-
}
|
42
|
-
async writeHeader(branch, header) {
|
43
|
-
// console.log('saveHeader fs', header)
|
44
|
-
if (this.config.readonly)
|
45
|
-
return;
|
46
|
-
// console.log('writeHeader fs', branch, pHeader)
|
47
|
-
await writeSync(this.headerFilename(branch), header);
|
48
|
-
}
|
49
|
-
headerFilename(branch = 'main') {
|
50
|
-
// console.log('headerFilename', this.config.dataDir, this.name)
|
51
|
-
return join(this.config.dataDir, this.name, branch + '.json');
|
52
|
-
}
|
53
|
-
}
|
54
|
-
function loadSync(filename) {
|
55
|
-
try {
|
56
|
-
return readFileSync(filename, 'utf8').toString();
|
57
|
-
}
|
58
|
-
catch (error) {
|
59
|
-
// console.log('error', error)
|
60
|
-
return null;
|
61
|
-
}
|
62
|
-
}
|
63
|
-
async function writeSync(fullpath, stringValue) {
|
64
|
-
await fs.promises.mkdir(dirname(fullpath), { recursive: true });
|
65
|
-
// writeFileSync(fullpath, stringValue)
|
66
|
-
await fs.promises.writeFile(fullpath, stringValue);
|
67
|
-
}
|
package/dist/storage/rest.js
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
import fetch from 'cross-fetch';
|
2
|
-
import { Base } from './base.js';
|
3
|
-
const defaultConfig = {
|
4
|
-
url: 'http://localhost:4000/v' + Base.format
|
5
|
-
};
|
6
|
-
export class Rest extends Base {
|
7
|
-
constructor(name, config = {}) {
|
8
|
-
super(name, Object.assign({}, defaultConfig, config));
|
9
|
-
// console.log('Rest', name, config)
|
10
|
-
}
|
11
|
-
headerURL(branch = 'main') {
|
12
|
-
return `${this.config.url}/${branch}.json`;
|
13
|
-
}
|
14
|
-
async writeCars(cars) {
|
15
|
-
if (this.config.readonly)
|
16
|
-
return;
|
17
|
-
for (const { cid, bytes } of cars) {
|
18
|
-
const carURL = `${this.config.url}/${cid.toString()}.car`;
|
19
|
-
const response = await fetch(carURL, {
|
20
|
-
method: 'PUT',
|
21
|
-
body: bytes,
|
22
|
-
headers: { 'Content-Type': 'application/car' }
|
23
|
-
});
|
24
|
-
if (!response.ok)
|
25
|
-
throw new Error(`An error occurred: ${response.statusText}`);
|
26
|
-
}
|
27
|
-
}
|
28
|
-
async readCar(carCid) {
|
29
|
-
const carURL = `${this.config.url}/${carCid.toString()}.car`;
|
30
|
-
const response = await fetch(carURL);
|
31
|
-
if (!response.ok)
|
32
|
-
throw new Error(`An error occurred: ${response.statusText}`);
|
33
|
-
const got = await response.arrayBuffer();
|
34
|
-
return new Uint8Array(got);
|
35
|
-
}
|
36
|
-
async loadHeader(branch = 'main') {
|
37
|
-
const response = await fetch(this.headerURL(branch));
|
38
|
-
// console.log('rest getHeader', response.constructor.name)
|
39
|
-
if (!response.ok)
|
40
|
-
return null;
|
41
|
-
const got = await response.json();
|
42
|
-
// console.log('rest getHeader', got)
|
43
|
-
return got;
|
44
|
-
}
|
45
|
-
async writeHeader(branch, header) {
|
46
|
-
if (this.config.readonly)
|
47
|
-
return;
|
48
|
-
// console.log('writeHeader rt', branch, pHeader)
|
49
|
-
const response = await fetch(this.headerURL(branch), {
|
50
|
-
method: 'PUT',
|
51
|
-
body: header,
|
52
|
-
headers: { 'Content-Type': 'application/json' }
|
53
|
-
});
|
54
|
-
if (!response.ok)
|
55
|
-
throw new Error(`An error occurred: ${response.statusText}`);
|
56
|
-
}
|
57
|
-
}
|
package/dist/storage/ucan.js
DELETED
File without changes
|
package/dist/storage/utils.js
DELETED
@@ -1,144 +0,0 @@
|
|
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
DELETED
@@ -1,218 +0,0 @@
|
|
1
|
-
import SimplePeer from 'simple-peer';
|
2
|
-
import { parseCID } from './database.js';
|
3
|
-
import { decodeEventBlock } from './clock.js';
|
4
|
-
import { blocksToCarBlock, blocksToEncryptedCarBlock } from './storage/utils.js';
|
5
|
-
import { CarReader } from '@ipld/car';
|
6
|
-
/**
|
7
|
-
* @typedef {import('./database.js').Database} Database
|
8
|
-
*/
|
9
|
-
export class Sync {
|
10
|
-
/**
|
11
|
-
* @param {Database} database
|
12
|
-
* @param {typeof SimplePeer} [PeerClass]
|
13
|
-
* @memberof Sync
|
14
|
-
* @static
|
15
|
-
*/
|
16
|
-
status = 'new';
|
17
|
-
constructor(database, PeerClass = SimplePeer) {
|
18
|
-
this.database = database;
|
19
|
-
this.database.blocks.syncs.add(this); // should this happen during setup?
|
20
|
-
this.PeerClass = PeerClass;
|
21
|
-
this.pushBacklog = new Promise((resolve, reject) => {
|
22
|
-
this.pushBacklogResolve = resolve;
|
23
|
-
this.pushBacklogReject = reject;
|
24
|
-
});
|
25
|
-
this.isReady = false;
|
26
|
-
// this.pushBacklog.then(() => {
|
27
|
-
// // console.log('sync backlog resolved')
|
28
|
-
// this.database.notifyReset()
|
29
|
-
// })
|
30
|
-
// this.connected = new Promise((resolve, reject) => {
|
31
|
-
// this.readyResolve = resolve
|
32
|
-
// this.readyReject = reject
|
33
|
-
// })
|
34
|
-
}
|
35
|
-
async offer() {
|
36
|
-
this.status = 'offering';
|
37
|
-
return this.setupPeer(true);
|
38
|
-
}
|
39
|
-
async accept(base64offer) {
|
40
|
-
const offer = JSON.parse(atob(base64offer));
|
41
|
-
const p = this.setupPeer(false);
|
42
|
-
this.peer.signal(offer);
|
43
|
-
this.status = 'accepting';
|
44
|
-
return p;
|
45
|
-
}
|
46
|
-
connect(base64accept) {
|
47
|
-
const accept = JSON.parse(atob(base64accept));
|
48
|
-
this.status = 'connecting';
|
49
|
-
this.peer.signal(accept);
|
50
|
-
}
|
51
|
-
async setupPeer(initiator = false) {
|
52
|
-
this.peer = new this.PeerClass({
|
53
|
-
initiator,
|
54
|
-
trickle: false
|
55
|
-
});
|
56
|
-
this.peer.on('connect', () => this.startSync());
|
57
|
-
this.peer.on('data', data => this.gotData(data));
|
58
|
-
const p = new Promise((resolve, reject) => {
|
59
|
-
this.peer.on('signal', resolve);
|
60
|
-
this.peer.on('error', reject);
|
61
|
-
});
|
62
|
-
return p.then(signal => btoa(JSON.stringify(signal)));
|
63
|
-
}
|
64
|
-
async backlog() {
|
65
|
-
return this.pushBacklog;
|
66
|
-
}
|
67
|
-
async gotData(data) {
|
68
|
-
// console.log('got data', data.toString())
|
69
|
-
let reader = null;
|
70
|
-
try {
|
71
|
-
reader = await CarReader.fromBytes(data);
|
72
|
-
}
|
73
|
-
catch (e) {
|
74
|
-
// console.log('not a car', data.toString())
|
75
|
-
}
|
76
|
-
if (reader) {
|
77
|
-
// console.log('got car')
|
78
|
-
this.status = 'parking car';
|
79
|
-
const blz = new Set();
|
80
|
-
for await (const block of reader.blocks()) {
|
81
|
-
blz.add(block);
|
82
|
-
}
|
83
|
-
const roots = await reader.getRoots();
|
84
|
-
// console.log(
|
85
|
-
// 'got car',
|
86
|
-
// roots.map(c => c.toString()),
|
87
|
-
// this.database.clock.map(c => c.toString())
|
88
|
-
// )
|
89
|
-
// console.log(
|
90
|
-
// 'got blocks!',
|
91
|
-
// [...blz].map(({ cid }) => cid.toString())
|
92
|
-
// )
|
93
|
-
// @ts-ignore
|
94
|
-
reader.entries = reader.blocks;
|
95
|
-
await this.database.blocks.commit({
|
96
|
-
label: 'sync',
|
97
|
-
entries: () => [...blz],
|
98
|
-
get: async (cid) => await reader.get(cid),
|
99
|
-
lastCid: [...blz][0].cid // doesn't matter
|
100
|
-
}, false);
|
101
|
-
// first arg could be the roots parents?
|
102
|
-
// get the roots parents
|
103
|
-
const parents = await Promise.all(roots.map(async (cid) => {
|
104
|
-
const rbl = await reader.get(cid);
|
105
|
-
if (!rbl) {
|
106
|
-
console.log('missing root block', cid.toString(), reader);
|
107
|
-
throw new Error('missing root block');
|
108
|
-
}
|
109
|
-
const block = await decodeEventBlock(rbl.bytes);
|
110
|
-
return block.value.parents;
|
111
|
-
}));
|
112
|
-
this.database.applyClock(parents.flat(), roots);
|
113
|
-
this.database.notifyReset();
|
114
|
-
// console.log('after', this.database.clockToJSON())
|
115
|
-
this.pushBacklogResolve({ ok: true });
|
116
|
-
}
|
117
|
-
else {
|
118
|
-
// data is a json string, parse it
|
119
|
-
const message = JSON.parse(data.toString());
|
120
|
-
// console.log('got message', message)
|
121
|
-
if (message.ok) {
|
122
|
-
this.status = 'ok';
|
123
|
-
this.pushBacklogResolve({ ok: true });
|
124
|
-
}
|
125
|
-
else if (message.clock) {
|
126
|
-
const reqCidDiff = message;
|
127
|
-
// this might be a CID diff
|
128
|
-
// console.log('got diff', reqCidDiff)
|
129
|
-
const carBlock = await Sync.makeCar(this.database, null, reqCidDiff.cids);
|
130
|
-
if (!carBlock) {
|
131
|
-
// we are full synced
|
132
|
-
// console.log('we are full synced')
|
133
|
-
this.status = 'full synced';
|
134
|
-
this.peer.send(JSON.stringify({ ok: true }));
|
135
|
-
// this.pushBacklogResolve({ ok: true })
|
136
|
-
}
|
137
|
-
else {
|
138
|
-
// console.log('do send diff', carBlock.bytes.length)
|
139
|
-
this.status = 'sending diff car';
|
140
|
-
this.peer.send(carBlock.bytes);
|
141
|
-
// console.log('sent diff car')
|
142
|
-
// this.pushBacklogResolve({ ok: true })
|
143
|
-
}
|
144
|
-
}
|
145
|
-
}
|
146
|
-
}
|
147
|
-
destroy() {
|
148
|
-
this.database.blocks.syncs.delete(this);
|
149
|
-
this.status = 'destroyed';
|
150
|
-
// this.peer.destroy() todo
|
151
|
-
}
|
152
|
-
async sendUpdate(blockstore) {
|
153
|
-
if (!this.peer || !this.isReady)
|
154
|
-
return;
|
155
|
-
// console.log('send update from', this.database.instanceId)
|
156
|
-
// todo should send updates since last sync (currently sends each transaction)
|
157
|
-
const newCar = await blocksToCarBlock(blockstore.lastCid, blockstore);
|
158
|
-
this.status = 'sending update car';
|
159
|
-
this.peer.send(newCar.bytes);
|
160
|
-
}
|
161
|
-
async startSync() {
|
162
|
-
// console.log('start sync', this.peer.initiator)
|
163
|
-
this.isReady = true;
|
164
|
-
const allCIDs = await this.database.allStoredCIDs();
|
165
|
-
// console.log('allCIDs', allCIDs)
|
166
|
-
const reqCidDiff = {
|
167
|
-
clock: this.database.clockToJSON(),
|
168
|
-
cids: allCIDs.map(cid => cid.toString())
|
169
|
-
};
|
170
|
-
// console.log('send diff', reqCidDiff)
|
171
|
-
this.status = 'sending cid diff';
|
172
|
-
this.peer.send(JSON.stringify(reqCidDiff));
|
173
|
-
}
|
174
|
-
// get all the cids
|
175
|
-
// tell valet to make a file
|
176
|
-
/**
|
177
|
-
* @param {import("./database.js").Database} database
|
178
|
-
* @param {string} key
|
179
|
-
*/
|
180
|
-
static async makeCar(database, key, skip = []) {
|
181
|
-
const allCIDs = await database.allCIDs();
|
182
|
-
const blocks = database.blocks;
|
183
|
-
const rootCIDs = database.clock;
|
184
|
-
const newCIDs = [...new Set([...rootCIDs, ...allCIDs])].filter(cid => !skip.includes(cid.toString()));
|
185
|
-
const syncCIDs = [...new Set([...rootCIDs, ...allCIDs.filter(cid => !skip.includes(cid.toString()))])];
|
186
|
-
// console.log(
|
187
|
-
// 'makeCar',
|
188
|
-
// rootCIDs.map(c => c.toString()),
|
189
|
-
// syncCIDs.map(c => c.toString()),
|
190
|
-
// allCIDs.map(c => c.toString())
|
191
|
-
// )
|
192
|
-
if (newCIDs.length === 0) {
|
193
|
-
return null;
|
194
|
-
}
|
195
|
-
if (typeof key === 'undefined') {
|
196
|
-
key = blocks.valet?.primary.keyMaterial;
|
197
|
-
}
|
198
|
-
if (key) {
|
199
|
-
return blocksToEncryptedCarBlock(rootCIDs, {
|
200
|
-
entries: () => syncCIDs.map(cid => ({ cid })),
|
201
|
-
get: async (cid) => await blocks.get(cid)
|
202
|
-
}, key, syncCIDs.map(c => c.toString()));
|
203
|
-
}
|
204
|
-
else {
|
205
|
-
const carBlocks = await Promise.all(syncCIDs.map(async (c) => {
|
206
|
-
const b = await blocks.get(c);
|
207
|
-
if (typeof b.cid === 'string') {
|
208
|
-
b.cid = parseCID(b.cid);
|
209
|
-
}
|
210
|
-
return b;
|
211
|
-
}));
|
212
|
-
// console.log('carblock')
|
213
|
-
return blocksToCarBlock(rootCIDs, {
|
214
|
-
entries: () => carBlocks
|
215
|
-
});
|
216
|
-
}
|
217
|
-
}
|
218
|
-
}
|
package/dist/utils.js
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
/* global localStorage */
|
2
|
-
let storageSupported = false;
|
3
|
-
try {
|
4
|
-
storageSupported = window.localStorage && true;
|
5
|
-
}
|
6
|
-
catch (e) { }
|
7
|
-
export function localGet(key) {
|
8
|
-
if (storageSupported) {
|
9
|
-
return localStorage && localStorage.getItem(key);
|
10
|
-
}
|
11
|
-
}
|
12
|
-
export function localSet(key, value) {
|
13
|
-
if (storageSupported) {
|
14
|
-
return localStorage && localStorage.setItem(key, value);
|
15
|
-
}
|
16
|
-
}
|
package/dist/valet.js
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
import { Loader } from './loader.js';
|
2
|
-
export class Valet {
|
3
|
-
idb = null;
|
4
|
-
name = null;
|
5
|
-
uploadQueue = null;
|
6
|
-
alreadyEnqueued = new Set();
|
7
|
-
instanceId = Math.random().toString(36).slice(2);
|
8
|
-
constructor(name = 'default', config = {}) {
|
9
|
-
this.name = name;
|
10
|
-
// console.log('new Valet', name, config.primary)
|
11
|
-
this.primary = Loader.appropriate(name, config.primary);
|
12
|
-
this.secondary = config.secondary ? Loader.appropriate(name, config.secondary) : null;
|
13
|
-
// set up a promise listener that applies all the headers to the clock
|
14
|
-
// when they resolve
|
15
|
-
const readyP = [this.primary.ready];
|
16
|
-
if (this.secondary)
|
17
|
-
readyP.push(this.secondary.ready);
|
18
|
-
this.ready = Promise.all(readyP).then((blocksReady) => {
|
19
|
-
// console.log('blocksReady valet', this.name, blocksReady)
|
20
|
-
return blocksReady;
|
21
|
-
});
|
22
|
-
}
|
23
|
-
async saveHeader(header) {
|
24
|
-
// each storage needs to add its own carCidMapCarCid to the header
|
25
|
-
if (this.secondary) {
|
26
|
-
this.secondary.saveHeader(header);
|
27
|
-
} // todo: await?
|
28
|
-
return await this.primary.saveHeader(header);
|
29
|
-
}
|
30
|
-
async compact(clock) {
|
31
|
-
await this.primary.compact(clock);
|
32
|
-
if (this.secondary)
|
33
|
-
await this.secondary.compact(clock);
|
34
|
-
}
|
35
|
-
/**
|
36
|
-
* Group the blocks into a car and write it to the valet.
|
37
|
-
* @param {import('./blockstore.js').InnerBlockstore} innerBlockstore
|
38
|
-
* @param {Set<string>} cids
|
39
|
-
* @returns {Promise<void>}
|
40
|
-
* @memberof Valet
|
41
|
-
*/
|
42
|
-
async writeTransaction(innerBlockstore, cids) {
|
43
|
-
if (innerBlockstore.lastCid) {
|
44
|
-
await this.primary.parkCar(innerBlockstore, cids);
|
45
|
-
if (this.secondary)
|
46
|
-
await this.secondary.parkCar(innerBlockstore, cids);
|
47
|
-
}
|
48
|
-
else {
|
49
|
-
throw new Error('missing lastCid for car header');
|
50
|
-
}
|
51
|
-
}
|
52
|
-
/**
|
53
|
-
* Iterate over all blocks in the store.
|
54
|
-
*
|
55
|
-
* @yields {{cid: string, value: Uint8Array}}
|
56
|
-
* @returns {AsyncGenerator<any, any, any>}
|
57
|
-
*/
|
58
|
-
async *cids() {
|
59
|
-
// console.log('valet cids')
|
60
|
-
// todo use cidMap
|
61
|
-
// while (cursor) {
|
62
|
-
// yield { cid: cursor.key, car: cursor.value.car }
|
63
|
-
// cursor = await cursor.continue()
|
64
|
-
// }
|
65
|
-
}
|
66
|
-
remoteBlockFunction = null;
|
67
|
-
async getValetBlock(dataCID) {
|
68
|
-
// console.log('getValetBlock primary', dataCID)
|
69
|
-
try {
|
70
|
-
const { block } = await this.primary.getLoaderBlock(dataCID);
|
71
|
-
return block;
|
72
|
-
}
|
73
|
-
catch (e) {
|
74
|
-
// console.log('getValetBlock error', e)
|
75
|
-
if (this.secondary) {
|
76
|
-
// console.log('getValetBlock secondary', dataCID)
|
77
|
-
try {
|
78
|
-
// eslint-disable-next-line
|
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
|
83
|
-
const cids = new Set();
|
84
|
-
for await (const { cid } of reader.entries()) {
|
85
|
-
// console.log(cid, bytes)
|
86
|
-
cids.add(cid.toString());
|
87
|
-
}
|
88
|
-
// reader.get = reader.gat // some consumers prefer get
|
89
|
-
// console.log('replicating', reader.root)
|
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)
|
94
|
-
return block;
|
95
|
-
}
|
96
|
-
catch (e) {
|
97
|
-
// console.log('getValetBlock secondary error', e)
|
98
|
-
}
|
99
|
-
}
|
100
|
-
}
|
101
|
-
}
|
102
|
-
}
|