@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
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* writeAt - Efficiently patch bytes at a specific offset without rewriting entire file
|
|
3
|
+
*
|
|
4
|
+
* Only affected chunks and their parent nodes are rewritten.
|
|
5
|
+
* For a large file with a small patch, this is much more efficient than putFile.
|
|
6
|
+
*/
|
|
7
|
+
import { LinkType, toHex } from '../types.js';
|
|
8
|
+
import { sha256 } from '../hash.js';
|
|
9
|
+
import { encodeAndHash, decodeTreeNode, tryDecodeTreeNode } from '../codec.js';
|
|
10
|
+
import { encryptChk, decryptChk } from '../crypto.js';
|
|
11
|
+
/**
|
|
12
|
+
* Write data at a specific offset in an unencrypted file
|
|
13
|
+
*
|
|
14
|
+
* @param config - Tree configuration
|
|
15
|
+
* @param rootHash - Current root hash of the file
|
|
16
|
+
* @param offset - Byte offset to write at
|
|
17
|
+
* @param data - Data to write
|
|
18
|
+
* @returns New root hash
|
|
19
|
+
*/
|
|
20
|
+
export async function writeAt(config, rootHash, offset, data) {
|
|
21
|
+
const { store } = config;
|
|
22
|
+
// Get root data
|
|
23
|
+
const rootData = await store.get(rootHash);
|
|
24
|
+
if (!rootData) {
|
|
25
|
+
throw new Error(`Root not found: ${toHex(rootHash)}`);
|
|
26
|
+
}
|
|
27
|
+
// Check if it's a tree node or single blob
|
|
28
|
+
const node = tryDecodeTreeNode(rootData);
|
|
29
|
+
if (!node) {
|
|
30
|
+
// Single blob - modify in place
|
|
31
|
+
if (offset + data.length > rootData.length) {
|
|
32
|
+
throw new Error(`Write extends beyond file: offset=${offset}, data=${data.length}, file=${rootData.length}`);
|
|
33
|
+
}
|
|
34
|
+
const newData = new Uint8Array(rootData);
|
|
35
|
+
newData.set(data, offset);
|
|
36
|
+
const newHash = await sha256(newData);
|
|
37
|
+
await store.put(newHash, newData);
|
|
38
|
+
return { hash: newHash, size: newData.length };
|
|
39
|
+
}
|
|
40
|
+
// Multi-chunk file - find and modify affected chunks
|
|
41
|
+
const totalSize = node.links.reduce((sum, l) => sum + l.size, 0);
|
|
42
|
+
if (offset + data.length > totalSize) {
|
|
43
|
+
throw new Error(`Write extends beyond file: offset=${offset}, data=${data.length}, file=${totalSize}`);
|
|
44
|
+
}
|
|
45
|
+
const newLinks = await writeAtInNode(config, node, offset, data);
|
|
46
|
+
// Rebuild tree with new links
|
|
47
|
+
const newRootHash = await buildTreeFromLinks(config, newLinks, totalSize);
|
|
48
|
+
return { hash: newRootHash, size: totalSize };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Write data at a specific offset in an encrypted file
|
|
52
|
+
*
|
|
53
|
+
* @param config - Tree configuration
|
|
54
|
+
* @param rootHash - Current root hash of the encrypted file
|
|
55
|
+
* @param rootKey - Current encryption key for the root
|
|
56
|
+
* @param offset - Byte offset to write at
|
|
57
|
+
* @param data - Data to write (plaintext)
|
|
58
|
+
* @returns New root hash and key
|
|
59
|
+
*/
|
|
60
|
+
export async function writeAtEncrypted(config, rootHash, rootKey, offset, data) {
|
|
61
|
+
const { store } = config;
|
|
62
|
+
// Get and decrypt root
|
|
63
|
+
const encryptedRoot = await store.get(rootHash);
|
|
64
|
+
if (!encryptedRoot) {
|
|
65
|
+
throw new Error(`Root not found: ${toHex(rootHash)}`);
|
|
66
|
+
}
|
|
67
|
+
const decryptedRoot = await decryptChk(encryptedRoot, rootKey);
|
|
68
|
+
// Check if it's a tree node or single blob
|
|
69
|
+
const node = tryDecodeTreeNode(decryptedRoot);
|
|
70
|
+
if (!node) {
|
|
71
|
+
// Single blob - modify in place
|
|
72
|
+
if (offset + data.length > decryptedRoot.length) {
|
|
73
|
+
throw new Error(`Write extends beyond file: offset=${offset}, data=${data.length}, file=${decryptedRoot.length}`);
|
|
74
|
+
}
|
|
75
|
+
const newData = new Uint8Array(decryptedRoot);
|
|
76
|
+
newData.set(data, offset);
|
|
77
|
+
// Re-encrypt with CHK
|
|
78
|
+
const { ciphertext, key } = await encryptChk(newData);
|
|
79
|
+
const newHash = await sha256(ciphertext);
|
|
80
|
+
await store.put(newHash, ciphertext);
|
|
81
|
+
return { hash: newHash, size: newData.length, key };
|
|
82
|
+
}
|
|
83
|
+
// Multi-chunk file - find and modify affected chunks
|
|
84
|
+
const totalSize = node.links.reduce((sum, l) => sum + l.size, 0);
|
|
85
|
+
if (offset + data.length > totalSize) {
|
|
86
|
+
throw new Error(`Write extends beyond file: offset=${offset}, data=${data.length}, file=${totalSize}`);
|
|
87
|
+
}
|
|
88
|
+
const newLinks = await writeAtInNodeEncrypted(config, node, offset, data);
|
|
89
|
+
// Rebuild encrypted tree with new links
|
|
90
|
+
const { hash: newRootHash, key: newRootKey } = await buildEncryptedTreeFromLinks(config, newLinks, totalSize);
|
|
91
|
+
return { hash: newRootHash, size: totalSize, key: newRootKey };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Recursively modify chunks in a tree node (unencrypted)
|
|
95
|
+
*/
|
|
96
|
+
async function writeAtInNode(config, node, offset, data) {
|
|
97
|
+
const { store } = config;
|
|
98
|
+
const newLinks = [];
|
|
99
|
+
let position = 0;
|
|
100
|
+
for (const link of node.links) {
|
|
101
|
+
const linkStart = position;
|
|
102
|
+
const linkEnd = position + link.size;
|
|
103
|
+
position = linkEnd;
|
|
104
|
+
// Check if this chunk overlaps with the write range
|
|
105
|
+
const writeStart = offset;
|
|
106
|
+
const writeEnd = offset + data.length;
|
|
107
|
+
if (linkEnd <= writeStart || linkStart >= writeEnd) {
|
|
108
|
+
// No overlap - keep original link
|
|
109
|
+
newLinks.push(link);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
// This chunk needs modification
|
|
113
|
+
const chunkData = await store.get(link.hash);
|
|
114
|
+
if (!chunkData) {
|
|
115
|
+
throw new Error(`Missing chunk: ${toHex(link.hash)}`);
|
|
116
|
+
}
|
|
117
|
+
if (link.type !== LinkType.Blob) {
|
|
118
|
+
// Intermediate node - recurse
|
|
119
|
+
const childNode = decodeTreeNode(chunkData);
|
|
120
|
+
const childOffset = Math.max(0, offset - linkStart);
|
|
121
|
+
const childData = data.slice(Math.max(0, linkStart - offset), Math.min(data.length, linkEnd - offset));
|
|
122
|
+
const newChildLinks = await writeAtInNode(config, childNode, childOffset, childData);
|
|
123
|
+
// Build new intermediate node
|
|
124
|
+
const newChildNode = {
|
|
125
|
+
type: LinkType.File,
|
|
126
|
+
links: newChildLinks,
|
|
127
|
+
};
|
|
128
|
+
const { data: encodedNode, hash: newChildHash } = await encodeAndHash(newChildNode);
|
|
129
|
+
await store.put(newChildHash, encodedNode);
|
|
130
|
+
newLinks.push({
|
|
131
|
+
hash: newChildHash,
|
|
132
|
+
size: link.size,
|
|
133
|
+
type: LinkType.File,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// Leaf blob - modify bytes
|
|
138
|
+
const newChunkData = new Uint8Array(chunkData);
|
|
139
|
+
// Calculate which bytes to modify in this chunk
|
|
140
|
+
const chunkWriteStart = Math.max(0, writeStart - linkStart);
|
|
141
|
+
const chunkWriteEnd = Math.min(chunkData.length, writeEnd - linkStart);
|
|
142
|
+
const dataReadStart = Math.max(0, linkStart - writeStart);
|
|
143
|
+
const dataReadEnd = dataReadStart + (chunkWriteEnd - chunkWriteStart);
|
|
144
|
+
newChunkData.set(data.slice(dataReadStart, dataReadEnd), chunkWriteStart);
|
|
145
|
+
const newHash = await sha256(newChunkData);
|
|
146
|
+
await store.put(newHash, newChunkData);
|
|
147
|
+
newLinks.push({
|
|
148
|
+
hash: newHash,
|
|
149
|
+
size: newChunkData.length,
|
|
150
|
+
type: LinkType.Blob,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return newLinks;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Recursively modify chunks in an encrypted tree node
|
|
158
|
+
*
|
|
159
|
+
* NOTE: For encrypted files, link.size stores CIPHERTEXT size (includes AES-GCM tag),
|
|
160
|
+
* but offset/data are in PLAINTEXT terms. We need to decrypt each chunk to get
|
|
161
|
+
* the actual plaintext size for offset calculations.
|
|
162
|
+
*/
|
|
163
|
+
async function writeAtInNodeEncrypted(config, node, offset, data) {
|
|
164
|
+
const { store } = config;
|
|
165
|
+
const newLinks = [];
|
|
166
|
+
// First pass: collect plaintext sizes by decrypting headers or using heuristics
|
|
167
|
+
// AES-GCM adds 16 bytes tag, so plaintext size = ciphertext size - 16
|
|
168
|
+
const AES_GCM_TAG_SIZE = 16;
|
|
169
|
+
let position = 0; // Track plaintext position
|
|
170
|
+
for (const link of node.links) {
|
|
171
|
+
// For blobs, plaintext size = ciphertext size - tag
|
|
172
|
+
// For intermediate nodes, the size stored is the sum of child plaintext sizes
|
|
173
|
+
const plaintextSize = link.type === LinkType.Blob
|
|
174
|
+
? link.size - AES_GCM_TAG_SIZE
|
|
175
|
+
: link.size; // Intermediate nodes store total plaintext size of subtree
|
|
176
|
+
const linkStart = position;
|
|
177
|
+
const linkEnd = position + plaintextSize;
|
|
178
|
+
position = linkEnd;
|
|
179
|
+
// Check if this chunk overlaps with the write range
|
|
180
|
+
const writeStart = offset;
|
|
181
|
+
const writeEnd = offset + data.length;
|
|
182
|
+
if (linkEnd <= writeStart || linkStart >= writeEnd) {
|
|
183
|
+
// No overlap - keep original link
|
|
184
|
+
newLinks.push(link);
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
// This chunk needs modification
|
|
188
|
+
if (!link.key) {
|
|
189
|
+
throw new Error(`Missing decryption key for chunk: ${toHex(link.hash)}`);
|
|
190
|
+
}
|
|
191
|
+
const encryptedChunk = await store.get(link.hash);
|
|
192
|
+
if (!encryptedChunk) {
|
|
193
|
+
throw new Error(`Missing chunk: ${toHex(link.hash)}`);
|
|
194
|
+
}
|
|
195
|
+
const decryptedChunk = await decryptChk(encryptedChunk, link.key);
|
|
196
|
+
if (link.type !== LinkType.Blob) {
|
|
197
|
+
// Intermediate node - recurse
|
|
198
|
+
const childNode = decodeTreeNode(decryptedChunk);
|
|
199
|
+
const childOffset = Math.max(0, offset - linkStart);
|
|
200
|
+
const childData = data.slice(Math.max(0, linkStart - offset), Math.min(data.length, linkEnd - offset));
|
|
201
|
+
const newChildLinks = await writeAtInNodeEncrypted(config, childNode, childOffset, childData);
|
|
202
|
+
// Build new encrypted intermediate node
|
|
203
|
+
const newChildNode = {
|
|
204
|
+
type: LinkType.File,
|
|
205
|
+
links: newChildLinks,
|
|
206
|
+
};
|
|
207
|
+
const { data: encodedNode } = await encodeAndHash(newChildNode);
|
|
208
|
+
const { ciphertext, key } = await encryptChk(encodedNode);
|
|
209
|
+
const newChildHash = await sha256(ciphertext);
|
|
210
|
+
await store.put(newChildHash, ciphertext);
|
|
211
|
+
// Recalculate total plaintext size from new links
|
|
212
|
+
const newPlaintextSize = newChildLinks.reduce((sum, l) => {
|
|
213
|
+
return sum + (l.type === LinkType.Blob ? l.size - AES_GCM_TAG_SIZE : l.size);
|
|
214
|
+
}, 0);
|
|
215
|
+
newLinks.push({
|
|
216
|
+
hash: newChildHash,
|
|
217
|
+
size: newPlaintextSize, // Store plaintext size for intermediate nodes
|
|
218
|
+
key,
|
|
219
|
+
type: LinkType.File,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
// Leaf blob - modify bytes
|
|
224
|
+
const newChunkData = new Uint8Array(decryptedChunk);
|
|
225
|
+
// Calculate which bytes to modify in this chunk
|
|
226
|
+
const chunkWriteStart = Math.max(0, writeStart - linkStart);
|
|
227
|
+
const chunkWriteEnd = Math.min(decryptedChunk.length, writeEnd - linkStart);
|
|
228
|
+
const dataReadStart = Math.max(0, linkStart - writeStart);
|
|
229
|
+
const dataReadEnd = dataReadStart + (chunkWriteEnd - chunkWriteStart);
|
|
230
|
+
newChunkData.set(data.slice(dataReadStart, dataReadEnd), chunkWriteStart);
|
|
231
|
+
// Re-encrypt with CHK
|
|
232
|
+
const { ciphertext, key } = await encryptChk(newChunkData);
|
|
233
|
+
const newHash = await sha256(ciphertext);
|
|
234
|
+
await store.put(newHash, ciphertext);
|
|
235
|
+
newLinks.push({
|
|
236
|
+
hash: newHash,
|
|
237
|
+
size: ciphertext.length, // Store ciphertext size for blobs
|
|
238
|
+
key,
|
|
239
|
+
type: LinkType.Blob,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return newLinks;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Build tree from links (unencrypted)
|
|
247
|
+
*/
|
|
248
|
+
async function buildTreeFromLinks(config, links, totalSize) {
|
|
249
|
+
const { store } = config;
|
|
250
|
+
if (links.length === 1 && links[0].size === totalSize) {
|
|
251
|
+
return links[0].hash;
|
|
252
|
+
}
|
|
253
|
+
// Create single flat node with all links
|
|
254
|
+
const node = {
|
|
255
|
+
type: LinkType.File,
|
|
256
|
+
links,
|
|
257
|
+
};
|
|
258
|
+
const { data, hash } = await encodeAndHash(node);
|
|
259
|
+
await store.put(hash, data);
|
|
260
|
+
return hash;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Build encrypted tree from links
|
|
264
|
+
*/
|
|
265
|
+
async function buildEncryptedTreeFromLinks(config, links, totalSize) {
|
|
266
|
+
const { store } = config;
|
|
267
|
+
// Single link with key - return directly
|
|
268
|
+
if (links.length === 1 && links[0].key && links[0].size === totalSize) {
|
|
269
|
+
return { hash: links[0].hash, key: links[0].key };
|
|
270
|
+
}
|
|
271
|
+
// Create single flat node with all links
|
|
272
|
+
const node = {
|
|
273
|
+
type: LinkType.File,
|
|
274
|
+
links,
|
|
275
|
+
};
|
|
276
|
+
const { data } = await encodeAndHash(node);
|
|
277
|
+
const { ciphertext, key } = await encryptChk(data);
|
|
278
|
+
const hash = await sha256(ciphertext);
|
|
279
|
+
await store.put(hash, ciphertext);
|
|
280
|
+
return { hash, key };
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=writeAt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeAt.js","sourceRoot":"","sources":["../../src/tree/writeAt.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HashTree - Simple content-addressed merkle tree
|
|
3
|
+
*
|
|
4
|
+
* Core principle: Every node is stored by SHA256(msgpack(node)) -> msgpack(node)
|
|
5
|
+
* This enables pure KV content-addressed storage.
|
|
6
|
+
*/
|
|
7
|
+
import type { TreeVisibility } from './visibility.js';
|
|
8
|
+
export type { TreeVisibility };
|
|
9
|
+
/**
|
|
10
|
+
* 32-byte SHA256 hash used as content address
|
|
11
|
+
*/
|
|
12
|
+
export type Hash = Uint8Array;
|
|
13
|
+
/**
|
|
14
|
+
* Content Identifier - hash + optional decryption key
|
|
15
|
+
*
|
|
16
|
+
* For public content: just the hash
|
|
17
|
+
* For encrypted content: hash + CHK decryption key
|
|
18
|
+
*/
|
|
19
|
+
export interface CID {
|
|
20
|
+
/** SHA256 hash of the (encrypted) content */
|
|
21
|
+
hash: Hash;
|
|
22
|
+
/** CHK decryption key (for encrypted content) */
|
|
23
|
+
key?: Uint8Array;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a CID from hash and optional key
|
|
27
|
+
*/
|
|
28
|
+
export declare function cid(hash: Hash, key?: Uint8Array): CID;
|
|
29
|
+
/**
|
|
30
|
+
* Link/node types - what kind of content a link points to or a node contains
|
|
31
|
+
*/
|
|
32
|
+
export declare enum LinkType {
|
|
33
|
+
/** Raw data blob (leaf chunk) */
|
|
34
|
+
Blob = 0,
|
|
35
|
+
/** Chunked file tree (TreeNode with unnamed links) */
|
|
36
|
+
File = 1,
|
|
37
|
+
/** Directory tree (TreeNode with named links) */
|
|
38
|
+
Dir = 2
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A link to a child node with optional metadata
|
|
42
|
+
*/
|
|
43
|
+
export interface Link {
|
|
44
|
+
/** SHA256 hash of the child node's MessagePack encoding */
|
|
45
|
+
hash: Hash;
|
|
46
|
+
/** Optional name (for directory entries) */
|
|
47
|
+
name?: string;
|
|
48
|
+
/** Size of subtree in bytes (for efficient seeks). 0 for Dir links. */
|
|
49
|
+
size: number;
|
|
50
|
+
/** CHK decryption key (content hash) for encrypted nodes */
|
|
51
|
+
key?: Uint8Array;
|
|
52
|
+
/** Type of content this link points to: Blob, File, or Dir */
|
|
53
|
+
type: LinkType;
|
|
54
|
+
/** Optional metadata (for directory entries: createdAt, mimeType, thumbnail, etc.) */
|
|
55
|
+
meta?: Record<string, unknown>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Tree node - contains links to children
|
|
59
|
+
* Stored as: SHA256(msgpack(TreeNode)) -> msgpack(TreeNode)
|
|
60
|
+
*
|
|
61
|
+
* For directories: type=Dir, links have names
|
|
62
|
+
* For chunked files: type=File, links are ordered chunks
|
|
63
|
+
*/
|
|
64
|
+
export interface TreeNode {
|
|
65
|
+
/** Type of this node: File or Dir */
|
|
66
|
+
type: LinkType.File | LinkType.Dir;
|
|
67
|
+
/** Links to child nodes */
|
|
68
|
+
links: Link[];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Blob - raw data (leaf)
|
|
72
|
+
* Stored as: SHA256(data) -> data
|
|
73
|
+
*
|
|
74
|
+
* Note: Blobs are stored directly as raw bytes, not as a structured type
|
|
75
|
+
*/
|
|
76
|
+
export type Blob = Uint8Array;
|
|
77
|
+
/**
|
|
78
|
+
* Result of adding content to the tree
|
|
79
|
+
*/
|
|
80
|
+
export interface PutResult {
|
|
81
|
+
/** Hash of the stored node */
|
|
82
|
+
hash: Hash;
|
|
83
|
+
/** Size of the stored data */
|
|
84
|
+
size: number;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Options for building trees
|
|
88
|
+
*/
|
|
89
|
+
export interface TreeOptions {
|
|
90
|
+
/** Max links per tree node before splitting (default: 256) */
|
|
91
|
+
fanout?: number;
|
|
92
|
+
/** Max blob size before chunking (default: 2MB) */
|
|
93
|
+
chunkSize?: number;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Directory entry for building directory trees
|
|
97
|
+
*/
|
|
98
|
+
export interface DirEntry {
|
|
99
|
+
name: string;
|
|
100
|
+
hash: Hash;
|
|
101
|
+
size: number;
|
|
102
|
+
/** Type of content this entry points to: Blob, File, or Dir */
|
|
103
|
+
type: LinkType;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Content-addressed key-value store interface
|
|
107
|
+
*/
|
|
108
|
+
export interface Store {
|
|
109
|
+
/**
|
|
110
|
+
* Store data by its hash
|
|
111
|
+
* @returns true if newly stored, false if already existed
|
|
112
|
+
*/
|
|
113
|
+
put(hash: Hash, data: Uint8Array): Promise<boolean>;
|
|
114
|
+
/**
|
|
115
|
+
* Retrieve data by hash
|
|
116
|
+
* @returns data or null if not found
|
|
117
|
+
*/
|
|
118
|
+
get(hash: Hash): Promise<Uint8Array | null>;
|
|
119
|
+
/**
|
|
120
|
+
* Check if hash exists
|
|
121
|
+
*/
|
|
122
|
+
has(hash: Hash): Promise<boolean>;
|
|
123
|
+
/**
|
|
124
|
+
* Delete by hash
|
|
125
|
+
* @returns true if deleted, false if didn't exist
|
|
126
|
+
*/
|
|
127
|
+
delete(hash: Hash): Promise<boolean>;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Extended store with metadata support (e.g., Blossom)
|
|
131
|
+
*/
|
|
132
|
+
export interface StoreWithMeta extends Store {
|
|
133
|
+
/**
|
|
134
|
+
* Store with content type
|
|
135
|
+
*/
|
|
136
|
+
put(hash: Hash, data: Uint8Array, contentType?: string): Promise<boolean>;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Hex string representation of a hash
|
|
140
|
+
*/
|
|
141
|
+
export type HashHex = string;
|
|
142
|
+
/**
|
|
143
|
+
* Convert hash to hex string
|
|
144
|
+
*/
|
|
145
|
+
export declare function toHex(hash: Hash): HashHex;
|
|
146
|
+
/**
|
|
147
|
+
* Convert hex string to hash
|
|
148
|
+
*/
|
|
149
|
+
export declare function fromHex(hex: HashHex): Hash;
|
|
150
|
+
/**
|
|
151
|
+
* Compare two hashes for equality
|
|
152
|
+
*/
|
|
153
|
+
export declare function hashEquals(a: Hash, b: Hash): boolean;
|
|
154
|
+
/**
|
|
155
|
+
* Entry returned from RefResolver.list()
|
|
156
|
+
*/
|
|
157
|
+
export interface RefResolverListEntry {
|
|
158
|
+
key: string;
|
|
159
|
+
cid: CID;
|
|
160
|
+
/** Tree visibility: public, link-visible, or private */
|
|
161
|
+
visibility?: TreeVisibility;
|
|
162
|
+
/** Encrypted key for link-visible trees - decrypt with link key from URL */
|
|
163
|
+
encryptedKey?: string;
|
|
164
|
+
/** Key ID for link-visible trees */
|
|
165
|
+
keyId?: string;
|
|
166
|
+
/** Self-encrypted key for private/link-visible trees - decrypt with NIP-44 */
|
|
167
|
+
selfEncryptedKey?: string;
|
|
168
|
+
/** Self-encrypted link key for link-visible trees - allows owner to recover link key */
|
|
169
|
+
selfEncryptedLinkKey?: string;
|
|
170
|
+
/** Unix timestamp when the tree was created/last updated */
|
|
171
|
+
createdAt?: number;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Visibility info passed to subscribe callbacks
|
|
175
|
+
*/
|
|
176
|
+
export interface SubscribeVisibilityInfo {
|
|
177
|
+
/** Tree visibility: public, link-visible, or private */
|
|
178
|
+
visibility: TreeVisibility;
|
|
179
|
+
/** Encrypted key for link-visible trees - decrypt with link key from URL */
|
|
180
|
+
encryptedKey?: string;
|
|
181
|
+
/** Key ID for link-visible trees */
|
|
182
|
+
keyId?: string;
|
|
183
|
+
/** Self-encrypted key for private/link-visible trees - decrypt with NIP-44 */
|
|
184
|
+
selfEncryptedKey?: string;
|
|
185
|
+
/** Self-encrypted link key for link-visible trees - allows owner to recover link key for sharing */
|
|
186
|
+
selfEncryptedLinkKey?: string;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Options for publishing a tree
|
|
190
|
+
*/
|
|
191
|
+
export interface PublishOptions {
|
|
192
|
+
/** Tree visibility: public (default), link-visible, or private */
|
|
193
|
+
visibility?: TreeVisibility;
|
|
194
|
+
/** Link key for link-visible trees - if not provided, one will be generated */
|
|
195
|
+
linkKey?: Uint8Array;
|
|
196
|
+
/** Additional l-tags to add (e.g., ['docs'] for document trees) */
|
|
197
|
+
labels?: string[];
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Result from publishing a tree
|
|
201
|
+
*/
|
|
202
|
+
export interface PublishResult {
|
|
203
|
+
/** Whether the publish succeeded */
|
|
204
|
+
success: boolean;
|
|
205
|
+
/** Link key for link-visible trees (include in URL as k= param) */
|
|
206
|
+
linkKey?: Uint8Array;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* RefResolver - Maps human-readable keys to merkle root hashes (refs)
|
|
210
|
+
*
|
|
211
|
+
* This abstraction allows different backends (Nostr, DNS, HTTP, local storage)
|
|
212
|
+
* to provide mutable pointers to immutable content-addressed data.
|
|
213
|
+
*
|
|
214
|
+
* Key format is implementation-specific, e.g.:
|
|
215
|
+
* - Nostr: "npub1.../treename"
|
|
216
|
+
* - DNS: "example.com/treename"
|
|
217
|
+
* - Local: "local/mydata"
|
|
218
|
+
*
|
|
219
|
+
* All methods wait indefinitely until data is available - caller should apply timeout if needed.
|
|
220
|
+
*/
|
|
221
|
+
export interface RefResolver {
|
|
222
|
+
/**
|
|
223
|
+
* Resolve a key to its current CID.
|
|
224
|
+
* Waits indefinitely until found - caller should apply timeout if needed.
|
|
225
|
+
* @returns CID (never null - waits until found)
|
|
226
|
+
*/
|
|
227
|
+
resolve(key: string): Promise<CID | null>;
|
|
228
|
+
/**
|
|
229
|
+
* Subscribe to CID changes for a key.
|
|
230
|
+
* Callback fires immediately with current value (if available), then on each update.
|
|
231
|
+
* Subscription stays open indefinitely until unsubscribed.
|
|
232
|
+
*
|
|
233
|
+
* @param key The key to watch
|
|
234
|
+
* @param callback Called with new CID (or null if deleted/unavailable) and visibility info
|
|
235
|
+
* @returns Unsubscribe function
|
|
236
|
+
*/
|
|
237
|
+
subscribe(key: string, callback: (cid: CID | null, visibilityInfo?: SubscribeVisibilityInfo) => void): () => void;
|
|
238
|
+
/**
|
|
239
|
+
* Publish/update a CID (optional - only for writable backends)
|
|
240
|
+
* Handles all visibility types: public, link-visible, private
|
|
241
|
+
* @param key The key to publish to
|
|
242
|
+
* @param cid The CID to publish (with encryption key if encrypted)
|
|
243
|
+
* @param options Publish options (visibility, linkKey, labels)
|
|
244
|
+
* @returns Result with success status and linkKey (for link-visible)
|
|
245
|
+
*/
|
|
246
|
+
publish?(key: string, cid: CID, options?: PublishOptions): Promise<PublishResult>;
|
|
247
|
+
/**
|
|
248
|
+
* List all keys matching a prefix.
|
|
249
|
+
* Streams results as they arrive - stays open indefinitely.
|
|
250
|
+
* Callback fires on each new entry or update.
|
|
251
|
+
*
|
|
252
|
+
* @param prefix The prefix to watch (e.g., "npub1..." for all trees of a user)
|
|
253
|
+
* @param callback Called with updated list as entries arrive (includes visibility info)
|
|
254
|
+
* @returns Unsubscribe function
|
|
255
|
+
*/
|
|
256
|
+
list?(prefix: string, callback: (entries: Array<RefResolverListEntry>) => void): () => void;
|
|
257
|
+
/**
|
|
258
|
+
* Stop the resolver and clean up resources
|
|
259
|
+
*/
|
|
260
|
+
stop?(): void;
|
|
261
|
+
/**
|
|
262
|
+
* Inject a local list entry (for instant UI updates)
|
|
263
|
+
* This makes trees appear immediately without waiting for network
|
|
264
|
+
* @param entry The entry to inject with full visibility info
|
|
265
|
+
*/
|
|
266
|
+
injectListEntry?(entry: RefResolverListEntry): void;
|
|
267
|
+
/**
|
|
268
|
+
* Delete a tree (publish event without hash to nullify)
|
|
269
|
+
* @param key The key to delete (e.g., "npub1.../treename")
|
|
270
|
+
* @returns true if deleted successfully
|
|
271
|
+
*/
|
|
272
|
+
delete?(key: string): Promise<boolean>;
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B;;GAEG;AACH,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC;AAE9B;;;;;GAKG;AACH,MAAM,WAAW,GAAG;IAClB,6CAA6C;IAC7C,IAAI,EAAE,IAAI,CAAC;IACX,iDAAiD;IACjD,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,GAAG,CAErD;AAED;;GAEG;AACH,oBAAY,QAAQ;IAClB,iCAAiC;IACjC,IAAI,IAAI;IACR,sDAAsD;IACtD,IAAI,IAAI;IACR,iDAAiD;IACjD,GAAG,IAAI;CACR;AAED;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,2DAA2D;IAC3D,IAAI,EAAE,IAAI,CAAC;IACX,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,8DAA8D;IAC9D,IAAI,EAAE,QAAQ,CAAC;IACf,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACvB,qCAAqC;IACrC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC;IACnC,2BAA2B;IAC3B,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED;;;;;GAKG;AACH,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,8BAA8B;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpD;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAE5C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAElC;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,KAAK;IAC1C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3E;AAED;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B;;GAEG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAEzC;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAM1C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,OAAO,CAMpD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,GAAG,CAAC;IACT,wDAAwD;IACxD,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wFAAwF;IACxF,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,wDAAwD;IACxD,UAAU,EAAE,cAAc,CAAC;IAC3B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oGAAoG;IACpG,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,+EAA+E;IAC/E,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IAE1C;;;;;;;;OAQG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,EAAE,cAAc,CAAC,EAAE,uBAAuB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAElH;;;;;;;OAOG;IACH,OAAO,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAElF;;;;;;;;OAQG;IACH,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,oBAAoB,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAE5F;;OAEG;IACH,IAAI,CAAC,IAAI,IAAI,CAAC;IAEd;;;;OAIG;IACH,eAAe,CAAC,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAEpD;;;;OAIG;IACH,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a CID from hash and optional key
|
|
3
|
+
*/
|
|
4
|
+
export function cid(hash, key) {
|
|
5
|
+
return key ? { hash, key } : { hash };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Link/node types - what kind of content a link points to or a node contains
|
|
9
|
+
*/
|
|
10
|
+
export var LinkType;
|
|
11
|
+
(function (LinkType) {
|
|
12
|
+
/** Raw data blob (leaf chunk) */
|
|
13
|
+
LinkType[LinkType["Blob"] = 0] = "Blob";
|
|
14
|
+
/** Chunked file tree (TreeNode with unnamed links) */
|
|
15
|
+
LinkType[LinkType["File"] = 1] = "File";
|
|
16
|
+
/** Directory tree (TreeNode with named links) */
|
|
17
|
+
LinkType[LinkType["Dir"] = 2] = "Dir";
|
|
18
|
+
})(LinkType || (LinkType = {}));
|
|
19
|
+
/**
|
|
20
|
+
* Convert hash to hex string
|
|
21
|
+
*/
|
|
22
|
+
export function toHex(hash) {
|
|
23
|
+
return Array.from(hash).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Convert hex string to hash
|
|
27
|
+
*/
|
|
28
|
+
export function fromHex(hex) {
|
|
29
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
30
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
31
|
+
bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
|
|
32
|
+
}
|
|
33
|
+
return bytes;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Compare two hashes for equality
|
|
37
|
+
*/
|
|
38
|
+
export function hashEquals(a, b) {
|
|
39
|
+
if (a.length !== b.length)
|
|
40
|
+
return false;
|
|
41
|
+
for (let i = 0; i < a.length; i++) {
|
|
42
|
+
if (a[i] !== b[i])
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA2BA;;GAEG;AACH,MAAM,UAAU,GAAG,CAAC,IAAU,EAAE,GAAgB;IAC9C,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,QAOX;AAPD,WAAY,QAAQ;IAClB,iCAAiC;IACjC,uCAAQ,CAAA;IACR,sDAAsD;IACtD,uCAAQ,CAAA;IACR,iDAAiD;IACjD,qCAAO,CAAA;AACT,CAAC,EAPW,QAAQ,KAAR,QAAQ,QAOnB;AAoHD;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,IAAU;IAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,GAAY;IAClC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,CAAO,EAAE,CAAO;IACzC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/verify.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree verification utilities
|
|
3
|
+
*/
|
|
4
|
+
import { Store, Hash } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Verify tree integrity - checks that all referenced hashes exist
|
|
7
|
+
*/
|
|
8
|
+
export declare function verifyTree(store: Store, rootHash: Hash): Promise<{
|
|
9
|
+
valid: boolean;
|
|
10
|
+
missing: Hash[];
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,IAAI,EAAS,MAAM,YAAY,CAAC;AAGhD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,IAAI,GACb,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,IAAI,EAAE,CAAA;CAAE,CAAC,CA0B9C"}
|