@fireproof/core 0.8.0-dev → 0.8.0-dev.3
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/crypto.js +5 -1
- package/dist/database.js +8 -4
- package/dist/remote.js +56 -0
- package/dist/src/fireproof.d.ts +4 -3
- package/dist/src/fireproof.js +59729 -22872
- package/dist/src/fireproof.js.map +1 -1
- package/dist/src/fireproof.mjs +59729 -22872
- package/dist/src/fireproof.mjs.map +1 -1
- package/dist/storage/base.js +161 -284
- 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/utils.js +144 -0
- package/dist/sync.js +1 -1
- package/dist/valet.js +9 -3
- package/package.json +3 -1
- package/src/crypto.js +5 -1
- package/src/database.js +9 -6
- package/src/remote.js +113 -0
- package/src/storage/base.js +178 -305
- package/src/storage/browser.js +1 -1
- package/src/storage/filesystem.js +2 -3
- package/src/storage/rest.js +1 -2
- package/src/storage/utils.js +152 -0
- package/src/sync.js +1 -1
- package/src/valet.js +9 -3
package/dist/crypto.js
CHANGED
@@ -11,7 +11,11 @@ const encrypt = async function* ({ get, cids, hasher, key, cache, chunker, root
|
|
11
11
|
let eroot;
|
12
12
|
for (const string of cids) {
|
13
13
|
const cid = CID.parse(string);
|
14
|
-
|
14
|
+
let unencrypted = await get(cid);
|
15
|
+
if (!unencrypted.cid) {
|
16
|
+
unencrypted = { cid, bytes: unencrypted };
|
17
|
+
}
|
18
|
+
// console.log('unencrypted', unencrypted)
|
15
19
|
const block = await encode({ ...await codec.encrypt({ ...unencrypted, key }), codec, hasher });
|
16
20
|
// console.log(`encrypting ${string} as ${block.cid}`)
|
17
21
|
yield block;
|
package/dist/database.js
CHANGED
@@ -4,6 +4,7 @@ import { doTransaction, TransactionBlockstore } from './blockstore.js';
|
|
4
4
|
import charwise from 'charwise';
|
5
5
|
import { CID } from 'multiformats';
|
6
6
|
import { DbIndex as Index } from './db-index.js';
|
7
|
+
import { Remote } from './remote.js';
|
7
8
|
// TypeScript Types
|
8
9
|
// eslint-disable-next-line no-unused-vars
|
9
10
|
// import { CID } from 'multiformats/dist/types/src/cid.js'
|
@@ -27,12 +28,15 @@ export class Database {
|
|
27
28
|
indexes = new Map();
|
28
29
|
rootCache = null;
|
29
30
|
eventsCache = new Map();
|
31
|
+
remote = null;
|
32
|
+
name = '';
|
30
33
|
constructor(name, config = {}) {
|
31
34
|
this.name = name;
|
32
35
|
this.clock = [];
|
33
36
|
this.instanceId = `fp.${this.name}.${Math.random().toString(36).substring(2, 7)}`;
|
34
37
|
this.blocks = new TransactionBlockstore(name, config);
|
35
38
|
this.indexBlocks = new TransactionBlockstore(name ? name + '.indexes' : null, { primary: config.index });
|
39
|
+
this.remote = new Remote(this, name, config);
|
36
40
|
this.config = config;
|
37
41
|
// todo we can wait for index blocks elsewhere
|
38
42
|
this.ready = Promise.all([this.blocks.ready, this.indexBlocks.ready]).then(([blocksReady, indexReady]) => {
|
@@ -49,7 +53,7 @@ export class Database {
|
|
49
53
|
clock.add(cid);
|
50
54
|
}
|
51
55
|
if (header.index) {
|
52
|
-
this.indexBlocks.valet.primary.
|
56
|
+
this.indexBlocks.valet.primary.setLastCar(header.index.car);
|
53
57
|
this.indexBlocks.valet.primary.setKeyMaterial(header.index.key);
|
54
58
|
}
|
55
59
|
if (header.indexes) {
|
@@ -87,7 +91,7 @@ export class Database {
|
|
87
91
|
name: this.name,
|
88
92
|
index: {
|
89
93
|
key: this.indexBlocks.valet?.primary.keyMaterial,
|
90
|
-
car: this.indexBlocks.valet?.primary.
|
94
|
+
car: this.indexBlocks.valet?.primary.lastCar?.toString()
|
91
95
|
},
|
92
96
|
indexes: [...this.indexes.values()].map(index => index.toJSON())
|
93
97
|
};
|
@@ -101,9 +105,9 @@ export class Database {
|
|
101
105
|
clockToJSON(clock = null) {
|
102
106
|
return (clock || this.clock).map(cid => cid.toString());
|
103
107
|
}
|
104
|
-
maybeSaveClock() {
|
108
|
+
async maybeSaveClock() {
|
105
109
|
if (this.name && this.blocks.valet) {
|
106
|
-
this.blocks.valet.saveHeader(this.toHeader());
|
110
|
+
await this.blocks.valet.saveHeader(this.toHeader());
|
107
111
|
}
|
108
112
|
}
|
109
113
|
index(name) {
|
package/dist/remote.js
CHANGED
@@ -26,6 +26,62 @@ export class Remote {
|
|
26
26
|
console.log('adv', adv, JSON.stringify(adv.root.data.ocm.out));
|
27
27
|
return { head, adv };
|
28
28
|
}
|
29
|
+
async sync(cid) {
|
30
|
+
// fetch the remote clock headCids using w3clock.head
|
31
|
+
const agent = this.client.agent();
|
32
|
+
const head = await w3clock.head({ issuer: agent, with: agent.did(), proofs: [] });
|
33
|
+
console.log('head', head, JSON.stringify(head.root.data.ocm.out));
|
34
|
+
const headCids = head.root.data.ocm.out.ok.head;
|
35
|
+
const lastSyncHead = await this.database.blocks.valet.primary.getLastSynced();
|
36
|
+
console.log('lastSyncHead', lastSyncHead);
|
37
|
+
const headSet = new Set(headCids.map(c => c.toString()));
|
38
|
+
const lastSyncSet = new Set(lastSyncHead.map(c => c.toString()));
|
39
|
+
// are they the same?
|
40
|
+
const same = headSet.size === lastSyncSet.size && [...headSet].every(value => lastSyncSet.has(value));
|
41
|
+
// if the headCids and the lastSyncHead are the same, we are in sync and can push
|
42
|
+
if (same) {
|
43
|
+
const currentHead = this.database.clock;
|
44
|
+
const currentHeadSet = new Set(currentHead.map(c => c.toString()));
|
45
|
+
console.log('synced with cloud', headSet, lastSyncSet);
|
46
|
+
// are they the same?
|
47
|
+
const currentSame = headSet.size === currentHeadSet.size && [...headSet].every(value => currentHeadSet.has(value));
|
48
|
+
if (currentSame) {
|
49
|
+
// we are in sync, do nothing
|
50
|
+
return true;
|
51
|
+
}
|
52
|
+
else {
|
53
|
+
console.log('push to cloud', headSet, currentHeadSet);
|
54
|
+
// we are ahead of the remote, push our clock
|
55
|
+
// const lastCompact = this.database.blocks.valet.primary.getLastCompact()
|
56
|
+
// get a compact since the last sync
|
57
|
+
console.log('we are ahead of the remote, push our clock');
|
58
|
+
// const compact = this.database.blocks.valet.primary.getCompactSince(lastSyncHead)
|
59
|
+
}
|
60
|
+
}
|
61
|
+
else {
|
62
|
+
// we are behind, fetch the remote
|
63
|
+
console.log('we are behind, fetch the remote');
|
64
|
+
}
|
65
|
+
// if it is the same as the local (current metadata carcid? `newValetCidCar` / sync clock), do nothing, we are in sync
|
66
|
+
// if it is the same as our previously pushed clock event, but our local clock is ahead of it, we need to push our clock
|
67
|
+
// - we can store the previous clock event cid in the metadata
|
68
|
+
// - sending our updates:
|
69
|
+
// - get the _last_sync and _last_compact values from our metadata
|
70
|
+
// - if last sync is after last compact
|
71
|
+
// - make a merged car file for the syncs
|
72
|
+
// - else
|
73
|
+
// - upload the car file for the last compact
|
74
|
+
// - make a merge car file for any uncompacted car files since the last compact, it should base its cidMap on the compact car file (as we go the sync stream will need to track it's own cidMap)
|
75
|
+
// - if there is only one car file, it is the merge car file (already based on last compact)
|
76
|
+
// - upload the merge car file
|
77
|
+
// - create a new clock block with the current w3clock.head as parent and the merge car file cid as the data
|
78
|
+
// - update the remote clock with the new clock block (it doesn't need to fetch the car file, and we dont need to store the clock blocks locally, just the most recent one)
|
79
|
+
//
|
80
|
+
// else if the remote head is not contained by our clock, it is is ahead of the local sync clock.
|
81
|
+
// - get the car file it points to from its data field
|
82
|
+
// - merge to the local clock (park that car so we have both carcid indexes)
|
83
|
+
// - calculate a new root from the merged head, and update the local clock
|
84
|
+
}
|
29
85
|
async connect(email) {
|
30
86
|
try {
|
31
87
|
const client = await create();
|
package/dist/src/fireproof.d.ts
CHANGED
@@ -160,7 +160,8 @@ declare class Database {
|
|
160
160
|
indexes: Map<any, any>;
|
161
161
|
rootCache: any;
|
162
162
|
eventsCache: Map<any, any>;
|
163
|
-
|
163
|
+
remote: any;
|
164
|
+
name: string;
|
164
165
|
clock: any[];
|
165
166
|
instanceId: string;
|
166
167
|
blocks: TransactionBlockstore;
|
@@ -175,7 +176,7 @@ declare class Database {
|
|
175
176
|
*/
|
176
177
|
toJSON(): any;
|
177
178
|
toHeader(): {
|
178
|
-
name:
|
179
|
+
name: string;
|
179
180
|
index: {
|
180
181
|
key: any;
|
181
182
|
car: any;
|
@@ -189,7 +190,7 @@ declare class Database {
|
|
189
190
|
* @instance
|
190
191
|
*/
|
191
192
|
clockToJSON(clock?: any): string[];
|
192
|
-
maybeSaveClock(): void
|
193
|
+
maybeSaveClock(): Promise<void>;
|
193
194
|
index(name: any): any;
|
194
195
|
/**
|
195
196
|
* Triggers a notification to all listeners
|