@weaveprotocol/core 0.1.1 → 0.2.0
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 +264 -42
- package/dist/identity/contact-key.d.ts +42 -0
- package/dist/identity/contact-key.d.ts.map +1 -0
- package/dist/identity/contact-key.js +133 -0
- package/dist/identity/contact-key.js.map +1 -0
- package/dist/index.d.ts +16 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -5
- package/dist/index.js.map +1 -1
- package/dist/network/mesh.d.ts +6 -0
- package/dist/network/mesh.d.ts.map +1 -1
- package/dist/network/mesh.js +11 -1
- package/dist/network/mesh.js.map +1 -1
- package/dist/network/multi-signaling.d.ts +12 -2
- package/dist/network/multi-signaling.d.ts.map +1 -1
- package/dist/network/multi-signaling.js +86 -14
- package/dist/network/multi-signaling.js.map +1 -1
- package/dist/network/peer-auth.d.ts +50 -16
- package/dist/network/peer-auth.d.ts.map +1 -1
- package/dist/network/peer-auth.js +52 -15
- package/dist/network/peer-auth.js.map +1 -1
- package/dist/node/carrier.d.ts +87 -0
- package/dist/node/carrier.d.ts.map +1 -1
- package/dist/node/carrier.js +180 -59
- package/dist/node/carrier.js.map +1 -1
- package/dist/node/copy.d.ts.map +1 -1
- package/dist/node/copy.js +6 -3
- package/dist/node/copy.js.map +1 -1
- package/dist/node/host.d.ts +117 -0
- package/dist/node/host.d.ts.map +1 -0
- package/dist/node/host.js +192 -0
- package/dist/node/host.js.map +1 -0
- package/dist/node/index.d.ts +6 -2
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +1 -0
- package/dist/node/index.js.map +1 -1
- package/dist/node/node.d.ts.map +1 -1
- package/dist/node/node.js +640 -25
- package/dist/node/node.js.map +1 -1
- package/dist/node/space-runtime.d.ts +42 -25
- package/dist/node/space-runtime.d.ts.map +1 -1
- package/dist/node/space-runtime.js +734 -35
- package/dist/node/space-runtime.js.map +1 -1
- package/dist/node/types.d.ts +269 -3
- package/dist/node/types.d.ts.map +1 -1
- package/dist/privacy/space-encryption.d.ts +16 -0
- package/dist/privacy/space-encryption.d.ts.map +1 -1
- package/dist/privacy/space-encryption.js +40 -0
- package/dist/privacy/space-encryption.js.map +1 -1
- package/dist/query/engine.js +1 -1
- package/dist/query/engine.js.map +1 -1
- package/dist/query/types.d.ts +7 -0
- package/dist/query/types.d.ts.map +1 -1
- package/dist/query/types.js.map +1 -1
- package/dist/react/use-query.d.ts +1 -1
- package/dist/react/use-query.d.ts.map +1 -1
- package/dist/records/topics.d.ts +21 -0
- package/dist/records/topics.d.ts.map +1 -0
- package/dist/records/topics.js +86 -0
- package/dist/records/topics.js.map +1 -0
- package/dist/schema/collection-def.d.ts +7 -0
- package/dist/schema/collection-def.d.ts.map +1 -1
- package/dist/schema/collection-def.js +4 -0
- package/dist/schema/collection-def.js.map +1 -1
- package/dist/schema/expression.d.ts +2 -0
- package/dist/schema/expression.d.ts.map +1 -1
- package/dist/schema/expression.js +1 -0
- package/dist/schema/expression.js.map +1 -1
- package/dist/schemas/contacts.d.ts +77 -0
- package/dist/schemas/contacts.d.ts.map +1 -0
- package/dist/schemas/contacts.js +35 -0
- package/dist/schemas/contacts.js.map +1 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/index.js.map +1 -1
- package/dist/session/auth.d.ts.map +1 -1
- package/dist/session/auth.js +14 -3
- package/dist/session/auth.js.map +1 -1
- package/dist/session/connect.d.ts +25 -1
- package/dist/session/connect.d.ts.map +1 -1
- package/dist/session/connect.js +9 -2
- package/dist/session/connect.js.map +1 -1
- package/dist/session/hosting.d.ts +155 -0
- package/dist/session/hosting.d.ts.map +1 -0
- package/dist/session/hosting.js +160 -0
- package/dist/session/hosting.js.map +1 -0
- package/dist/space/account-registry.d.ts +6 -0
- package/dist/space/account-registry.d.ts.map +1 -1
- package/dist/space/account-registry.js +16 -4
- package/dist/space/account-registry.js.map +1 -1
- package/dist/space/notify.d.ts +88 -0
- package/dist/space/notify.d.ts.map +1 -0
- package/dist/space/notify.js +127 -0
- package/dist/space/notify.js.map +1 -0
- package/dist/space/pass.d.ts +6 -0
- package/dist/space/pass.d.ts.map +1 -1
- package/dist/space/pass.js +5 -2
- package/dist/space/pass.js.map +1 -1
- package/dist/space/roles.d.ts +71 -0
- package/dist/space/roles.d.ts.map +1 -1
- package/dist/space/roles.js +114 -0
- package/dist/space/roles.js.map +1 -1
- package/dist/space/space-access.d.ts +24 -0
- package/dist/space/space-access.d.ts.map +1 -1
- package/dist/space/space-access.js +24 -0
- package/dist/space/space-access.js.map +1 -1
- package/dist/space/space-manager.d.ts +35 -1
- package/dist/space/space-manager.d.ts.map +1 -1
- package/dist/space/space-manager.js +72 -25
- package/dist/space/space-manager.js.map +1 -1
- package/dist/storage/blob/memory.d.ts +9 -0
- package/dist/storage/blob/memory.d.ts.map +1 -0
- package/dist/storage/blob/memory.js +20 -0
- package/dist/storage/blob/memory.js.map +1 -0
- package/dist/storage/blob/s3.d.ts +16 -0
- package/dist/storage/blob/s3.d.ts.map +1 -0
- package/dist/storage/blob/s3.js +86 -0
- package/dist/storage/blob/s3.js.map +1 -0
- package/dist/storage/blob-store.d.ts +26 -0
- package/dist/storage/blob-store.d.ts.map +1 -0
- package/dist/storage/blob-store.js +2 -0
- package/dist/storage/blob-store.js.map +1 -0
- package/dist/storage/encrypted-adapter.d.ts +3 -3
- package/dist/storage/encrypted-adapter.js +3 -3
- package/dist/storage/folder-adapter.d.ts +8 -8
- package/dist/storage/folder-adapter.d.ts.map +1 -1
- package/dist/storage/folder-adapter.js +7 -7
- package/dist/storage/folder-reconcile.d.ts +12 -14
- package/dist/storage/folder-reconcile.d.ts.map +1 -1
- package/dist/storage/folder-reconcile.js +20 -14
- package/dist/storage/folder-reconcile.js.map +1 -1
- package/dist/storage/index.d.ts +0 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +0 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/indexeddb-adapter.d.ts.map +1 -1
- package/dist/storage/indexeddb-adapter.js +8 -9
- package/dist/storage/indexeddb-adapter.js.map +1 -1
- package/dist/storage/mirror.d.ts +68 -0
- package/dist/storage/mirror.d.ts.map +1 -0
- package/dist/storage/mirror.js +174 -0
- package/dist/storage/mirror.js.map +1 -0
- package/dist/storage/segment.d.ts +20 -0
- package/dist/storage/segment.d.ts.map +1 -0
- package/dist/storage/segment.js +27 -0
- package/dist/storage/segment.js.map +1 -0
- package/dist/storage/storage-provider.d.ts +36 -40
- package/dist/storage/storage-provider.d.ts.map +1 -1
- package/dist/storage/storage-provider.js +208 -117
- package/dist/storage/storage-provider.js.map +1 -1
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/negentropy.d.ts +68 -0
- package/dist/sync/negentropy.d.ts.map +1 -0
- package/dist/sync/negentropy.js +379 -0
- package/dist/sync/negentropy.js.map +1 -0
- package/dist/sync/sync-engine.d.ts +45 -13
- package/dist/sync/sync-engine.d.ts.map +1 -1
- package/dist/sync/sync-engine.js +290 -207
- package/dist/sync/sync-engine.js.map +1 -1
- package/dist/sync/sync-messages.d.ts +42 -32
- package/dist/sync/sync-messages.d.ts.map +1 -1
- package/dist/sync/sync-messages.js +1 -1
- package/dist/sync/sync-messages.js.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/hash.d.ts +9 -0
- package/dist/utils/hash.d.ts.map +1 -1
- package/dist/utils/hash.js +33 -0
- package/dist/utils/hash.js.map +1 -1
- package/package.json +9 -3
- package/dist/storage/mst.d.ts +0 -121
- package/dist/storage/mst.d.ts.map +0 -1
- package/dist/storage/mst.js +0 -402
- package/dist/storage/mst.js.map +0 -1
- package/dist/sync/anti-entropy.d.ts +0 -49
- package/dist/sync/anti-entropy.d.ts.map +0 -1
- package/dist/sync/anti-entropy.js +0 -62
- package/dist/sync/anti-entropy.js.map +0 -1
package/dist/storage/mst.js
DELETED
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module mst
|
|
3
|
-
* Merkle Search Tree (MST) — a deterministic, content-addressed ordered map.
|
|
4
|
-
*
|
|
5
|
-
* Every key carries a height derived from its own hash (see {@link nodeHeight}),
|
|
6
|
-
* and a key lives in the node at exactly that height. Because the height comes
|
|
7
|
-
* from the key rather than from insertion order, the same set of entries always
|
|
8
|
-
* produces the same tree — and therefore the same root CID — no matter what
|
|
9
|
-
* order it was built in. That determinism is what makes the root usable as a
|
|
10
|
-
* one-word summary of a peer's state, and what lets two peers skip any subtree
|
|
11
|
-
* whose CID they both already hold.
|
|
12
|
-
*
|
|
13
|
-
* Nodes are immutable: an insert rewrites only the path from the touched node
|
|
14
|
-
* up to the root, which is O(log N) nodes rather than the whole tree.
|
|
15
|
-
*/
|
|
16
|
-
import { utf8Encode, utf8Decode } from '../utils/encoding.js';
|
|
17
|
-
import { sha256, cidFromBytes } from '../utils/hash.js';
|
|
18
|
-
/**
|
|
19
|
-
* Creates an empty MST node at the given height.
|
|
20
|
-
* @param height The height the node sits at.
|
|
21
|
-
* @returns An empty node.
|
|
22
|
-
*/
|
|
23
|
-
export function createEmptyNode(height = 0) {
|
|
24
|
-
return Object.freeze({
|
|
25
|
-
height,
|
|
26
|
-
keys: Object.freeze([]),
|
|
27
|
-
values: Object.freeze([]),
|
|
28
|
-
children: Object.freeze([null])
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Canonical JSON serialization of an MST node.
|
|
33
|
-
* @param node The node to serialize.
|
|
34
|
-
* @returns The canonical bytes.
|
|
35
|
-
*/
|
|
36
|
-
export function serializeNode(node) {
|
|
37
|
-
// Field order is fixed so the same node always hashes to the same CID.
|
|
38
|
-
const obj = {
|
|
39
|
-
height: node.height,
|
|
40
|
-
keys: node.keys,
|
|
41
|
-
values: node.values,
|
|
42
|
-
children: node.children
|
|
43
|
-
};
|
|
44
|
-
return utf8Encode(JSON.stringify(obj));
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Deserialize an MST node.
|
|
48
|
-
* @param data The canonical bytes.
|
|
49
|
-
* @returns The node.
|
|
50
|
-
*/
|
|
51
|
-
export function deserializeNode(data) {
|
|
52
|
-
const obj = JSON.parse(utf8Decode(data));
|
|
53
|
-
return Object.freeze({
|
|
54
|
-
height: obj.height ?? 0,
|
|
55
|
-
keys: Object.freeze([...obj.keys]),
|
|
56
|
-
values: Object.freeze([...obj.values]),
|
|
57
|
-
children: Object.freeze([...obj.children])
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Hashes a node to get its CID.
|
|
62
|
-
* @param node The node to hash.
|
|
63
|
-
* @returns The node's CID.
|
|
64
|
-
*/
|
|
65
|
-
export async function hashNode(node) {
|
|
66
|
-
const bytes = serializeNode(node);
|
|
67
|
-
return cidFromBytes(bytes);
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Calculate the deterministic height of a key using SHA-256.
|
|
71
|
-
* Counts leading zero bits in the hash, divided by 4 — so roughly one key in
|
|
72
|
-
* 16 sits a level higher than the last, giving the tree its branching factor.
|
|
73
|
-
* @param key The key to place.
|
|
74
|
-
* @returns The height the key belongs at.
|
|
75
|
-
*/
|
|
76
|
-
export async function nodeHeight(key) {
|
|
77
|
-
const hashBytes = await sha256(utf8Encode(key));
|
|
78
|
-
let zeros = 0;
|
|
79
|
-
for (let i = 0; i < hashBytes.length; i++) {
|
|
80
|
-
const byte = hashBytes[i];
|
|
81
|
-
if (byte === 0) {
|
|
82
|
-
zeros += 8;
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
let temp = byte;
|
|
86
|
-
while ((temp & 0x80) === 0) {
|
|
87
|
-
zeros++;
|
|
88
|
-
temp <<= 1;
|
|
89
|
-
}
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return Math.floor(zeros / 4);
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Load a node from the storage adapter.
|
|
97
|
-
* @param adapter The storage adapter.
|
|
98
|
-
* @param cid The node's CID.
|
|
99
|
-
* @returns The node.
|
|
100
|
-
*/
|
|
101
|
-
export async function loadNode(adapter, cid) {
|
|
102
|
-
const data = await adapter.get(cid);
|
|
103
|
-
if (!data)
|
|
104
|
-
throw new Error(`Node not found: ${cid}`);
|
|
105
|
-
return deserializeNode(data);
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Save a node to the storage adapter and return its CID.
|
|
109
|
-
* @param adapter The storage adapter.
|
|
110
|
-
* @param node The node to store.
|
|
111
|
-
* @returns The node's CID.
|
|
112
|
-
*/
|
|
113
|
-
export async function saveNode(adapter, node) {
|
|
114
|
-
const bytes = serializeNode(node);
|
|
115
|
-
const cid = await cidFromBytes(bytes);
|
|
116
|
-
await adapter.put(cid, bytes);
|
|
117
|
-
return cid;
|
|
118
|
-
}
|
|
119
|
-
// --------------------------------------------------------------- internals
|
|
120
|
-
/** Index of the first key that is greater than or equal to `target`. */
|
|
121
|
-
function lowerBound(keys, target) {
|
|
122
|
-
let lo = 0;
|
|
123
|
-
let hi = keys.length;
|
|
124
|
-
while (lo < hi) {
|
|
125
|
-
const mid = (lo + hi) >> 1;
|
|
126
|
-
if (keys[mid] < target)
|
|
127
|
-
lo = mid + 1;
|
|
128
|
-
else
|
|
129
|
-
hi = mid;
|
|
130
|
-
}
|
|
131
|
-
return lo;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Stores a node, unless it carries nothing at all — an empty node with no
|
|
135
|
-
* surviving child is simply an absent subtree, and representing it as `null`
|
|
136
|
-
* keeps the tree canonical.
|
|
137
|
-
*/
|
|
138
|
-
async function saveOrPrune(adapter, node) {
|
|
139
|
-
if (node.keys.length === 0 && node.children.every(child => child === null))
|
|
140
|
-
return null;
|
|
141
|
-
return saveNode(adapter, node);
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Wraps a subtree in empty parent nodes until it sits at `toHeight`.
|
|
145
|
-
*
|
|
146
|
-
* A height gap has to be filled with real nodes rather than skipped, because
|
|
147
|
-
* every tree holding the same keys must produce the same CIDs.
|
|
148
|
-
*/
|
|
149
|
-
async function lift(adapter, cid, fromHeight, toHeight) {
|
|
150
|
-
if (cid === null)
|
|
151
|
-
return null;
|
|
152
|
-
let current = cid;
|
|
153
|
-
for (let h = fromHeight + 1; h <= toHeight; h++) {
|
|
154
|
-
current = await saveNode(adapter, Object.freeze({
|
|
155
|
-
height: h,
|
|
156
|
-
keys: Object.freeze([]),
|
|
157
|
-
values: Object.freeze([]),
|
|
158
|
-
children: Object.freeze([current])
|
|
159
|
-
}));
|
|
160
|
-
}
|
|
161
|
-
return current;
|
|
162
|
-
}
|
|
163
|
-
/** Builds a subtree topped at `topHeight` holding exactly one entry. */
|
|
164
|
-
async function singleton(adapter, key, value, keyHeight, topHeight) {
|
|
165
|
-
const leaf = await saveNode(adapter, Object.freeze({
|
|
166
|
-
height: keyHeight,
|
|
167
|
-
keys: Object.freeze([key]),
|
|
168
|
-
values: Object.freeze([value]),
|
|
169
|
-
children: Object.freeze([null, null])
|
|
170
|
-
}));
|
|
171
|
-
return (await lift(adapter, leaf, keyHeight, topHeight));
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Splits a subtree into the entries below `key` and those above it, both
|
|
175
|
-
* returned at the input subtree's height.
|
|
176
|
-
*/
|
|
177
|
-
async function splitSubtree(adapter, cid, key) {
|
|
178
|
-
if (cid === null)
|
|
179
|
-
return [null, null];
|
|
180
|
-
const node = await loadNode(adapter, cid);
|
|
181
|
-
const idx = lowerBound(node.keys, key);
|
|
182
|
-
// The child at `idx` straddles the split point, so it splits too.
|
|
183
|
-
const [childLeft, childRight] = await splitSubtree(adapter, node.children[idx] ?? null, key);
|
|
184
|
-
const left = {
|
|
185
|
-
height: node.height,
|
|
186
|
-
keys: node.keys.slice(0, idx),
|
|
187
|
-
values: node.values.slice(0, idx),
|
|
188
|
-
children: [...node.children.slice(0, idx), childLeft]
|
|
189
|
-
};
|
|
190
|
-
const right = {
|
|
191
|
-
height: node.height,
|
|
192
|
-
keys: node.keys.slice(idx),
|
|
193
|
-
values: node.values.slice(idx),
|
|
194
|
-
children: [childRight, ...node.children.slice(idx + 1)]
|
|
195
|
-
};
|
|
196
|
-
return [await saveOrPrune(adapter, left), await saveOrPrune(adapter, right)];
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Merges two adjacent subtrees of equal height, where every key on the left
|
|
200
|
-
* sorts before every key on the right.
|
|
201
|
-
*/
|
|
202
|
-
async function mergeSubtrees(adapter, left, right) {
|
|
203
|
-
if (left === null)
|
|
204
|
-
return right;
|
|
205
|
-
if (right === null)
|
|
206
|
-
return left;
|
|
207
|
-
const leftNode = await loadNode(adapter, left);
|
|
208
|
-
const rightNode = await loadNode(adapter, right);
|
|
209
|
-
// The two subtrees meet at the left's last child and the right's first.
|
|
210
|
-
const middle = await mergeSubtrees(adapter, leftNode.children[leftNode.children.length - 1] ?? null, rightNode.children[0] ?? null);
|
|
211
|
-
return saveOrPrune(adapter, {
|
|
212
|
-
height: leftNode.height,
|
|
213
|
-
keys: [...leftNode.keys, ...rightNode.keys],
|
|
214
|
-
values: [...leftNode.values, ...rightNode.values],
|
|
215
|
-
children: [...leftNode.children.slice(0, -1), middle, ...rightNode.children.slice(1)]
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
/** Inserts into a subtree known to sit at `subtreeHeight`. */
|
|
219
|
-
async function insertInto(adapter, cid, subtreeHeight, key, value, keyHeight) {
|
|
220
|
-
if (cid === null)
|
|
221
|
-
return singleton(adapter, key, value, keyHeight, subtreeHeight);
|
|
222
|
-
const node = await loadNode(adapter, cid);
|
|
223
|
-
const idx = lowerBound(node.keys, key);
|
|
224
|
-
if (keyHeight === node.height) {
|
|
225
|
-
if (node.keys[idx] === key) {
|
|
226
|
-
const values = [...node.values];
|
|
227
|
-
values[idx] = value;
|
|
228
|
-
return saveNode(adapter, { ...node, values });
|
|
229
|
-
}
|
|
230
|
-
// The key lands between two existing keys, so the subtree that currently
|
|
231
|
-
// spans that gap has to be split around it.
|
|
232
|
-
const [childLeft, childRight] = await splitSubtree(adapter, node.children[idx] ?? null, key);
|
|
233
|
-
return saveNode(adapter, {
|
|
234
|
-
height: node.height,
|
|
235
|
-
keys: [...node.keys.slice(0, idx), key, ...node.keys.slice(idx)],
|
|
236
|
-
values: [...node.values.slice(0, idx), value, ...node.values.slice(idx)],
|
|
237
|
-
children: [...node.children.slice(0, idx), childLeft, childRight, ...node.children.slice(idx + 1)]
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
// The key belongs further down; only this child changes.
|
|
241
|
-
const child = await insertInto(adapter, node.children[idx] ?? null, node.height - 1, key, value, keyHeight);
|
|
242
|
-
const children = [...node.children];
|
|
243
|
-
children[idx] = child;
|
|
244
|
-
return saveNode(adapter, { ...node, children });
|
|
245
|
-
}
|
|
246
|
-
/** Removes from a subtree, returning its new CID, or `null` if nothing is left. */
|
|
247
|
-
async function deleteFrom(adapter, cid, key, keyHeight) {
|
|
248
|
-
if (cid === null)
|
|
249
|
-
return null;
|
|
250
|
-
const node = await loadNode(adapter, cid);
|
|
251
|
-
// A key sitting above this node cannot appear anywhere beneath it.
|
|
252
|
-
if (keyHeight > node.height)
|
|
253
|
-
return cid;
|
|
254
|
-
const idx = lowerBound(node.keys, key);
|
|
255
|
-
if (keyHeight === node.height) {
|
|
256
|
-
if (node.keys[idx] !== key)
|
|
257
|
-
return cid;
|
|
258
|
-
// Removing the separator joins the subtrees on either side of it.
|
|
259
|
-
const merged = await mergeSubtrees(adapter, node.children[idx] ?? null, node.children[idx + 1] ?? null);
|
|
260
|
-
return saveOrPrune(adapter, {
|
|
261
|
-
height: node.height,
|
|
262
|
-
keys: [...node.keys.slice(0, idx), ...node.keys.slice(idx + 1)],
|
|
263
|
-
values: [...node.values.slice(0, idx), ...node.values.slice(idx + 1)],
|
|
264
|
-
children: [...node.children.slice(0, idx), merged, ...node.children.slice(idx + 2)]
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
const existing = node.children[idx] ?? null;
|
|
268
|
-
const child = await deleteFrom(adapter, existing, key, keyHeight);
|
|
269
|
-
if (child === existing)
|
|
270
|
-
return cid;
|
|
271
|
-
const children = [...node.children];
|
|
272
|
-
children[idx] = child;
|
|
273
|
-
return saveOrPrune(adapter, { ...node, children });
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Walks the entries whose keys start with `prefix`, in key order, skipping
|
|
277
|
-
* every subtree that lies wholly outside that range.
|
|
278
|
-
*/
|
|
279
|
-
async function walkEntries(adapter, cid, prefix, visit) {
|
|
280
|
-
if (cid === null)
|
|
281
|
-
return;
|
|
282
|
-
const node = await loadNode(adapter, cid);
|
|
283
|
-
const { keys } = node;
|
|
284
|
-
// Child i holds the keys between keys[i - 1] and keys[i].
|
|
285
|
-
for (let i = 0; i <= keys.length; i++) {
|
|
286
|
-
const below = keys[i - 1];
|
|
287
|
-
const above = keys[i];
|
|
288
|
-
const afterRange = below !== undefined && below > prefix && !below.startsWith(prefix);
|
|
289
|
-
if (afterRange)
|
|
290
|
-
return;
|
|
291
|
-
const beforeRange = above !== undefined && above < prefix;
|
|
292
|
-
if (!beforeRange)
|
|
293
|
-
await walkEntries(adapter, node.children[i] ?? null, prefix, visit);
|
|
294
|
-
if (above !== undefined && above.startsWith(prefix))
|
|
295
|
-
visit(above, node.values[i]);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
/** Collects the CID of every node reachable from `cid`. */
|
|
299
|
-
async function collectCids(adapter, cid, out = new Set()) {
|
|
300
|
-
if (cid === null || out.has(cid))
|
|
301
|
-
return out;
|
|
302
|
-
out.add(cid);
|
|
303
|
-
const node = await loadNode(adapter, cid);
|
|
304
|
-
for (const child of node.children) {
|
|
305
|
-
await collectCids(adapter, child ?? null, out);
|
|
306
|
-
}
|
|
307
|
-
return out;
|
|
308
|
-
}
|
|
309
|
-
// ------------------------------------------------------------ public API
|
|
310
|
-
/**
|
|
311
|
-
* Every node CID reachable from a root: the tree as it stands, without the
|
|
312
|
-
* orphans older versions left behind in the store. Sync uses it to decide
|
|
313
|
-
* which of a peer's subtrees it already holds; garbage collection uses it to
|
|
314
|
-
* decide what to keep.
|
|
315
|
-
* @param adapter The storage adapter.
|
|
316
|
-
* @param rootCid The root, or null for an empty tree.
|
|
317
|
-
*/
|
|
318
|
-
export async function collectReachableCids(adapter, rootCid) {
|
|
319
|
-
return collectCids(adapter, rootCid);
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Insert a key-value pair into the MST.
|
|
323
|
-
* @param adapter The storage adapter.
|
|
324
|
-
* @param rootCid The current root, or null for an empty tree.
|
|
325
|
-
* @param key The key to insert.
|
|
326
|
-
* @param value The value to store against it.
|
|
327
|
-
* @returns The new root CID.
|
|
328
|
-
*/
|
|
329
|
-
export async function insertIntoMST(adapter, rootCid, key, value) {
|
|
330
|
-
const keyHeight = await nodeHeight(key);
|
|
331
|
-
if (rootCid === null)
|
|
332
|
-
return singleton(adapter, key, value, keyHeight, keyHeight);
|
|
333
|
-
const root = await loadNode(adapter, rootCid);
|
|
334
|
-
if (keyHeight > root.height) {
|
|
335
|
-
// The key outranks everything already stored, so it becomes the new root
|
|
336
|
-
// and the existing tree is split to sit beneath it.
|
|
337
|
-
const [left, right] = await splitSubtree(adapter, rootCid, key);
|
|
338
|
-
return saveNode(adapter, {
|
|
339
|
-
height: keyHeight,
|
|
340
|
-
keys: [key],
|
|
341
|
-
values: [value],
|
|
342
|
-
children: [
|
|
343
|
-
await lift(adapter, left, root.height, keyHeight - 1),
|
|
344
|
-
await lift(adapter, right, root.height, keyHeight - 1)
|
|
345
|
-
]
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
return insertInto(adapter, rootCid, root.height, key, value, keyHeight);
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Delete a key from the MST.
|
|
352
|
-
* @param adapter The storage adapter.
|
|
353
|
-
* @param rootCid The current root, or null for an empty tree.
|
|
354
|
-
* @param key The key to remove.
|
|
355
|
-
* @returns The new root CID, or null once the tree is empty.
|
|
356
|
-
*/
|
|
357
|
-
export async function deleteFromMST(adapter, rootCid, key) {
|
|
358
|
-
if (!rootCid)
|
|
359
|
-
return null;
|
|
360
|
-
const keyHeight = await nodeHeight(key);
|
|
361
|
-
let next = await deleteFrom(adapter, rootCid, key, keyHeight);
|
|
362
|
-
// Removing the tallest key can leave empty wrappers on top; drop them so the
|
|
363
|
-
// root is always the highest node that actually holds a key.
|
|
364
|
-
while (next !== null) {
|
|
365
|
-
const node = await loadNode(adapter, next);
|
|
366
|
-
if (node.keys.length > 0)
|
|
367
|
-
break;
|
|
368
|
-
next = node.children[0] ?? null;
|
|
369
|
-
}
|
|
370
|
-
return next;
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Lookup a value by key.
|
|
374
|
-
* @param adapter The storage adapter.
|
|
375
|
-
* @param rootCid The root to search from.
|
|
376
|
-
* @param key The key to find.
|
|
377
|
-
* @returns The value, or null when absent.
|
|
378
|
-
*/
|
|
379
|
-
export async function lookupInMST(adapter, rootCid, key) {
|
|
380
|
-
let cid = rootCid;
|
|
381
|
-
while (cid !== null) {
|
|
382
|
-
const node = await loadNode(adapter, cid);
|
|
383
|
-
const idx = lowerBound(node.keys, key);
|
|
384
|
-
if (node.keys[idx] === key)
|
|
385
|
-
return node.values[idx];
|
|
386
|
-
cid = node.children[idx] ?? null;
|
|
387
|
-
}
|
|
388
|
-
return null;
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Lists entries — keys with their values — in key order: all of them, or
|
|
392
|
-
* those under a prefix, reading only the nodes that can hold them.
|
|
393
|
-
* @param adapter The storage adapter.
|
|
394
|
-
* @param rootCid The root, or null for an empty tree.
|
|
395
|
-
* @param prefix Only keys starting with this
|
|
396
|
-
*/
|
|
397
|
-
export async function listMSTEntries(adapter, rootCid, prefix = '') {
|
|
398
|
-
const entries = [];
|
|
399
|
-
await walkEntries(adapter, rootCid, prefix, (key, value) => { entries.push({ key, value }); });
|
|
400
|
-
return entries;
|
|
401
|
-
}
|
|
402
|
-
//# sourceMappingURL=mst.js.map
|
package/dist/storage/mst.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mst.js","sourceRoot":"","sources":["../../src/storage/mst.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module anti-entropy
|
|
3
|
-
* The pieces of reconciliation that do not depend on messages.
|
|
4
|
-
*
|
|
5
|
-
* Two peers reconcile by walking each other's Merkle Search Tree from the root,
|
|
6
|
-
* descending only into subtrees they do not already have. Nodes are content
|
|
7
|
-
* addressed, so a subtree whose CID you hold is one you have and can be
|
|
8
|
-
* skipped whole. Two trees differing by one entry exchange only
|
|
9
|
-
* the nodes on the path to it — a handful at any size — instead of every key.
|
|
10
|
-
*/
|
|
11
|
-
import type { StorageAdapter } from '../types.js';
|
|
12
|
-
import { type MSTNode } from '../storage/mst.js';
|
|
13
|
-
/**
|
|
14
|
-
* Checks a node a peer sent: it must be well formed, and hash to the CID it
|
|
15
|
-
* was sent as.
|
|
16
|
-
*
|
|
17
|
-
* A peer can send anything. Only the four fields of a node are read, and they
|
|
18
|
-
* are hashed the one canonical way — so whatever else came with it, a node
|
|
19
|
-
* that checks out is exactly the node that CID names.
|
|
20
|
-
*
|
|
21
|
-
* @returns The node, or null when it is malformed or does not match the CID
|
|
22
|
-
*/
|
|
23
|
-
export declare function verifyNode(cid: string, value: unknown): Promise<MSTNode | null>;
|
|
24
|
-
/**
|
|
25
|
-
* The children of a peer's node worth fetching: those this store does not hold.
|
|
26
|
-
*
|
|
27
|
-
* A node is only ever stored by building this store's own tree, so holding
|
|
28
|
-
* one means holding — or having since superseded — every entry beneath it,
|
|
29
|
-
* whether or not the current root still reaches it. Asking the store is one
|
|
30
|
-
* lookup per child, where collecting the local tree first read all of it.
|
|
31
|
-
*
|
|
32
|
-
* @param adapter The local store
|
|
33
|
-
* @param node A node from the peer's tree
|
|
34
|
-
*/
|
|
35
|
-
export declare function unknownChildren(adapter: StorageAdapter, node: MSTNode): Promise<string[]>;
|
|
36
|
-
/**
|
|
37
|
-
* The version ids a peer's node names that differ from this store's.
|
|
38
|
-
*
|
|
39
|
-
* A key is a record key under a prefix (`r/`, `g/`, `h/`) and its value a
|
|
40
|
-
* version id, so two peers can hold the same key with different values — two
|
|
41
|
-
* versions of one record. Either way the other side's version is worth
|
|
42
|
-
* fetching: the ordering rule decides, on arrival, whether it is kept.
|
|
43
|
-
*
|
|
44
|
-
* @param adapter The local store
|
|
45
|
-
* @param localRoot The local tree's root
|
|
46
|
-
* @param node A node from the peer's tree
|
|
47
|
-
*/
|
|
48
|
-
export declare function differingEntries(adapter: StorageAdapter, localRoot: string | null, node: MSTNode): Promise<string[]>;
|
|
49
|
-
//# sourceMappingURL=anti-entropy.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"anti-entropy.d.ts","sourceRoot":"","sources":["../../src/sync/anti-entropy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAyB,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIxE;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAWrF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAI/F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ1H"}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { hashNode, lookupInMST } from '../storage/mst.js';
|
|
2
|
-
const isString = (value) => typeof value === 'string';
|
|
3
|
-
/**
|
|
4
|
-
* Checks a node a peer sent: it must be well formed, and hash to the CID it
|
|
5
|
-
* was sent as.
|
|
6
|
-
*
|
|
7
|
-
* A peer can send anything. Only the four fields of a node are read, and they
|
|
8
|
-
* are hashed the one canonical way — so whatever else came with it, a node
|
|
9
|
-
* that checks out is exactly the node that CID names.
|
|
10
|
-
*
|
|
11
|
-
* @returns The node, or null when it is malformed or does not match the CID
|
|
12
|
-
*/
|
|
13
|
-
export async function verifyNode(cid, value) {
|
|
14
|
-
const { height, keys, values, children } = (value ?? {});
|
|
15
|
-
if (!Number.isSafeInteger(height) ||
|
|
16
|
-
!Array.isArray(keys) || !keys.every(isString) ||
|
|
17
|
-
!Array.isArray(values) || values.length !== keys.length || !values.every(isString) ||
|
|
18
|
-
!Array.isArray(children) || children.length !== keys.length + 1 ||
|
|
19
|
-
!children.every((child) => child === null || isString(child)))
|
|
20
|
-
return null;
|
|
21
|
-
const node = { height: height, keys, values, children };
|
|
22
|
-
return (await hashNode(node)) === cid ? node : null;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* The children of a peer's node worth fetching: those this store does not hold.
|
|
26
|
-
*
|
|
27
|
-
* A node is only ever stored by building this store's own tree, so holding
|
|
28
|
-
* one means holding — or having since superseded — every entry beneath it,
|
|
29
|
-
* whether or not the current root still reaches it. Asking the store is one
|
|
30
|
-
* lookup per child, where collecting the local tree first read all of it.
|
|
31
|
-
*
|
|
32
|
-
* @param adapter The local store
|
|
33
|
-
* @param node A node from the peer's tree
|
|
34
|
-
*/
|
|
35
|
-
export async function unknownChildren(adapter, node) {
|
|
36
|
-
const children = node.children.filter((child) => child !== null);
|
|
37
|
-
const held = await Promise.all(children.map((child) => adapter.has(child)));
|
|
38
|
-
return children.filter((_, i) => !held[i]);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* The version ids a peer's node names that differ from this store's.
|
|
42
|
-
*
|
|
43
|
-
* A key is a record key under a prefix (`r/`, `g/`, `h/`) and its value a
|
|
44
|
-
* version id, so two peers can hold the same key with different values — two
|
|
45
|
-
* versions of one record. Either way the other side's version is worth
|
|
46
|
-
* fetching: the ordering rule decides, on arrival, whether it is kept.
|
|
47
|
-
*
|
|
48
|
-
* @param adapter The local store
|
|
49
|
-
* @param localRoot The local tree's root
|
|
50
|
-
* @param node A node from the peer's tree
|
|
51
|
-
*/
|
|
52
|
-
export async function differingEntries(adapter, localRoot, node) {
|
|
53
|
-
const ours = await Promise.all(node.keys.map((key) => lookupInMST(adapter, localRoot, key)));
|
|
54
|
-
const wanted = [];
|
|
55
|
-
for (let i = 0; i < node.keys.length; i++) {
|
|
56
|
-
const theirs = node.values[i];
|
|
57
|
-
if (typeof theirs === 'string' && ours[i] !== theirs && !(await adapter.getExpression(theirs)))
|
|
58
|
-
wanted.push(theirs);
|
|
59
|
-
}
|
|
60
|
-
return wanted;
|
|
61
|
-
}
|
|
62
|
-
//# sourceMappingURL=anti-entropy.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"anti-entropy.js","sourceRoot":"","sources":["../../src/sync/anti-entropy.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAgB,MAAM,mBAAmB,CAAC;AAExE,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;AAEhF;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,KAAc;IAC1D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAA4C,CAAC;IACpG,IACE,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC;QAC7B,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC7C,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;QAClF,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC;QAC/D,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,MAAM,IAAI,GAAY,EAAE,MAAM,EAAE,MAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC3E,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACtD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAuB,EAAE,IAAa;IAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;IAClF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAuB,EAAE,SAAwB,EAAE,IAAa;IACrG,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|