@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,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OPFS (Origin Private File System) content-addressed store
|
|
3
|
+
* Persistent browser storage using the File System Access API
|
|
4
|
+
*
|
|
5
|
+
* Files are stored as: <dirName>/<first2chars>/<hash>.bin
|
|
6
|
+
* This provides sharding to avoid too many files in one directory.
|
|
7
|
+
*/
|
|
8
|
+
import { toHex, fromHex } from '../types.js';
|
|
9
|
+
const DEFAULT_DIR_NAME = 'hashtree';
|
|
10
|
+
export class OpfsStore {
|
|
11
|
+
dirName;
|
|
12
|
+
rootDir = null;
|
|
13
|
+
storeDir = null;
|
|
14
|
+
initPromise = null;
|
|
15
|
+
constructor(options = DEFAULT_DIR_NAME) {
|
|
16
|
+
if (typeof options === 'string') {
|
|
17
|
+
this.dirName = options;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
this.dirName = options.dirName ?? DEFAULT_DIR_NAME;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get or create the store directory (with deduplication)
|
|
25
|
+
*/
|
|
26
|
+
async getStoreDir() {
|
|
27
|
+
if (this.storeDir)
|
|
28
|
+
return this.storeDir;
|
|
29
|
+
// Deduplicate initialization
|
|
30
|
+
if (this.initPromise)
|
|
31
|
+
return this.initPromise;
|
|
32
|
+
this.initPromise = (async () => {
|
|
33
|
+
this.rootDir = await navigator.storage.getDirectory();
|
|
34
|
+
this.storeDir = await this.rootDir.getDirectoryHandle(this.dirName, { create: true });
|
|
35
|
+
return this.storeDir;
|
|
36
|
+
})();
|
|
37
|
+
return this.initPromise;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get shard directory for a hash (first 2 hex chars)
|
|
41
|
+
*/
|
|
42
|
+
async getShardDir(hashHex, create) {
|
|
43
|
+
const storeDir = await this.getStoreDir();
|
|
44
|
+
const shard = hashHex.slice(0, 2);
|
|
45
|
+
try {
|
|
46
|
+
return await storeDir.getDirectoryHandle(shard, { create });
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async put(hash, data) {
|
|
53
|
+
const hashHex = toHex(hash);
|
|
54
|
+
try {
|
|
55
|
+
const shardDir = await this.getShardDir(hashHex, true);
|
|
56
|
+
if (!shardDir)
|
|
57
|
+
return false;
|
|
58
|
+
// Check if file already exists
|
|
59
|
+
try {
|
|
60
|
+
await shardDir.getFileHandle(`${hashHex}.bin`, { create: false });
|
|
61
|
+
return false; // Already exists
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// File doesn't exist, continue to create
|
|
65
|
+
}
|
|
66
|
+
const handle = await shardDir.getFileHandle(`${hashHex}.bin`, { create: true });
|
|
67
|
+
const writable = await handle.createWritable();
|
|
68
|
+
await writable.write(data);
|
|
69
|
+
await writable.close();
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
console.error(`OPFS write failed for ${hashHex}:`, err);
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async get(hash) {
|
|
78
|
+
if (!hash)
|
|
79
|
+
return null;
|
|
80
|
+
const hashHex = toHex(hash);
|
|
81
|
+
const shardDir = await this.getShardDir(hashHex, false);
|
|
82
|
+
if (!shardDir)
|
|
83
|
+
return null;
|
|
84
|
+
try {
|
|
85
|
+
const handle = await shardDir.getFileHandle(`${hashHex}.bin`, { create: false });
|
|
86
|
+
const file = await handle.getFile();
|
|
87
|
+
const buffer = await file.arrayBuffer();
|
|
88
|
+
return new Uint8Array(buffer);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async has(hash) {
|
|
95
|
+
const hashHex = toHex(hash);
|
|
96
|
+
const shardDir = await this.getShardDir(hashHex, false);
|
|
97
|
+
if (!shardDir)
|
|
98
|
+
return false;
|
|
99
|
+
try {
|
|
100
|
+
await shardDir.getFileHandle(`${hashHex}.bin`, { create: false });
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async delete(hash) {
|
|
108
|
+
const hashHex = toHex(hash);
|
|
109
|
+
const shardDir = await this.getShardDir(hashHex, false);
|
|
110
|
+
if (!shardDir)
|
|
111
|
+
return false;
|
|
112
|
+
try {
|
|
113
|
+
await shardDir.removeEntry(`${hashHex}.bin`);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get all stored hashes
|
|
122
|
+
*/
|
|
123
|
+
async keys() {
|
|
124
|
+
const storeDir = await this.getStoreDir();
|
|
125
|
+
const hashes = [];
|
|
126
|
+
// @ts-ignore - entries() exists on FileSystemDirectoryHandle
|
|
127
|
+
for await (const [, shardHandle] of storeDir.entries()) {
|
|
128
|
+
if (shardHandle.kind !== 'directory')
|
|
129
|
+
continue;
|
|
130
|
+
// @ts-ignore
|
|
131
|
+
for await (const [fileName] of shardHandle.entries()) {
|
|
132
|
+
if (fileName.endsWith('.bin')) {
|
|
133
|
+
const hashHex = fileName.slice(0, -4);
|
|
134
|
+
hashes.push(fromHex(hashHex));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return hashes;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Clear all data
|
|
142
|
+
*/
|
|
143
|
+
async clear() {
|
|
144
|
+
const storeDir = await this.getStoreDir();
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
for await (const [name, handle] of storeDir.entries()) {
|
|
147
|
+
if (handle.kind === 'directory') {
|
|
148
|
+
await storeDir.removeEntry(name, { recursive: true });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get count of stored items
|
|
154
|
+
*/
|
|
155
|
+
async count() {
|
|
156
|
+
const keys = await this.keys();
|
|
157
|
+
return keys.length;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get total bytes stored
|
|
161
|
+
*/
|
|
162
|
+
async totalBytes() {
|
|
163
|
+
const storeDir = await this.getStoreDir();
|
|
164
|
+
let total = 0;
|
|
165
|
+
// @ts-ignore
|
|
166
|
+
for await (const [, shardHandle] of storeDir.entries()) {
|
|
167
|
+
if (shardHandle.kind !== 'directory')
|
|
168
|
+
continue;
|
|
169
|
+
// @ts-ignore
|
|
170
|
+
for await (const [, fileHandle] of shardHandle.entries()) {
|
|
171
|
+
if (fileHandle.kind === 'file') {
|
|
172
|
+
const file = await fileHandle.getFile();
|
|
173
|
+
total += file.size;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return total;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Close - cleanup any resources
|
|
181
|
+
*/
|
|
182
|
+
async close() {
|
|
183
|
+
this.rootDir = null;
|
|
184
|
+
this.storeDir = null;
|
|
185
|
+
this.initPromise = null;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Delete the entire store directory
|
|
189
|
+
*/
|
|
190
|
+
static async deleteStore(dirName = DEFAULT_DIR_NAME) {
|
|
191
|
+
const root = await navigator.storage.getDirectory();
|
|
192
|
+
try {
|
|
193
|
+
await root.removeEntry(dirName, { recursive: true });
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// Directory might not exist
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=opfs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opfs.js","sourceRoot":"","sources":["../../src/store/opfs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StreamWriter - supports incremental file appends
|
|
3
|
+
*
|
|
4
|
+
* Created via HashTree.createStream()
|
|
5
|
+
*
|
|
6
|
+
* All chunks are CHK encrypted by default (same as putFile).
|
|
7
|
+
* Use createStream({ unencrypted: true }) for unencrypted streaming.
|
|
8
|
+
*/
|
|
9
|
+
import { Store, Hash, CID } from './types.js';
|
|
10
|
+
import { type EncryptionKey } from './crypto.js';
|
|
11
|
+
import { type Chunker } from './builder.js';
|
|
12
|
+
export type { Chunker } from './builder.js';
|
|
13
|
+
export interface StreamWriterConfig {
|
|
14
|
+
store: Store;
|
|
15
|
+
chunkSize?: number;
|
|
16
|
+
chunker?: Chunker;
|
|
17
|
+
unencrypted?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare class StreamWriter {
|
|
20
|
+
private store;
|
|
21
|
+
private chunker;
|
|
22
|
+
private unencrypted;
|
|
23
|
+
private buffer;
|
|
24
|
+
private bufferOffset;
|
|
25
|
+
private chunks;
|
|
26
|
+
private totalSize;
|
|
27
|
+
constructor(config: StreamWriterConfig);
|
|
28
|
+
/** @deprecated Use config object instead */
|
|
29
|
+
constructor(store: Store, chunkSize: number, maxLinks: number, unencrypted?: boolean);
|
|
30
|
+
/** Get current target chunk size */
|
|
31
|
+
private currentChunkSize;
|
|
32
|
+
/**
|
|
33
|
+
* Append data to the stream
|
|
34
|
+
*/
|
|
35
|
+
append(data: Uint8Array): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Flush current buffer as a chunk (encrypted or plaintext based on mode)
|
|
38
|
+
*/
|
|
39
|
+
private flushChunk;
|
|
40
|
+
/**
|
|
41
|
+
* Get current root CID without finalizing
|
|
42
|
+
* Useful for checkpoints (e.g., live streaming)
|
|
43
|
+
* Returns CID with key for encrypted streams, CID without key for public streams
|
|
44
|
+
*/
|
|
45
|
+
currentRoot(): Promise<CID | null>;
|
|
46
|
+
/**
|
|
47
|
+
* Finalize the stream and return root CID
|
|
48
|
+
* For encrypted streams: returns { hash, size, key }
|
|
49
|
+
* For public streams: returns { hash, size } (key is undefined)
|
|
50
|
+
*/
|
|
51
|
+
finalize(): Promise<{
|
|
52
|
+
hash: Hash;
|
|
53
|
+
size: number;
|
|
54
|
+
key?: EncryptionKey;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Build flat tree from chunks
|
|
58
|
+
*/
|
|
59
|
+
private buildTreeFromChunks;
|
|
60
|
+
/**
|
|
61
|
+
* Get stats
|
|
62
|
+
*/
|
|
63
|
+
get stats(): {
|
|
64
|
+
chunks: number;
|
|
65
|
+
buffered: number;
|
|
66
|
+
totalSize: number;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Clear internal state to release memory
|
|
70
|
+
* Call after finalize() if you want to free memory immediately
|
|
71
|
+
*/
|
|
72
|
+
clear(): void;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=streaming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAiC,MAAM,YAAY,CAAC;AAG7E,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,KAAK,OAAO,EAAgB,MAAM,cAAc,CAAC;AAC1D,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAU;IAG7B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,YAAY,CAAa;IAGjC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,SAAS,CAAa;gBAElB,MAAM,EAAE,kBAAkB;IACtC,4CAA4C;gBAChC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO;IAuBpF,oCAAoC;IACpC,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B7C;;OAEG;YACW,UAAU;IAuBxB;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IA2BxC;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC;IAuB5E;;OAEG;YACW,mBAAmB;IA0BjC;;OAEG;IACH,IAAI,KAAK,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAMnE;IAED;;;OAGG;IACH,KAAK,IAAI,IAAI;CAMd"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StreamWriter - supports incremental file appends
|
|
3
|
+
*
|
|
4
|
+
* Created via HashTree.createStream()
|
|
5
|
+
*
|
|
6
|
+
* All chunks are CHK encrypted by default (same as putFile).
|
|
7
|
+
* Use createStream({ unencrypted: true }) for unencrypted streaming.
|
|
8
|
+
*/
|
|
9
|
+
import { LinkType, cid } from './types.js';
|
|
10
|
+
import { encodeAndHash } from './codec.js';
|
|
11
|
+
import { sha256 } from './hash.js';
|
|
12
|
+
import { encryptChk } from './crypto.js';
|
|
13
|
+
import { fixedChunker } from './builder.js';
|
|
14
|
+
export class StreamWriter {
|
|
15
|
+
store;
|
|
16
|
+
chunker;
|
|
17
|
+
unencrypted;
|
|
18
|
+
// Current partial chunk being built
|
|
19
|
+
buffer;
|
|
20
|
+
bufferOffset = 0;
|
|
21
|
+
// Completed chunks (with encryption keys for tree building when encrypted)
|
|
22
|
+
chunks = [];
|
|
23
|
+
totalSize = 0;
|
|
24
|
+
constructor(storeOrConfig, chunkSize, _maxLinks, unencrypted) {
|
|
25
|
+
if ('store' in storeOrConfig && typeof storeOrConfig === 'object' && !('get' in storeOrConfig)) {
|
|
26
|
+
// New config-based constructor
|
|
27
|
+
const config = storeOrConfig;
|
|
28
|
+
this.store = config.store;
|
|
29
|
+
this.chunker = config.chunker ?? fixedChunker(config.chunkSize ?? 2 * 1024 * 1024);
|
|
30
|
+
this.unencrypted = config.unencrypted ?? false;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
// Legacy positional constructor (maxLinks ignored)
|
|
34
|
+
this.store = storeOrConfig;
|
|
35
|
+
this.chunker = fixedChunker(chunkSize);
|
|
36
|
+
this.unencrypted = unencrypted ?? false;
|
|
37
|
+
}
|
|
38
|
+
// Initialize buffer with first chunk size
|
|
39
|
+
this.buffer = new Uint8Array(this.chunker(0));
|
|
40
|
+
}
|
|
41
|
+
/** Get current target chunk size */
|
|
42
|
+
currentChunkSize() {
|
|
43
|
+
return this.chunker(this.chunks.length);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Append data to the stream
|
|
47
|
+
*/
|
|
48
|
+
async append(data) {
|
|
49
|
+
let offset = 0;
|
|
50
|
+
while (offset < data.length) {
|
|
51
|
+
const targetSize = this.currentChunkSize();
|
|
52
|
+
// Resize buffer if needed for new chunk size
|
|
53
|
+
if (this.buffer.length !== targetSize) {
|
|
54
|
+
const newBuffer = new Uint8Array(targetSize);
|
|
55
|
+
if (this.bufferOffset > 0) {
|
|
56
|
+
newBuffer.set(this.buffer.subarray(0, this.bufferOffset));
|
|
57
|
+
}
|
|
58
|
+
this.buffer = newBuffer;
|
|
59
|
+
}
|
|
60
|
+
const space = targetSize - this.bufferOffset;
|
|
61
|
+
const toWrite = Math.min(space, data.length - offset);
|
|
62
|
+
this.buffer.set(data.subarray(offset, offset + toWrite), this.bufferOffset);
|
|
63
|
+
this.bufferOffset += toWrite;
|
|
64
|
+
offset += toWrite;
|
|
65
|
+
// Flush full chunk
|
|
66
|
+
if (this.bufferOffset === targetSize) {
|
|
67
|
+
await this.flushChunk();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
this.totalSize += data.length;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Flush current buffer as a chunk (encrypted or plaintext based on mode)
|
|
74
|
+
*/
|
|
75
|
+
async flushChunk() {
|
|
76
|
+
if (this.bufferOffset === 0)
|
|
77
|
+
return;
|
|
78
|
+
const chunkSize = this.bufferOffset;
|
|
79
|
+
// slice() to create independent copy - allows buffer reuse after await
|
|
80
|
+
const chunk = this.buffer.slice(0, chunkSize);
|
|
81
|
+
if (this.unencrypted) {
|
|
82
|
+
// Public mode: store plaintext
|
|
83
|
+
const hash = await sha256(chunk);
|
|
84
|
+
await this.store.put(hash, chunk);
|
|
85
|
+
this.chunks.push({ hash, size: chunkSize, type: LinkType.Blob });
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Encrypted mode: CHK encrypt the chunk
|
|
89
|
+
const { ciphertext, key } = await encryptChk(chunk);
|
|
90
|
+
const hash = await sha256(ciphertext);
|
|
91
|
+
await this.store.put(hash, ciphertext);
|
|
92
|
+
this.chunks.push({ hash, size: chunkSize, key, type: LinkType.Blob });
|
|
93
|
+
}
|
|
94
|
+
this.bufferOffset = 0;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get current root CID without finalizing
|
|
98
|
+
* Useful for checkpoints (e.g., live streaming)
|
|
99
|
+
* Returns CID with key for encrypted streams, CID without key for public streams
|
|
100
|
+
*/
|
|
101
|
+
async currentRoot() {
|
|
102
|
+
if (this.chunks.length === 0 && this.bufferOffset === 0) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
// Temporarily store buffer without modifying state
|
|
106
|
+
const tempChunks = [...this.chunks];
|
|
107
|
+
if (this.bufferOffset > 0) {
|
|
108
|
+
const chunk = this.buffer.slice(0, this.bufferOffset);
|
|
109
|
+
if (this.unencrypted) {
|
|
110
|
+
const hash = await sha256(chunk);
|
|
111
|
+
await this.store.put(hash, chunk);
|
|
112
|
+
tempChunks.push({ hash, size: chunk.length, type: LinkType.Blob });
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Store PLAINTEXT size in link.size for correct range seeking
|
|
116
|
+
const plaintextSize = chunk.length;
|
|
117
|
+
const { ciphertext, key } = await encryptChk(chunk);
|
|
118
|
+
const hash = await sha256(ciphertext);
|
|
119
|
+
await this.store.put(hash, ciphertext);
|
|
120
|
+
tempChunks.push({ hash, size: plaintextSize, key, type: LinkType.Blob });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return this.buildTreeFromChunks(tempChunks, this.totalSize);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Finalize the stream and return root CID
|
|
127
|
+
* For encrypted streams: returns { hash, size, key }
|
|
128
|
+
* For public streams: returns { hash, size } (key is undefined)
|
|
129
|
+
*/
|
|
130
|
+
async finalize() {
|
|
131
|
+
// Flush remaining buffer
|
|
132
|
+
await this.flushChunk();
|
|
133
|
+
if (this.chunks.length === 0) {
|
|
134
|
+
// Empty stream
|
|
135
|
+
if (this.unencrypted) {
|
|
136
|
+
const emptyData = new Uint8Array(0);
|
|
137
|
+
const hash = await sha256(emptyData);
|
|
138
|
+
await this.store.put(hash, emptyData);
|
|
139
|
+
return { hash, size: 0 };
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
const { ciphertext, key } = await encryptChk(new Uint8Array(0));
|
|
143
|
+
const hash = await sha256(ciphertext);
|
|
144
|
+
await this.store.put(hash, ciphertext);
|
|
145
|
+
return { hash, size: 0, key };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const result = await this.buildTreeFromChunks(this.chunks, this.totalSize);
|
|
149
|
+
return { hash: result.hash, size: this.totalSize, key: result.key };
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Build flat tree from chunks
|
|
153
|
+
*/
|
|
154
|
+
async buildTreeFromChunks(chunks, _totalSize) {
|
|
155
|
+
// Single chunk - return its hash (and key if encrypted)
|
|
156
|
+
if (chunks.length === 1) {
|
|
157
|
+
return cid(chunks[0].hash, chunks[0].key);
|
|
158
|
+
}
|
|
159
|
+
// Create single flat node with all links
|
|
160
|
+
const node = {
|
|
161
|
+
type: LinkType.File,
|
|
162
|
+
links: chunks,
|
|
163
|
+
};
|
|
164
|
+
const { data, hash: nodeHash } = await encodeAndHash(node);
|
|
165
|
+
if (this.unencrypted) {
|
|
166
|
+
// Public mode: store plaintext tree node
|
|
167
|
+
await this.store.put(nodeHash, data);
|
|
168
|
+
return { hash: nodeHash };
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// Encrypted mode: CHK encrypt the tree node
|
|
172
|
+
const { ciphertext, key } = await encryptChk(data);
|
|
173
|
+
const hash = await sha256(ciphertext);
|
|
174
|
+
await this.store.put(hash, ciphertext);
|
|
175
|
+
return cid(hash, key);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get stats
|
|
180
|
+
*/
|
|
181
|
+
get stats() {
|
|
182
|
+
return {
|
|
183
|
+
chunks: this.chunks.length,
|
|
184
|
+
buffered: this.bufferOffset,
|
|
185
|
+
totalSize: this.totalSize,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Clear internal state to release memory
|
|
190
|
+
* Call after finalize() if you want to free memory immediately
|
|
191
|
+
*/
|
|
192
|
+
clear() {
|
|
193
|
+
this.chunks = [];
|
|
194
|
+
this.buffer = new Uint8Array(0);
|
|
195
|
+
this.bufferOffset = 0;
|
|
196
|
+
this.totalSize = 0;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=streaming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming.js","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree creation operations
|
|
3
|
+
*/
|
|
4
|
+
import { Store, Hash, Link, LinkType, CID } from '../types.js';
|
|
5
|
+
export interface CreateConfig {
|
|
6
|
+
store: Store;
|
|
7
|
+
chunkSize: number;
|
|
8
|
+
}
|
|
9
|
+
export interface DirEntry {
|
|
10
|
+
name: string;
|
|
11
|
+
cid: CID;
|
|
12
|
+
size: number;
|
|
13
|
+
type: LinkType;
|
|
14
|
+
meta?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Store a blob directly (small data)
|
|
18
|
+
*/
|
|
19
|
+
export declare function putBlob(store: Store, data: Uint8Array): Promise<Hash>;
|
|
20
|
+
/**
|
|
21
|
+
* Store a file, chunking if necessary
|
|
22
|
+
*/
|
|
23
|
+
export declare function putFile(config: CreateConfig, data: Uint8Array): Promise<{
|
|
24
|
+
hash: Hash;
|
|
25
|
+
size: number;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Build a directory from entries
|
|
29
|
+
*
|
|
30
|
+
* Directories are encoded as MessagePack blobs. If the encoded blob exceeds
|
|
31
|
+
* chunkSize, it's chunked by bytes like files using putFile.
|
|
32
|
+
*/
|
|
33
|
+
export declare function putDirectory(config: CreateConfig, entries: DirEntry[]): Promise<Hash>;
|
|
34
|
+
export declare function buildTree(config: CreateConfig, links: Link[], totalSize?: number): Promise<Hash>;
|
|
35
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/tree/create.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,IAAI,EAAY,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAIzE,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3E;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA4BvC;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,QAAQ,EAAE,GAClB,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,IAAI,EAAE,EACb,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAgBf"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree creation operations
|
|
3
|
+
*/
|
|
4
|
+
import { LinkType } from '../types.js';
|
|
5
|
+
import { sha256 } from '../hash.js';
|
|
6
|
+
import { encodeAndHash } from '../codec.js';
|
|
7
|
+
/**
|
|
8
|
+
* Store a blob directly (small data)
|
|
9
|
+
*/
|
|
10
|
+
export async function putBlob(store, data) {
|
|
11
|
+
const hash = await sha256(data);
|
|
12
|
+
await store.put(hash, data);
|
|
13
|
+
return hash;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Store a file, chunking if necessary
|
|
17
|
+
*/
|
|
18
|
+
export async function putFile(config, data) {
|
|
19
|
+
const { store, chunkSize } = config;
|
|
20
|
+
const size = data.length;
|
|
21
|
+
if (data.length <= chunkSize) {
|
|
22
|
+
const hash = await putBlob(store, data);
|
|
23
|
+
return { hash, size };
|
|
24
|
+
}
|
|
25
|
+
// Process chunks sequentially to avoid memory spikes
|
|
26
|
+
// (For parallel processing of large files, use StreamWriter instead)
|
|
27
|
+
const links = [];
|
|
28
|
+
let offset = 0;
|
|
29
|
+
while (offset < data.length) {
|
|
30
|
+
const end = Math.min(offset + chunkSize, data.length);
|
|
31
|
+
// Use subarray to avoid copying
|
|
32
|
+
const chunk = data.subarray(offset, end);
|
|
33
|
+
const hash = await putBlob(store, chunk);
|
|
34
|
+
links.push({
|
|
35
|
+
hash,
|
|
36
|
+
size: chunk.length,
|
|
37
|
+
type: LinkType.Blob,
|
|
38
|
+
});
|
|
39
|
+
offset = end;
|
|
40
|
+
}
|
|
41
|
+
const rootHash = await buildTree(config, links, size);
|
|
42
|
+
return { hash: rootHash, size };
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build a directory from entries
|
|
46
|
+
*
|
|
47
|
+
* Directories are encoded as MessagePack blobs. If the encoded blob exceeds
|
|
48
|
+
* chunkSize, it's chunked by bytes like files using putFile.
|
|
49
|
+
*/
|
|
50
|
+
export async function putDirectory(config, entries) {
|
|
51
|
+
const { store, chunkSize } = config;
|
|
52
|
+
const sorted = [...entries].sort((a, b) => a.name.localeCompare(b.name));
|
|
53
|
+
const links = sorted.map(e => ({
|
|
54
|
+
hash: e.cid.hash,
|
|
55
|
+
key: e.cid.key,
|
|
56
|
+
name: e.name,
|
|
57
|
+
size: e.size,
|
|
58
|
+
type: e.type,
|
|
59
|
+
meta: e.meta,
|
|
60
|
+
}));
|
|
61
|
+
const node = {
|
|
62
|
+
type: LinkType.Dir,
|
|
63
|
+
links,
|
|
64
|
+
};
|
|
65
|
+
const { data, hash } = await encodeAndHash(node);
|
|
66
|
+
// Small directory - store directly
|
|
67
|
+
if (data.length <= chunkSize) {
|
|
68
|
+
await store.put(hash, data);
|
|
69
|
+
return hash;
|
|
70
|
+
}
|
|
71
|
+
// Large directory - reuse putFile for chunking
|
|
72
|
+
const { hash: rootHash } = await putFile(config, data);
|
|
73
|
+
return rootHash;
|
|
74
|
+
}
|
|
75
|
+
export async function buildTree(config, links, totalSize) {
|
|
76
|
+
const { store } = config;
|
|
77
|
+
// Single chunk that matches total size - return it directly
|
|
78
|
+
if (links.length === 1 && links[0].size === totalSize) {
|
|
79
|
+
return links[0].hash;
|
|
80
|
+
}
|
|
81
|
+
// Create single flat node with all links
|
|
82
|
+
const node = {
|
|
83
|
+
type: LinkType.File,
|
|
84
|
+
links,
|
|
85
|
+
};
|
|
86
|
+
const { data, hash } = await encodeAndHash(node);
|
|
87
|
+
await store.put(hash, data);
|
|
88
|
+
return hash;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/tree/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree editing operations
|
|
3
|
+
*/
|
|
4
|
+
import { Hash, CID, LinkType } from '../types.js';
|
|
5
|
+
import { type CreateConfig } from './create.js';
|
|
6
|
+
export interface EditConfig extends CreateConfig {
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Add or update an entry in a directory
|
|
10
|
+
* @returns New root hash
|
|
11
|
+
*/
|
|
12
|
+
export declare function setEntry(config: EditConfig, rootHash: Hash, path: string[], name: string, entryCid: CID, size: number, type?: LinkType, meta?: Record<string, unknown>): Promise<Hash>;
|
|
13
|
+
/**
|
|
14
|
+
* Remove an entry from a directory
|
|
15
|
+
* @returns New root hash
|
|
16
|
+
*/
|
|
17
|
+
export declare function removeEntry(config: EditConfig, rootHash: Hash, path: string[], name: string): Promise<Hash>;
|
|
18
|
+
/**
|
|
19
|
+
* Rename an entry in a directory
|
|
20
|
+
* @returns New root hash
|
|
21
|
+
*/
|
|
22
|
+
export declare function renameEntry(config: EditConfig, rootHash: Hash, path: string[], oldName: string, newName: string): Promise<Hash>;
|
|
23
|
+
/**
|
|
24
|
+
* Move an entry to a different directory
|
|
25
|
+
* @returns New root hash
|
|
26
|
+
*/
|
|
27
|
+
export declare function moveEntry(config: EditConfig, rootHash: Hash, sourcePath: string[], name: string, targetPath: string[]): Promise<Hash>;
|
|
28
|
+
//# sourceMappingURL=edit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tree/edit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAS,IAAI,EAAE,GAAG,EAAO,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAA+B,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAG7E,MAAM,WAAW,UAAW,SAAQ,YAAY;CAAG;AAEnD;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,IAAI,EACd,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,GAAG,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,QAAwB,EAC9B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,IAAI,EACd,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,IAAI,EACd,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,IAAI,EACd,UAAU,EAAE,MAAM,EAAE,EACpB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
|