@dignetwork/dig-sdk 0.0.1-alpha.15 → 0.0.1-alpha.17

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.
@@ -106,7 +106,7 @@ declare class DataIntegrityTree {
106
106
  * @param rootHash - The root hash of the tree. Defaults to the latest root hash.
107
107
  * @returns The readable stream for the file.
108
108
  */
109
- getValueStream(hexKey: string, rootHash?: string | null): Readable;
109
+ getValueStream(hexKey: string, rootHash?: string | null, byteOffset?: number | null, length?: number | null): Readable;
110
110
  /**
111
111
  * Delete all leaves from the Merkle tree.
112
112
  */
@@ -1 +1 @@
1
- {"version":3,"file":"DataIntegrityTree.d.ts","sourceRoot":"","sources":["../../src/DataIntegrityTree/DataIntegrityTree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DataIntegrityTree.d.ts","sourceRoot":"","sources":["../../src/DataIntegrityTree/DataIntegrityTree.ts"],"names":[],"mappings":"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"}
@@ -111,7 +111,10 @@ class DataIntegrityTree {
111
111
  }
112
112
  }
113
113
  static from(storeId, options) {
114
- return new DataIntegrityTree(storeId, { ...options, disableInitialize: true });
114
+ return new DataIntegrityTree(storeId, {
115
+ ...options,
116
+ disableInitialize: true,
117
+ });
115
118
  }
116
119
  /**
117
120
  * Load the manifest file.
@@ -188,81 +191,54 @@ class DataIntegrityTree {
188
191
  const tempFilePath = path.join(tempDir, `${crypto.randomUUID()}.gz`);
189
192
  return new Promise((resolve, reject) => {
190
193
  const tempWriteStream = fs.createWriteStream(tempFilePath);
191
- // Update the hash with the original data
192
194
  readStream.on("data", (chunk) => {
193
195
  uncompressedHash.update(chunk);
194
196
  });
195
- // Pipe the read stream through gzip into the temporary write stream
196
197
  readStream.pipe(gzip).pipe(tempWriteStream);
197
198
  tempWriteStream.on("finish", async () => {
198
- let finalWriteStream;
199
+ sha256 = uncompressedHash.digest("hex");
200
+ const finalWriteStream = this._createWriteStream(sha256);
201
+ const finalPath = finalWriteStream.path;
202
+ // Ensure the directory exists before copying the file
203
+ const finalDir = path.dirname(finalPath);
204
+ if (!fs.existsSync(finalDir)) {
205
+ fs.mkdirSync(finalDir, { recursive: true });
206
+ }
199
207
  try {
200
- sha256 = uncompressedHash.digest("hex");
201
- finalWriteStream = this._createWriteStream(sha256);
202
- const finalPath = finalWriteStream.path;
203
- // Ensure the directory exists
204
- const finalDir = path.dirname(finalPath);
205
- if (!fs.existsSync(finalDir)) {
206
- fs.mkdirSync(finalDir, { recursive: true });
207
- }
208
- // Copy the temporary gzipped file to the final destination
209
208
  await this._streamFile(tempFilePath, finalPath);
210
- await unlink(tempFilePath); // Clean up the temporary file
209
+ await unlink(tempFilePath);
211
210
  const combinedHash = crypto
212
211
  .createHash("sha256")
213
212
  .update(`${key}/${sha256}`)
214
213
  .digest("hex");
215
- // Check if the key already exists with the same hash
216
214
  if (Array.from(this.files.values()).some((file) => file.hash === combinedHash)) {
217
215
  console.log(`No changes detected for key: ${key}`);
218
216
  return resolve();
219
217
  }
220
- // Delete existing key if present
221
218
  if (this.files.has(key)) {
222
219
  this.deleteKey(key);
223
220
  }
224
- // Insert the new key with the hash
225
221
  console.log(`Inserted key: ${key}`);
226
222
  this.files.set(key, {
227
223
  hash: combinedHash,
228
224
  sha256: sha256,
229
225
  });
226
+ await new Promise((resolve) => setTimeout(resolve, 100));
230
227
  this._rebuildTree();
228
+ await new Promise((resolve) => setTimeout(resolve, 100));
231
229
  resolve();
232
230
  }
233
231
  catch (err) {
234
- // On error, cleanup the temporary file and reject
235
- await unlink(tempFilePath).catch(() => { });
236
232
  reject(err);
237
233
  }
238
- finally {
239
- // Always close the final write stream if it exists
240
- if (finalWriteStream) {
241
- finalWriteStream.end();
242
- }
243
- }
234
+ tempWriteStream.end();
235
+ finalWriteStream.end();
244
236
  });
245
- tempWriteStream.on("error", async (err) => {
246
- // Close streams and clean up in case of error
247
- tempWriteStream.destroy();
248
- gzip.destroy();
249
- readStream.destroy();
250
- await unlink(tempFilePath).catch(() => { }); // Clean up the temp file
237
+ tempWriteStream.on("error", (err) => {
238
+ tempWriteStream.end();
251
239
  reject(err);
252
240
  });
253
- readStream.on("error", async (err) => {
254
- // Close streams and clean up in case of error
255
- tempWriteStream.destroy();
256
- gzip.destroy();
257
- readStream.destroy();
258
- await unlink(tempFilePath).catch(() => { }); // Clean up the temp file
259
- reject(err);
260
- });
261
- gzip.on("error", (err) => {
262
- // Handle errors in the gzip stream
263
- tempWriteStream.destroy();
264
- gzip.destroy();
265
- readStream.destroy();
241
+ readStream.on("error", (err) => {
266
242
  reject(err);
267
243
  });
268
244
  });
@@ -369,7 +345,9 @@ class DataIntegrityTree {
369
345
  ? fs.readFileSync(manifestPath, "utf-8").trim().split("\n")
370
346
  : [];
371
347
  // Check if the last entry is the same as the rootHash to avoid duplicates
372
- const latestRootHash = manifestContent.length > 0 ? manifestContent[manifestContent.length - 1] : null;
348
+ const latestRootHash = manifestContent.length > 0
349
+ ? manifestContent[manifestContent.length - 1]
350
+ : null;
373
351
  if (latestRootHash !== rootHash) {
374
352
  // Append the new rootHash if it is not the same as the last one
375
353
  fs.appendFileSync(manifestPath, `${rootHash}\n`);
@@ -445,7 +423,7 @@ class DataIntegrityTree {
445
423
  * @param rootHash - The root hash of the tree. Defaults to the latest root hash.
446
424
  * @returns The readable stream for the file.
447
425
  */
448
- getValueStream(hexKey, rootHash = null) {
426
+ getValueStream(hexKey, rootHash = null, byteOffset = null, length = null) {
449
427
  if (!isHexString(hexKey)) {
450
428
  throw new Error("key must be a valid hex string");
451
429
  }
@@ -468,8 +446,22 @@ class DataIntegrityTree {
468
446
  if (!fs.existsSync(filePath)) {
469
447
  throw new Error(`File at path ${filePath} does not exist`);
470
448
  }
471
- // Create a read stream and pipe it through a decompression stream using the same algorithm (gzip)
472
- const readStream = fs.createReadStream(filePath);
449
+ const fileSize = fs.statSync(filePath).size;
450
+ // Validate offset and length
451
+ if (byteOffset !== null && length !== null) {
452
+ if (byteOffset + length > fileSize) {
453
+ throw new Error(`Offset (${byteOffset}) and length (${length}) exceed the file size (${fileSize}).`);
454
+ }
455
+ }
456
+ // Create the read stream with optional byte range
457
+ const options = {};
458
+ if (byteOffset !== null) {
459
+ options.start = byteOffset;
460
+ }
461
+ if (length !== null && byteOffset !== null) {
462
+ options.end = byteOffset + length - 1; // `end` is inclusive, hence `byteOffset + length - 1`
463
+ }
464
+ const readStream = fs.createReadStream(filePath, options);
473
465
  const decompressStream = zlib.createGunzip();
474
466
  // Return the combined stream as a generic Readable stream
475
467
  return readStream.pipe(decompressStream);
@@ -1 +1 @@
1
- {"version":3,"file":"directoryUtils.d.ts","sourceRoot":"","sources":["../../src/utils/directoryUtils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AA8BzD,eAAO,MAAM,YAAY,cACZ,iBAAiB,WACnB,MAAM,YACN,MAAM,KACd,OAAO,CAAC,IAAI,CAiDd,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,eAAgB,MAAM,KAAG,MAiBxD,CAAC"}
1
+ {"version":3,"file":"directoryUtils.d.ts","sourceRoot":"","sources":["../../src/utils/directoryUtils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AA+BzD,eAAO,MAAM,YAAY,cACZ,iBAAiB,WACnB,MAAM,YACN,MAAM,KACd,OAAO,CAAC,IAAI,CA4Cd,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,eAAgB,MAAM,KAAG,MAiBxD,CAAC"}
@@ -32,22 +32,23 @@ const fs = __importStar(require("fs"));
32
32
  const ignore_1 = __importDefault(require("ignore"));
33
33
  // Custom concurrency handler
34
34
  const limitConcurrency = async (concurrencyLimit, tasks) => {
35
- const results = [];
36
35
  const executing = [];
37
36
  for (const task of tasks) {
38
37
  const p = task();
39
- results.push(p);
38
+ // Add the new task to the executing array
39
+ executing.push(p);
40
+ // When a task completes, remove it from the executing array
41
+ const cleanup = p.finally(() => {
42
+ executing.splice(executing.indexOf(cleanup), 1);
43
+ });
40
44
  // Once the limit is reached, wait for one to complete
41
45
  if (executing.length >= concurrencyLimit) {
46
+ await new Promise((resolve) => setTimeout(resolve, 100));
42
47
  await Promise.race(executing);
43
48
  }
44
- // Add the new task to the executing array
45
- executing.push(p);
46
- // When a task completes, remove it from the executing array
47
- p.finally(() => executing.splice(executing.indexOf(p), 1));
48
49
  }
49
50
  // Wait for all remaining tasks to complete
50
- return Promise.all(results);
51
+ return Promise.all(executing);
51
52
  };
52
53
  const addDirectory = async (datalayer, dirPath, baseDir = dirPath) => {
53
54
  const ig = (0, ignore_1.default)();
@@ -77,14 +78,10 @@ const addDirectory = async (datalayer, dirPath, baseDir = dirPath) => {
77
78
  const stream = fs.createReadStream(filePath);
78
79
  datalayer
79
80
  .upsertKey(stream, Buffer.from(relativePath).toString("hex"))
80
- .then(async () => {
81
- await new Promise((resolve) => setTimeout(resolve, 100));
82
- resolve();
83
- })
81
+ .then(() => resolve())
84
82
  .catch(reject);
85
83
  }));
86
84
  }
87
- await new Promise((resolve) => setTimeout(resolve, 100));
88
85
  }
89
86
  // Run tasks with limited concurrency (set the concurrency limit as needed)
90
87
  await limitConcurrency(10, tasks); // Adjust 10 based on your system limits
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dignetwork/dig-sdk",
3
- "version": "0.0.1-alpha.15",
3
+ "version": "0.0.1-alpha.17",
4
4
  "description": "",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",