@hashtree/core 0.1.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/LICENSE +21 -0
- package/dist/bep52.d.ts +179 -0
- package/dist/bep52.d.ts.map +1 -0
- package/dist/bep52.js +384 -0
- package/dist/bep52.js.map +1 -0
- package/dist/builder.d.ts +137 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +281 -0
- package/dist/builder.js.map +1 -0
- package/dist/codec.d.ts +37 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +109 -0
- package/dist/codec.js.map +1 -0
- package/dist/crypto.d.ts +92 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +212 -0
- package/dist/crypto.js.map +1 -0
- package/dist/encrypted.d.ts +114 -0
- package/dist/encrypted.d.ts.map +1 -0
- package/dist/encrypted.js +446 -0
- package/dist/encrypted.js.map +1 -0
- package/dist/hash.d.ts +14 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +27 -0
- package/dist/hash.js.map +1 -0
- package/dist/hashtree.d.ts +237 -0
- package/dist/hashtree.d.ts.map +1 -0
- package/dist/hashtree.js +557 -0
- package/dist/hashtree.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/nhash.d.ts +94 -0
- package/dist/nhash.d.ts.map +1 -0
- package/dist/nhash.js +293 -0
- package/dist/nhash.js.map +1 -0
- package/dist/resolver/index.d.ts +5 -0
- package/dist/resolver/index.d.ts.map +1 -0
- package/dist/resolver/index.js +5 -0
- package/dist/resolver/index.js.map +1 -0
- package/dist/resolver/nostr.d.ts +82 -0
- package/dist/resolver/nostr.d.ts.map +1 -0
- package/dist/resolver/nostr.js +868 -0
- package/dist/resolver/nostr.js.map +1 -0
- package/dist/store/blossom.d.ts +100 -0
- package/dist/store/blossom.d.ts.map +1 -0
- package/dist/store/blossom.js +355 -0
- package/dist/store/blossom.js.map +1 -0
- package/dist/store/dexie.d.ts +44 -0
- package/dist/store/dexie.d.ts.map +1 -0
- package/dist/store/dexie.js +196 -0
- package/dist/store/dexie.js.map +1 -0
- package/dist/store/fallback.d.ts +40 -0
- package/dist/store/fallback.d.ts.map +1 -0
- package/dist/store/fallback.js +71 -0
- package/dist/store/fallback.js.map +1 -0
- package/dist/store/index.d.ts +6 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +6 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/memory.d.ts +29 -0
- package/dist/store/memory.d.ts.map +1 -0
- package/dist/store/memory.js +66 -0
- package/dist/store/memory.js.map +1 -0
- package/dist/store/opfs.d.ts +56 -0
- package/dist/store/opfs.d.ts.map +1 -0
- package/dist/store/opfs.js +200 -0
- package/dist/store/opfs.js.map +1 -0
- package/dist/streaming.d.ts +74 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +199 -0
- package/dist/streaming.js.map +1 -0
- package/dist/tree/create.d.ts +35 -0
- package/dist/tree/create.d.ts.map +1 -0
- package/dist/tree/create.js +90 -0
- package/dist/tree/create.js.map +1 -0
- package/dist/tree/edit.d.ts +28 -0
- package/dist/tree/edit.d.ts.map +1 -0
- package/dist/tree/edit.js +115 -0
- package/dist/tree/edit.js.map +1 -0
- package/dist/tree/editEncrypted.d.ts +46 -0
- package/dist/tree/editEncrypted.d.ts.map +1 -0
- package/dist/tree/editEncrypted.js +225 -0
- package/dist/tree/editEncrypted.js.map +1 -0
- package/dist/tree/index.d.ts +7 -0
- package/dist/tree/index.d.ts.map +1 -0
- package/dist/tree/index.js +7 -0
- package/dist/tree/index.js.map +1 -0
- package/dist/tree/read.d.ts +75 -0
- package/dist/tree/read.d.ts.map +1 -0
- package/dist/tree/read.js +389 -0
- package/dist/tree/read.js.map +1 -0
- package/dist/tree/writeAt.d.ts +44 -0
- package/dist/tree/writeAt.d.ts.map +1 -0
- package/dist/tree/writeAt.js +282 -0
- package/dist/tree/writeAt.js.map +1 -0
- package/dist/types.d.ts +274 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +47 -0
- package/dist/types.js.map +1 -0
- package/dist/verify.d.ts +12 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +32 -0
- package/dist/verify.js.map +1 -0
- package/dist/visibility.d.ts +50 -0
- package/dist/visibility.d.ts.map +1 -0
- package/dist/visibility.js +111 -0
- package/dist/visibility.js.map +1 -0
- package/dist/webrtc/index.d.ts +4 -0
- package/dist/webrtc/index.d.ts.map +1 -0
- package/dist/webrtc/index.js +4 -0
- package/dist/webrtc/index.js.map +1 -0
- package/dist/webrtc/lruCache.d.ts +20 -0
- package/dist/webrtc/lruCache.d.ts.map +1 -0
- package/dist/webrtc/lruCache.js +59 -0
- package/dist/webrtc/lruCache.js.map +1 -0
- package/dist/webrtc/peer.d.ts +122 -0
- package/dist/webrtc/peer.d.ts.map +1 -0
- package/dist/webrtc/peer.js +583 -0
- package/dist/webrtc/peer.js.map +1 -0
- package/dist/webrtc/protocol.d.ts +76 -0
- package/dist/webrtc/protocol.d.ts.map +1 -0
- package/dist/webrtc/protocol.js +167 -0
- package/dist/webrtc/protocol.js.map +1 -0
- package/dist/webrtc/store.d.ts +190 -0
- package/dist/webrtc/store.d.ts.map +1 -0
- package/dist/webrtc/store.js +1043 -0
- package/dist/webrtc/store.js.map +1 -0
- package/dist/webrtc/types.d.ts +196 -0
- package/dist/webrtc/types.d.ts.map +1 -0
- package/dist/webrtc/types.js +46 -0
- package/dist/webrtc/types.js.map +1 -0
- package/dist/worker/protocol.d.ts +493 -0
- package/dist/worker/protocol.d.ts.map +1 -0
- package/dist/worker/protocol.js +15 -0
- package/dist/worker/protocol.js.map +1 -0
- package/package.json +59 -0
package/dist/hashtree.js
ADDED
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HashTree - Unified merkle tree operations
|
|
3
|
+
*
|
|
4
|
+
* Single class for creating, reading, and editing content-addressed merkle trees.
|
|
5
|
+
*
|
|
6
|
+
* All files are encrypted by default using CHK (Content Hash Key) encryption.
|
|
7
|
+
* Use the "Public" variants (putFilePublic, readFilePublic) for unencrypted storage.
|
|
8
|
+
*/
|
|
9
|
+
import { LinkType, toHex, cid } from './types.js';
|
|
10
|
+
import { tryDecodeTreeNode } from './codec.js';
|
|
11
|
+
import { StreamWriter } from './streaming.js';
|
|
12
|
+
export { StreamWriter } from './streaming.js';
|
|
13
|
+
export { verifyTree } from './verify.js';
|
|
14
|
+
import * as create from './tree/create.js';
|
|
15
|
+
import * as read from './tree/read.js';
|
|
16
|
+
import * as edit from './tree/edit.js';
|
|
17
|
+
import { putFileEncrypted, readFileEncrypted, readFileEncryptedStream, readFileEncryptedRange, putDirectoryEncrypted, listDirectoryEncrypted, getTreeNodeEncrypted, } from './encrypted.js';
|
|
18
|
+
import * as editEncrypted from './tree/editEncrypted.js';
|
|
19
|
+
import * as writeAtOps from './tree/writeAt.js';
|
|
20
|
+
/** Default chunk size: 2MB (optimized for blossom uploads) */
|
|
21
|
+
export const DEFAULT_CHUNK_SIZE = 2 * 1024 * 1024;
|
|
22
|
+
/**
|
|
23
|
+
* HashTree - create, read, and edit merkle trees
|
|
24
|
+
*/
|
|
25
|
+
export class HashTree {
|
|
26
|
+
store;
|
|
27
|
+
chunkSize;
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.store = config.store;
|
|
30
|
+
this.chunkSize = config.chunkSize ?? DEFAULT_CHUNK_SIZE;
|
|
31
|
+
}
|
|
32
|
+
get config() {
|
|
33
|
+
return { store: this.store, chunkSize: this.chunkSize };
|
|
34
|
+
}
|
|
35
|
+
// Create (encrypted by default)
|
|
36
|
+
async putBlob(data) {
|
|
37
|
+
return create.putBlob(this.store, data);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Store a file
|
|
41
|
+
* @param data - File data to store
|
|
42
|
+
* @param options - { unencrypted?: boolean } - if true, store without encryption
|
|
43
|
+
* @returns { cid, size }
|
|
44
|
+
*/
|
|
45
|
+
async putFile(data, options) {
|
|
46
|
+
if (options?.unencrypted) {
|
|
47
|
+
const result = await create.putFile(this.config, data);
|
|
48
|
+
return { cid: { hash: result.hash }, size: result.size };
|
|
49
|
+
}
|
|
50
|
+
const result = await putFileEncrypted(this.config, data);
|
|
51
|
+
return { cid: cid(result.hash, result.key), size: result.size };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Store a directory
|
|
55
|
+
* @param entries - Directory entries
|
|
56
|
+
* @param options - { unencrypted?: boolean } - if true, store without encryption
|
|
57
|
+
* @returns { cid, size }
|
|
58
|
+
*/
|
|
59
|
+
async putDirectory(entries, options) {
|
|
60
|
+
const size = entries.reduce((sum, e) => sum + e.size, 0);
|
|
61
|
+
if (options?.unencrypted) {
|
|
62
|
+
const dirEntries = entries.map(e => ({
|
|
63
|
+
name: e.name,
|
|
64
|
+
cid: e.cid,
|
|
65
|
+
size: e.size,
|
|
66
|
+
type: e.type,
|
|
67
|
+
meta: e.meta,
|
|
68
|
+
}));
|
|
69
|
+
const hash = await create.putDirectory(this.config, dirEntries);
|
|
70
|
+
return { cid: { hash }, size };
|
|
71
|
+
}
|
|
72
|
+
// Encrypted by default
|
|
73
|
+
const encryptedEntries = entries.map(e => ({
|
|
74
|
+
name: e.name,
|
|
75
|
+
hash: e.cid.hash,
|
|
76
|
+
size: e.size,
|
|
77
|
+
key: e.cid.key,
|
|
78
|
+
type: e.type,
|
|
79
|
+
meta: e.meta,
|
|
80
|
+
}));
|
|
81
|
+
const result = await putDirectoryEncrypted(this.config, encryptedEntries);
|
|
82
|
+
return { cid: cid(result.hash, result.key), size };
|
|
83
|
+
}
|
|
84
|
+
// Read
|
|
85
|
+
async getBlob(hash) {
|
|
86
|
+
return read.getBlob(this.store, hash);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get a tree node
|
|
90
|
+
*/
|
|
91
|
+
async getTreeNode(id) {
|
|
92
|
+
if (id.key) {
|
|
93
|
+
return getTreeNodeEncrypted(this.store, id.hash, id.key);
|
|
94
|
+
}
|
|
95
|
+
return read.getTreeNode(this.store, id.hash);
|
|
96
|
+
}
|
|
97
|
+
async getType(id) {
|
|
98
|
+
if (!id?.hash)
|
|
99
|
+
return LinkType.Blob;
|
|
100
|
+
return read.getType(this.store, id.hash);
|
|
101
|
+
}
|
|
102
|
+
async isDirectory(id) {
|
|
103
|
+
if (!id?.hash)
|
|
104
|
+
return false;
|
|
105
|
+
// For encrypted directories, we need to decrypt to check the node type
|
|
106
|
+
if (id.key) {
|
|
107
|
+
try {
|
|
108
|
+
// Try to get the tree node (will decrypt and validate)
|
|
109
|
+
const node = await getTreeNodeEncrypted(this.store, id.hash, id.key);
|
|
110
|
+
if (!node)
|
|
111
|
+
return false;
|
|
112
|
+
// Empty directory is still a directory
|
|
113
|
+
if (node.links.length === 0)
|
|
114
|
+
return true;
|
|
115
|
+
// Check if it's a directory (has named entries) vs chunked file (no names)
|
|
116
|
+
return node.links.some(l => l.name !== undefined && !l.name.startsWith('_'));
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return read.isDirectory(this.store, id.hash);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Read a file
|
|
126
|
+
*/
|
|
127
|
+
async readFile(id) {
|
|
128
|
+
if (id.key) {
|
|
129
|
+
return readFileEncrypted(this.store, id.hash, id.key);
|
|
130
|
+
}
|
|
131
|
+
return read.readFile(this.store, id.hash);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Stream a file
|
|
135
|
+
* @param id - CID of the file
|
|
136
|
+
* @param options - { offset?: number, prefetch?: number }
|
|
137
|
+
*/
|
|
138
|
+
async *readFileStream(id, options = {}) {
|
|
139
|
+
if (id.key) {
|
|
140
|
+
yield* readFileEncryptedStream(this.store, id.hash, id.key, options);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
yield* read.readFileStream(this.store, id.hash, options);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Read a range of bytes from a file
|
|
148
|
+
*/
|
|
149
|
+
async readFileRange(id, start, end) {
|
|
150
|
+
if (id.key) {
|
|
151
|
+
return readFileEncryptedRange(this.store, id.hash, id.key, start, end);
|
|
152
|
+
}
|
|
153
|
+
return read.readFileRange(this.store, id.hash, start, end);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* List directory entries
|
|
157
|
+
*/
|
|
158
|
+
async listDirectory(id) {
|
|
159
|
+
if (id.key) {
|
|
160
|
+
const entries = await listDirectoryEncrypted(this.store, id.hash, id.key);
|
|
161
|
+
return entries.map(e => ({
|
|
162
|
+
name: e.name,
|
|
163
|
+
cid: cid(e.hash, e.key),
|
|
164
|
+
size: e.size,
|
|
165
|
+
type: e.type ?? LinkType.Blob,
|
|
166
|
+
meta: e.meta,
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
const entries = await read.listDirectory(this.store, id.hash);
|
|
170
|
+
return entries.map(e => ({
|
|
171
|
+
name: e.name,
|
|
172
|
+
cid: e.cid,
|
|
173
|
+
size: e.size,
|
|
174
|
+
type: e.type,
|
|
175
|
+
meta: e.meta,
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Resolve a path to get the entry's CID
|
|
180
|
+
*
|
|
181
|
+
* @param root - Root CID of the tree
|
|
182
|
+
* @param path - Path to resolve (string like 'a/b/file.txt' or array like ['a', 'b', 'file.txt'])
|
|
183
|
+
* @returns { cid, type } or null if not found
|
|
184
|
+
*/
|
|
185
|
+
async resolvePath(root, path) {
|
|
186
|
+
const parts = Array.isArray(path)
|
|
187
|
+
? path
|
|
188
|
+
: path.split('/').filter(p => p.length > 0);
|
|
189
|
+
let current = root;
|
|
190
|
+
let entryType = LinkType.Dir;
|
|
191
|
+
for (const segment of parts) {
|
|
192
|
+
const entries = await this.listDirectory(current);
|
|
193
|
+
const entry = entries.find(e => e.name === segment);
|
|
194
|
+
if (!entry) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
current = entry.cid;
|
|
198
|
+
entryType = entry.type;
|
|
199
|
+
}
|
|
200
|
+
return { cid: current, type: entryType };
|
|
201
|
+
}
|
|
202
|
+
async getSize(hash) {
|
|
203
|
+
return read.getSize(this.store, hash);
|
|
204
|
+
}
|
|
205
|
+
async *walk(hash, path = '') {
|
|
206
|
+
yield* read.walk(this.store, hash, path);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Walk entire tree and return all entries as an array
|
|
210
|
+
* More convenient than the async generator for most use cases
|
|
211
|
+
* @param id - Root CID of the tree
|
|
212
|
+
* @param options.includeData - If true, include file data in results
|
|
213
|
+
* @param options.filesOnly - If true, only return files (not directories)
|
|
214
|
+
*/
|
|
215
|
+
async walkTree(id, options) {
|
|
216
|
+
const results = [];
|
|
217
|
+
const walkRecursive = async (currentCid, currentPath) => {
|
|
218
|
+
const isDir = await this.isDirectory(currentCid);
|
|
219
|
+
if (isDir) {
|
|
220
|
+
if (!options?.filesOnly) {
|
|
221
|
+
const entries = await this.listDirectory(currentCid);
|
|
222
|
+
const dirSize = entries.reduce((sum, e) => sum + e.size, 0);
|
|
223
|
+
results.push({ path: currentPath, cid: currentCid, type: LinkType.Dir, size: dirSize });
|
|
224
|
+
}
|
|
225
|
+
const entries = await this.listDirectory(currentCid);
|
|
226
|
+
for (const entry of entries) {
|
|
227
|
+
const childPath = currentPath ? `${currentPath}/${entry.name}` : entry.name;
|
|
228
|
+
await walkRecursive(entry.cid, childPath);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
// File or blob
|
|
233
|
+
const type = await this.getType(currentCid);
|
|
234
|
+
const size = await this.getSize(currentCid.hash);
|
|
235
|
+
const result = {
|
|
236
|
+
path: currentPath,
|
|
237
|
+
cid: currentCid,
|
|
238
|
+
type,
|
|
239
|
+
size,
|
|
240
|
+
};
|
|
241
|
+
if (options?.includeData) {
|
|
242
|
+
const data = await this.readFile(currentCid);
|
|
243
|
+
if (data)
|
|
244
|
+
result.data = data;
|
|
245
|
+
}
|
|
246
|
+
results.push(result);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
await walkRecursive(id, '');
|
|
250
|
+
return results;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Iterate over all raw blocks in a merkle tree
|
|
254
|
+
* Yields each block's hash and data, traversing encrypted nodes correctly
|
|
255
|
+
* Useful for syncing to remote stores (e.g., Blossom push)
|
|
256
|
+
*/
|
|
257
|
+
async *walkBlocks(id) {
|
|
258
|
+
const visited = new Set();
|
|
259
|
+
const traverse = async function* (store, hash, key) {
|
|
260
|
+
const hex = toHex(hash);
|
|
261
|
+
if (visited.has(hex))
|
|
262
|
+
return;
|
|
263
|
+
visited.add(hex);
|
|
264
|
+
const data = await store.get(hash);
|
|
265
|
+
if (!data)
|
|
266
|
+
return;
|
|
267
|
+
yield { hash, data };
|
|
268
|
+
// Handle encrypted vs unencrypted tree nodes
|
|
269
|
+
if (key) {
|
|
270
|
+
const decrypted = await getTreeNodeEncrypted(store, hash, key);
|
|
271
|
+
if (decrypted) {
|
|
272
|
+
for (const link of decrypted.links) {
|
|
273
|
+
yield* traverse(store, link.hash, link.key);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
const node = tryDecodeTreeNode(data);
|
|
279
|
+
if (node) {
|
|
280
|
+
for (const link of node.links) {
|
|
281
|
+
yield* traverse(store, link.hash, link.key);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
yield* traverse(this.store, id.hash, id.key);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Pull (fetch) all chunks for a tree recursively
|
|
290
|
+
* Triggers WebRTC fetches for any missing chunks
|
|
291
|
+
* Uses parallel fetching within each tree level for better performance
|
|
292
|
+
* @returns { cid, chunks, bytes } - The CID and stats about what was pulled
|
|
293
|
+
*/
|
|
294
|
+
async pull(id) {
|
|
295
|
+
const visited = new Set();
|
|
296
|
+
let chunks = 0;
|
|
297
|
+
let bytes = 0;
|
|
298
|
+
const fetch = async (hash, key) => {
|
|
299
|
+
const hex = toHex(hash);
|
|
300
|
+
if (visited.has(hex))
|
|
301
|
+
return;
|
|
302
|
+
visited.add(hex);
|
|
303
|
+
// Fetch the chunk (will go to WebRTC peers if not local)
|
|
304
|
+
const data = await this.store.get(hash);
|
|
305
|
+
if (!data) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
chunks++;
|
|
309
|
+
bytes += data.length;
|
|
310
|
+
// If there's an encryption key, try to decrypt and check if it's a tree node
|
|
311
|
+
// For encrypted data, we can't use isTreeNode on the raw bytes
|
|
312
|
+
if (key) {
|
|
313
|
+
const decrypted = await getTreeNodeEncrypted(this.store, hash, key);
|
|
314
|
+
if (decrypted) {
|
|
315
|
+
// It's an encrypted tree node - fetch all children in parallel
|
|
316
|
+
await Promise.all(decrypted.links.map(link => fetch(link.hash, link.key)));
|
|
317
|
+
}
|
|
318
|
+
// If decryption failed or not a tree node, it's a blob (already fetched)
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
// Unencrypted data - check directly
|
|
322
|
+
const node = tryDecodeTreeNode(data);
|
|
323
|
+
if (node) {
|
|
324
|
+
// Fetch all children in parallel
|
|
325
|
+
await Promise.all(node.links.map(link => fetch(link.hash, link.key)));
|
|
326
|
+
}
|
|
327
|
+
// If not a tree node, it's a blob (already fetched)
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
await fetch(id.hash, id.key);
|
|
331
|
+
return { cid: id, chunks, bytes };
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Push all chunks for a tree to a target store
|
|
335
|
+
* Useful for syncing to remote stores (e.g., Blossom servers)
|
|
336
|
+
* @param id - CID of the tree to push
|
|
337
|
+
* @param targetStore - Store to push blocks to (must support put())
|
|
338
|
+
* @param options - callbacks for progress and per-block status
|
|
339
|
+
* @returns { cid, pushed, skipped, failed, bytes, errors } - The CID and detailed stats
|
|
340
|
+
*/
|
|
341
|
+
async push(id, targetStore, options) {
|
|
342
|
+
// First pull to ensure all blocks are available locally
|
|
343
|
+
await this.pull(id);
|
|
344
|
+
// Check if already aborted
|
|
345
|
+
if (options?.signal?.aborted) {
|
|
346
|
+
return { cid: id, pushed: 0, skipped: 0, failed: 0, bytes: 0, errors: [], cancelled: true };
|
|
347
|
+
}
|
|
348
|
+
let pushed = 0;
|
|
349
|
+
let skipped = 0;
|
|
350
|
+
let failed = 0;
|
|
351
|
+
let bytes = 0;
|
|
352
|
+
let completed = 0;
|
|
353
|
+
let discovered = 0;
|
|
354
|
+
let walkDone = false;
|
|
355
|
+
const errors = [];
|
|
356
|
+
const concurrency = options?.concurrency ?? 4;
|
|
357
|
+
// Bounded queue for producer-consumer pattern
|
|
358
|
+
const queue = [];
|
|
359
|
+
const maxQueueSize = concurrency * 2;
|
|
360
|
+
let queueResolve = null;
|
|
361
|
+
let consumerResolve = null;
|
|
362
|
+
// Process a single block
|
|
363
|
+
const processBlock = async (block) => {
|
|
364
|
+
if (options?.signal?.aborted)
|
|
365
|
+
return;
|
|
366
|
+
const { hash, data } = block;
|
|
367
|
+
try {
|
|
368
|
+
const isNew = await targetStore.put(hash, data);
|
|
369
|
+
if (isNew === false) {
|
|
370
|
+
skipped++;
|
|
371
|
+
options?.onBlock?.(hash, 'skipped');
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
pushed++;
|
|
375
|
+
bytes += data.length;
|
|
376
|
+
options?.onBlock?.(hash, 'success');
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
catch (e) {
|
|
380
|
+
failed++;
|
|
381
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
382
|
+
errors.push({ hash, error });
|
|
383
|
+
options?.onBlock?.(hash, 'error', error);
|
|
384
|
+
}
|
|
385
|
+
completed++;
|
|
386
|
+
// Report progress: completed / discovered (discovered grows as we walk)
|
|
387
|
+
options?.onProgress?.(completed, discovered);
|
|
388
|
+
};
|
|
389
|
+
// Consumer: pull from queue and process
|
|
390
|
+
const runConsumer = async () => {
|
|
391
|
+
const active = [];
|
|
392
|
+
while (!walkDone || queue.length > 0 || active.length > 0) {
|
|
393
|
+
if (options?.signal?.aborted)
|
|
394
|
+
break;
|
|
395
|
+
// Start new tasks from queue
|
|
396
|
+
while (active.length < concurrency && queue.length > 0) {
|
|
397
|
+
const block = queue.shift();
|
|
398
|
+
// Signal producer that queue has space
|
|
399
|
+
if (queueResolve && queue.length < maxQueueSize) {
|
|
400
|
+
queueResolve();
|
|
401
|
+
queueResolve = null;
|
|
402
|
+
}
|
|
403
|
+
const promise = processBlock(block).then(() => {
|
|
404
|
+
active.splice(active.indexOf(promise), 1);
|
|
405
|
+
});
|
|
406
|
+
active.push(promise);
|
|
407
|
+
}
|
|
408
|
+
// If queue empty but walk not done, wait for producer
|
|
409
|
+
if (queue.length === 0 && !walkDone && active.length < concurrency) {
|
|
410
|
+
await new Promise(resolve => {
|
|
411
|
+
consumerResolve = resolve;
|
|
412
|
+
});
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
// Wait for at least one task to complete
|
|
416
|
+
if (active.length > 0) {
|
|
417
|
+
await Promise.race(active);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
await Promise.all(active);
|
|
421
|
+
};
|
|
422
|
+
// Producer: walk tree and push to queue
|
|
423
|
+
const runProducer = async () => {
|
|
424
|
+
for await (const block of this.walkBlocks(id)) {
|
|
425
|
+
if (options?.signal?.aborted)
|
|
426
|
+
break;
|
|
427
|
+
discovered++;
|
|
428
|
+
// Wait if queue is full
|
|
429
|
+
while (queue.length >= maxQueueSize) {
|
|
430
|
+
await new Promise(resolve => {
|
|
431
|
+
queueResolve = resolve;
|
|
432
|
+
});
|
|
433
|
+
if (options?.signal?.aborted)
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
queue.push(block);
|
|
437
|
+
// Wake up consumer
|
|
438
|
+
if (consumerResolve) {
|
|
439
|
+
consumerResolve();
|
|
440
|
+
consumerResolve = null;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
walkDone = true;
|
|
444
|
+
// Wake consumer one last time
|
|
445
|
+
if (consumerResolve) {
|
|
446
|
+
consumerResolve();
|
|
447
|
+
consumerResolve = null;
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
// Run producer and consumer in parallel
|
|
451
|
+
await Promise.all([runProducer(), runConsumer()]);
|
|
452
|
+
return { cid: id, pushed, skipped, failed, bytes, errors, cancelled: options?.signal?.aborted ?? false };
|
|
453
|
+
}
|
|
454
|
+
// Edit operations
|
|
455
|
+
/**
|
|
456
|
+
* Add or update an entry in a directory
|
|
457
|
+
* @param root - Root CID of the tree
|
|
458
|
+
* @param path - Path to the directory containing the entry
|
|
459
|
+
* @param name - Name of the entry
|
|
460
|
+
* @param entry - CID of the entry content
|
|
461
|
+
* @param size - Size of the content
|
|
462
|
+
* @param type - Type of the entry (LinkType.Blob, LinkType.File, or LinkType.Dir)
|
|
463
|
+
* @returns New root CID
|
|
464
|
+
*/
|
|
465
|
+
async setEntry(root, path, name, entry, size, type = LinkType.Blob, meta) {
|
|
466
|
+
if (root.key) {
|
|
467
|
+
const result = await editEncrypted.setEntryEncrypted(this.config, root.hash, root.key, path, name, entry.hash, size, entry.key, type, meta);
|
|
468
|
+
return cid(result.hash, result.key);
|
|
469
|
+
}
|
|
470
|
+
const hash = await edit.setEntry(this.config, root.hash, path, name, entry, size, type, meta);
|
|
471
|
+
return { hash };
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Remove an entry from a directory
|
|
475
|
+
* @param root - Root CID of the tree
|
|
476
|
+
* @param path - Path to the directory containing the entry
|
|
477
|
+
* @param name - Name of the entry to remove
|
|
478
|
+
* @returns New root CID
|
|
479
|
+
*/
|
|
480
|
+
async removeEntry(root, path, name) {
|
|
481
|
+
if (root.key) {
|
|
482
|
+
const result = await editEncrypted.removeEntryEncrypted(this.config, root.hash, root.key, path, name);
|
|
483
|
+
return cid(result.hash, result.key);
|
|
484
|
+
}
|
|
485
|
+
const hash = await edit.removeEntry(this.config, root.hash, path, name);
|
|
486
|
+
return { hash };
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Rename an entry in a directory
|
|
490
|
+
* @param root - Root CID of the tree
|
|
491
|
+
* @param path - Path to the directory containing the entry
|
|
492
|
+
* @param oldName - Current name
|
|
493
|
+
* @param newName - New name
|
|
494
|
+
* @returns New root CID
|
|
495
|
+
*/
|
|
496
|
+
async renameEntry(root, path, oldName, newName) {
|
|
497
|
+
if (root.key) {
|
|
498
|
+
const result = await editEncrypted.renameEntryEncrypted(this.config, root.hash, root.key, path, oldName, newName);
|
|
499
|
+
return cid(result.hash, result.key);
|
|
500
|
+
}
|
|
501
|
+
const hash = await edit.renameEntry(this.config, root.hash, path, oldName, newName);
|
|
502
|
+
return { hash };
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Move an entry to a different directory
|
|
506
|
+
* @param root - Root CID of the tree
|
|
507
|
+
* @param sourcePath - Path to the source directory
|
|
508
|
+
* @param name - Name of the entry to move
|
|
509
|
+
* @param targetPath - Path to the target directory
|
|
510
|
+
* @returns New root CID
|
|
511
|
+
*/
|
|
512
|
+
async moveEntry(root, sourcePath, name, targetPath) {
|
|
513
|
+
if (root.key) {
|
|
514
|
+
const result = await editEncrypted.moveEntryEncrypted(this.config, root.hash, root.key, sourcePath, name, targetPath);
|
|
515
|
+
return cid(result.hash, result.key);
|
|
516
|
+
}
|
|
517
|
+
const hash = await edit.moveEntry(this.config, root.hash, sourcePath, name, targetPath);
|
|
518
|
+
return { hash };
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Write data at a specific offset in a file
|
|
522
|
+
* Only affected chunks are rewritten - efficient for small patches to large files.
|
|
523
|
+
* Useful for updating file headers (e.g., WebM duration) without rewriting entire file.
|
|
524
|
+
*
|
|
525
|
+
* @param fileCid - CID of the file to modify
|
|
526
|
+
* @param offset - Byte offset to write at
|
|
527
|
+
* @param data - Data to write
|
|
528
|
+
* @returns New file CID
|
|
529
|
+
*/
|
|
530
|
+
async writeAt(fileCid, offset, data) {
|
|
531
|
+
if (fileCid.key) {
|
|
532
|
+
const result = await writeAtOps.writeAtEncrypted(this.config, fileCid.hash, fileCid.key, offset, data);
|
|
533
|
+
return cid(result.hash, result.key);
|
|
534
|
+
}
|
|
535
|
+
const result = await writeAtOps.writeAt(this.config, fileCid.hash, offset, data);
|
|
536
|
+
return { hash: result.hash };
|
|
537
|
+
}
|
|
538
|
+
// Utility
|
|
539
|
+
getStore() {
|
|
540
|
+
return this.store;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Create a streaming file writer for incremental appends
|
|
544
|
+
* Useful for writing large files chunk by chunk (e.g., video recording)
|
|
545
|
+
* @param options.unencrypted - if true, create without encryption
|
|
546
|
+
* @param options.chunker - custom chunker for variable chunk sizes (e.g., videoChunker for faster start)
|
|
547
|
+
*/
|
|
548
|
+
createStream(options) {
|
|
549
|
+
return new StreamWriter({
|
|
550
|
+
store: this.store,
|
|
551
|
+
chunkSize: this.chunkSize,
|
|
552
|
+
chunker: options?.chunker,
|
|
553
|
+
unencrypted: options?.unencrypted ?? false,
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
//# sourceMappingURL=hashtree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hashtree.js","sourceRoot":"","sources":["../src/hashtree.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HashTree - Simple content-addressed merkle tree storage
|
|
3
|
+
*
|
|
4
|
+
* Browser-first, ESM-only library for building merkle trees
|
|
5
|
+
* with content-hash addressing: SHA256(content) -> content
|
|
6
|
+
*/
|
|
7
|
+
export type { Hash, CID, TreeNode, Blob, Link, Store, StoreWithMeta, RefResolver, RefResolverListEntry, SubscribeVisibilityInfo, PublishOptions, PublishResult, RefResolver as RootResolver, } from './types.js';
|
|
8
|
+
export { LinkType, toHex, fromHex, cid, } from './types.js';
|
|
9
|
+
export { sha256 } from './hash.js';
|
|
10
|
+
export { encryptChk, decryptChk, contentHash, encryptedSizeChk, encrypt, decrypt, generateKey, keyToHex, keyFromHex, encryptedSize, plaintextSize, type EncryptionKey, } from './crypto.js';
|
|
11
|
+
export { encodeTreeNode, decodeTreeNode, tryDecodeTreeNode, encodeAndHash, getNodeType, } from './codec.js';
|
|
12
|
+
export { MemoryStore } from './store/memory.js';
|
|
13
|
+
export { OpfsStore, type OpfsStoreOptions } from './store/opfs.js';
|
|
14
|
+
export { BlossomStore, type BlossomStoreConfig, type BlossomServer, type BlossomSigner, type BlossomAuthEvent, type BlossomLogEntry, type BlossomLogger, type BlossomUploadCallback, } from './store/blossom.js';
|
|
15
|
+
export { DexieStore } from './store/dexie.js';
|
|
16
|
+
export { HashTree, StreamWriter, verifyTree, DEFAULT_CHUNK_SIZE, type HashTreeConfig, type TreeEntry, type DirEntry, } from './hashtree.js';
|
|
17
|
+
export type { StreamOptions } from './tree/read.js';
|
|
18
|
+
export { type Chunker, fixedChunker, videoChunker, } from './builder.js';
|
|
19
|
+
export { WebRTCStore, DEFAULT_RELAYS, Peer, PeerId, generateUuid, type SignalingMessage, type WebRTCStoreConfig, type PeerStatus, type WebRTCStoreEvent, type WebRTCStoreEventHandler, type EventSigner, type EventEncrypter, type EventDecrypter, type GiftWrapper, type GiftUnwrapper, type SignedEvent, type PeerPool, type PeerClassifier, type PoolConfig, type WebRTCStats, } from './webrtc/index.js';
|
|
20
|
+
export { BEP52_BLOCK_SIZE, ZERO_HASH, Bep52TreeBuilder, Bep52StreamBuilder, type Bep52Result, type Bep52Config, } from './bep52.js';
|
|
21
|
+
export * as bep52 from './bep52.js';
|
|
22
|
+
export { createNostrRefResolver, createNostrRefResolver as createNostrRootResolver, type NostrRefResolverConfig, type NostrRefResolverConfig as NostrRootResolverConfig, type NostrEvent, type NostrFilter, type Nip19Like, type VisibilityCallbacks, } from './resolver/index.js';
|
|
23
|
+
export { nhashEncode, nhashDecode, npathEncode, npathDecode, decode, isNHash, isNPath, NHashTypeGuard, BECH32_REGEX, type NHashData, type NPathData, type DecodeResult, } from './nhash.js';
|
|
24
|
+
export { generateLinkKey, computeKeyId, encryptKeyForLink, decryptKeyFromLink, hex as visibilityHex, type TreeVisibility, } from './visibility.js';
|
|
25
|
+
export type { WorkerRequest, WorkerResponse, WorkerConfig, NostrFilter as WorkerNostrFilter, UnsignedEvent as WorkerUnsignedEvent, SignedEvent as WorkerSignedEvent, PeerStats as WorkerPeerStats, RelayStats as WorkerRelayStats, DirEntry as WorkerDirEntry, SocialGraphEvent as WorkerSocialGraphEvent, BlossomUploadProgress as WorkerBlossomUploadProgress, BlossomServerStatus as WorkerBlossomServerStatus, BlossomServerConfig as WorkerBlossomServerConfig, MediaRequest, MediaResponse, WebRTCCommand, WebRTCEvent, } from './worker/protocol.js';
|
|
26
|
+
export { generateRequestId } from './worker/protocol.js';
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HashTree - Simple content-addressed merkle tree storage
|
|
3
|
+
*
|
|
4
|
+
* Browser-first, ESM-only library for building merkle trees
|
|
5
|
+
* with content-hash addressing: SHA256(content) -> content
|
|
6
|
+
*/
|
|
7
|
+
export { LinkType, toHex, fromHex, cid, } from './types.js';
|
|
8
|
+
// Hash utilities
|
|
9
|
+
export { sha256 } from './hash.js';
|
|
10
|
+
// Encryption utilities
|
|
11
|
+
export {
|
|
12
|
+
// CHK (Content Hash Key) encryption - deterministic, enables deduplication
|
|
13
|
+
encryptChk, decryptChk, contentHash, encryptedSizeChk,
|
|
14
|
+
// Legacy encryption with random IV (deprecated, use CHK)
|
|
15
|
+
encrypt, decrypt, generateKey, keyToHex, keyFromHex, encryptedSize, plaintextSize, } from './crypto.js';
|
|
16
|
+
// MessagePack codec
|
|
17
|
+
export { encodeTreeNode, decodeTreeNode, tryDecodeTreeNode, encodeAndHash, getNodeType, } from './codec.js';
|
|
18
|
+
// Storage adapters
|
|
19
|
+
export { MemoryStore } from './store/memory.js';
|
|
20
|
+
export { OpfsStore } from './store/opfs.js';
|
|
21
|
+
export { BlossomStore, } from './store/blossom.js';
|
|
22
|
+
export { DexieStore } from './store/dexie.js';
|
|
23
|
+
// HashTree - unified tree operations (create, read, edit, stream)
|
|
24
|
+
export { HashTree, StreamWriter, verifyTree, DEFAULT_CHUNK_SIZE, } from './hashtree.js';
|
|
25
|
+
// Chunker utilities
|
|
26
|
+
export { fixedChunker, videoChunker, } from './builder.js';
|
|
27
|
+
// WebRTC P2P store
|
|
28
|
+
export { WebRTCStore, DEFAULT_RELAYS, Peer, PeerId, generateUuid, } from './webrtc/index.js';
|
|
29
|
+
// BEP52 (BitTorrent v2) compatible merkle tree
|
|
30
|
+
// Main API: Bep52TreeBuilder, Bep52StreamBuilder
|
|
31
|
+
// Low-level functions available via: import { bep52 } from '@hashtree/core'
|
|
32
|
+
export { BEP52_BLOCK_SIZE, ZERO_HASH, Bep52TreeBuilder, Bep52StreamBuilder, } from './bep52.js';
|
|
33
|
+
// Re-export low-level BEP52 merkle functions as namespace
|
|
34
|
+
export * as bep52 from './bep52.js';
|
|
35
|
+
// Ref resolvers
|
|
36
|
+
export { createNostrRefResolver,
|
|
37
|
+
// Legacy alias
|
|
38
|
+
createNostrRefResolver as createNostrRootResolver, } from './resolver/index.js';
|
|
39
|
+
// Bech32 identifiers (nhash, npath)
|
|
40
|
+
export { nhashEncode, nhashDecode, npathEncode, npathDecode, decode, isNHash, isNPath, NHashTypeGuard, BECH32_REGEX, } from './nhash.js';
|
|
41
|
+
// Tree visibility utilities (public/link-visible/private)
|
|
42
|
+
export { generateLinkKey, computeKeyId, encryptKeyForLink, decryptKeyFromLink, hex as visibilityHex, } from './visibility.js';
|
|
43
|
+
export { generateRequestId } from './worker/protocol.js';
|
|
44
|
+
//# sourceMappingURL=index.js.map
|