@dignetwork/dig-sdk 0.0.1-alpha.19 → 0.0.1-alpha.191
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/dist/DataIntegrityTree/DataIntegrityTree.d.ts +10 -1
- package/dist/DataIntegrityTree/DataIntegrityTree.d.ts.map +1 -1
- package/dist/DataIntegrityTree/DataIntegrityTree.js +77 -10
- package/dist/DigNetwork/ContentServer.d.ts +20 -5
- package/dist/DigNetwork/ContentServer.d.ts.map +1 -1
- package/dist/DigNetwork/ContentServer.js +224 -28
- package/dist/DigNetwork/DigNetwork.d.ts +15 -9
- package/dist/DigNetwork/DigNetwork.d.ts.map +1 -1
- package/dist/DigNetwork/DigNetwork.js +129 -189
- package/dist/DigNetwork/DigPeer.d.ts +8 -3
- package/dist/DigNetwork/DigPeer.d.ts.map +1 -1
- package/dist/DigNetwork/DigPeer.js +72 -115
- package/dist/DigNetwork/IncentiveServer.d.ts.map +1 -1
- package/dist/DigNetwork/IncentiveServer.js +6 -5
- package/dist/DigNetwork/PropagationServer.d.ts +89 -33
- package/dist/DigNetwork/PropagationServer.d.ts.map +1 -1
- package/dist/DigNetwork/PropagationServer.js +625 -358
- package/dist/blockchain/DataStore.d.ts +25 -7
- package/dist/blockchain/DataStore.d.ts.map +1 -1
- package/dist/blockchain/DataStore.js +117 -159
- package/dist/blockchain/DataStoreSerializer.d.ts +1 -1
- package/dist/blockchain/DataStoreSerializer.d.ts.map +1 -1
- package/dist/blockchain/FullNodePeer.d.ts +95 -10
- package/dist/blockchain/FullNodePeer.d.ts.map +1 -1
- package/dist/blockchain/FullNodePeer.js +325 -115
- package/dist/blockchain/ServerCoin.d.ts +13 -5
- package/dist/blockchain/ServerCoin.d.ts.map +1 -1
- package/dist/blockchain/ServerCoin.js +89 -28
- package/dist/blockchain/StoreMonitorRegistry.d.ts +85 -0
- package/dist/blockchain/StoreMonitorRegistry.d.ts.map +1 -0
- package/dist/blockchain/StoreMonitorRegistry.js +238 -0
- package/dist/blockchain/Wallet.d.ts +2 -2
- package/dist/blockchain/Wallet.d.ts.map +1 -1
- package/dist/blockchain/Wallet.js +50 -18
- package/dist/blockchain/coins.d.ts +1 -2
- package/dist/blockchain/coins.d.ts.map +1 -1
- package/dist/blockchain/coins.js +1 -55
- package/dist/blockchain/index.d.ts +1 -0
- package/dist/blockchain/index.d.ts.map +1 -1
- package/dist/blockchain/index.js +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/ContentScanner.d.ts +63 -0
- package/dist/utils/ContentScanner.d.ts.map +1 -0
- package/dist/utils/ContentScanner.js +175 -0
- package/dist/utils/DigCache.d.ts +38 -0
- package/dist/utils/DigCache.d.ts.map +1 -0
- package/dist/utils/DigCache.js +236 -0
- package/dist/utils/Environment.d.ts +21 -0
- package/dist/utils/Environment.d.ts.map +1 -0
- package/dist/utils/Environment.js +93 -0
- package/dist/utils/FileCache.d.ts +1 -1
- package/dist/utils/FileCache.d.ts.map +1 -1
- package/dist/utils/FileCache.js +2 -2
- package/dist/utils/FileTransfer.d.ts +47 -0
- package/dist/utils/FileTransfer.d.ts.map +1 -0
- package/dist/utils/FileTransfer.js +209 -0
- package/dist/utils/NconfManager.d.ts.map +1 -1
- package/dist/utils/NconfManager.js +16 -7
- package/dist/utils/PeerRanker.d.ts +55 -0
- package/dist/utils/PeerRanker.d.ts.map +1 -0
- package/dist/utils/PeerRanker.js +186 -0
- package/dist/utils/StoreArchiveManager.d.ts +45 -0
- package/dist/utils/StoreArchiveManager.d.ts.map +1 -0
- package/dist/utils/StoreArchiveManager.js +153 -0
- package/dist/utils/Udi.d.ts +30 -0
- package/dist/utils/Udi.d.ts.map +1 -0
- package/dist/utils/Udi.js +170 -0
- package/dist/utils/config.d.ts +4 -3
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +13 -8
- package/dist/utils/directoryUtils.d.ts +16 -0
- package/dist/utils/directoryUtils.d.ts.map +1 -1
- package/dist/utils/directoryUtils.js +66 -0
- package/dist/utils/index.d.ts +5 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +5 -1
- package/dist/utils/merkle.d.ts +2 -0
- package/dist/utils/merkle.d.ts.map +1 -0
- package/dist/utils/merkle.js +28 -0
- package/dist/utils/network.d.ts +2 -1
- package/dist/utils/network.d.ts.map +1 -1
- package/dist/utils/network.js +40 -15
- package/dist/utils/promiseUtils.d.ts +27 -0
- package/dist/utils/promiseUtils.d.ts.map +1 -0
- package/dist/utils/promiseUtils.js +69 -0
- package/dist/utils/ssl.js +2 -2
- package/package.json +31 -13
- package/dist/utils/deltaUtils.d.ts +0 -2
- package/dist/utils/deltaUtils.d.ts.map +0 -1
- package/dist/utils/deltaUtils.js +0 -83
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.Udi = void 0;
|
|
27
|
+
const urns = __importStar(require("urns"));
|
|
28
|
+
const crypto_1 = require("crypto");
|
|
29
|
+
const hi_base32_1 = require("hi-base32");
|
|
30
|
+
class Udi {
|
|
31
|
+
constructor(chainName, storeId, rootHash = null, resourceKey = null) {
|
|
32
|
+
if (!storeId) {
|
|
33
|
+
throw new Error("storeId cannot be empty");
|
|
34
|
+
}
|
|
35
|
+
this.chainName = chainName || "chia";
|
|
36
|
+
this._storeIdHex = Udi.verifyAndFormatHex(storeId);
|
|
37
|
+
this._rootHashHex = rootHash ? Udi.verifyAndFormatHex(rootHash) : null;
|
|
38
|
+
this.resourceKey = resourceKey;
|
|
39
|
+
}
|
|
40
|
+
static verifyAndFormatHex(input) {
|
|
41
|
+
if (!/^[a-fA-F0-9]{64}$/.test(input)) {
|
|
42
|
+
throw new Error("Input must be a 64-character hex string.");
|
|
43
|
+
}
|
|
44
|
+
return input;
|
|
45
|
+
}
|
|
46
|
+
static fromUrn(urn) {
|
|
47
|
+
const parsedUrn = urns.parseURN(urn);
|
|
48
|
+
if (parsedUrn.nid !== Udi.nid) {
|
|
49
|
+
throw new Error(`Invalid nid: ${parsedUrn.nid}`);
|
|
50
|
+
}
|
|
51
|
+
const parts = parsedUrn.nss.split(":");
|
|
52
|
+
if (parts.length < 2) {
|
|
53
|
+
throw new Error(`Invalid UDI format: ${parsedUrn.nss}`);
|
|
54
|
+
}
|
|
55
|
+
const chainName = parts[0];
|
|
56
|
+
const storeIdHex = Udi.convertToHex(parts[1].split("/")[0]);
|
|
57
|
+
let rootHashHex = null;
|
|
58
|
+
if (parts.length > 2) {
|
|
59
|
+
rootHashHex = Udi.convertToHex(parts[2].split("/")[0]);
|
|
60
|
+
}
|
|
61
|
+
const pathParts = parsedUrn.nss.split("/");
|
|
62
|
+
let resourceKey = null;
|
|
63
|
+
if (pathParts.length > 1) {
|
|
64
|
+
resourceKey = pathParts.slice(1).join("/");
|
|
65
|
+
}
|
|
66
|
+
return new Udi(chainName, storeIdHex, rootHashHex, resourceKey);
|
|
67
|
+
}
|
|
68
|
+
static convertToHex(input) {
|
|
69
|
+
// Attempt hex conversion first
|
|
70
|
+
if (/^[a-fA-F0-9]{64}$/.test(input))
|
|
71
|
+
return input;
|
|
72
|
+
// Convert from Base32
|
|
73
|
+
try {
|
|
74
|
+
const paddedInput = Udi.addBase32Padding(input.toUpperCase());
|
|
75
|
+
const buffer = Buffer.from((0, hi_base32_1.decode)(paddedInput, false));
|
|
76
|
+
return buffer.toString("hex");
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
console.warn("Base32 decoding failed, trying Base64 encoding...");
|
|
80
|
+
}
|
|
81
|
+
// Convert from Base64
|
|
82
|
+
try {
|
|
83
|
+
const standardBase64 = Udi.addBase64Padding(Udi.toStandardBase64(input));
|
|
84
|
+
const buffer = Buffer.from(standardBase64, "base64");
|
|
85
|
+
return buffer.toString("hex");
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
throw new Error("Invalid input encoding. Must be 32-byte hex, Base32, or Base64 string.");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
static addBase32Padding(input) {
|
|
92
|
+
const paddingNeeded = (8 - (input.length % 8)) % 8;
|
|
93
|
+
return input + "=".repeat(paddingNeeded);
|
|
94
|
+
}
|
|
95
|
+
static toStandardBase64(base64UrlSafe) {
|
|
96
|
+
return base64UrlSafe.replace(/-/g, "+").replace(/_/g, "/");
|
|
97
|
+
}
|
|
98
|
+
static addBase64Padding(base64) {
|
|
99
|
+
const paddingNeeded = (4 - (base64.length % 4)) % 4;
|
|
100
|
+
return base64 + "=".repeat(paddingNeeded);
|
|
101
|
+
}
|
|
102
|
+
toUrn(encoding = "hex") {
|
|
103
|
+
const storeIdStr = this.formatBufferAsEncoding(this._storeIdHex, encoding);
|
|
104
|
+
let urn = `${Udi.namespace}:${this.chainName}:${storeIdStr}`;
|
|
105
|
+
if (this._rootHashHex) {
|
|
106
|
+
const rootHashStr = this.formatBufferAsEncoding(this._rootHashHex, encoding);
|
|
107
|
+
urn += `:${rootHashStr}`;
|
|
108
|
+
}
|
|
109
|
+
if (this.resourceKey) {
|
|
110
|
+
urn += `/${this.resourceKey}`;
|
|
111
|
+
}
|
|
112
|
+
return urn;
|
|
113
|
+
}
|
|
114
|
+
formatBufferAsEncoding(hexString, encoding) {
|
|
115
|
+
const buffer = Buffer.from(hexString, "hex");
|
|
116
|
+
if (encoding === "hex") {
|
|
117
|
+
return hexString;
|
|
118
|
+
}
|
|
119
|
+
else if (encoding === "base32") {
|
|
120
|
+
return (0, hi_base32_1.encode)(buffer).replace(/=+$/, ""); // Strip padding for Base32
|
|
121
|
+
}
|
|
122
|
+
else if (encoding === "base64") {
|
|
123
|
+
return Udi.toBase64UrlSafe(buffer.toString("base64")); // Convert to URL-safe Base64
|
|
124
|
+
}
|
|
125
|
+
throw new Error("Unsupported encoding type");
|
|
126
|
+
}
|
|
127
|
+
static toBase64UrlSafe(base64Standard) {
|
|
128
|
+
return base64Standard.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
129
|
+
}
|
|
130
|
+
equals(other) {
|
|
131
|
+
return (this._storeIdHex === other._storeIdHex &&
|
|
132
|
+
this.chainName === other.chainName &&
|
|
133
|
+
(this._rootHashHex && other._rootHashHex
|
|
134
|
+
? this._rootHashHex === other._rootHashHex
|
|
135
|
+
: this._rootHashHex === other._rootHashHex) &&
|
|
136
|
+
this.resourceKey === other.resourceKey);
|
|
137
|
+
}
|
|
138
|
+
toString() {
|
|
139
|
+
return this.toUrn();
|
|
140
|
+
}
|
|
141
|
+
clone() {
|
|
142
|
+
return new Udi(this.chainName, this._storeIdHex, this._rootHashHex, this.resourceKey);
|
|
143
|
+
}
|
|
144
|
+
hashCode() {
|
|
145
|
+
const hash = (0, crypto_1.createHash)("sha256");
|
|
146
|
+
hash.update(this.toUrn());
|
|
147
|
+
return hash.digest("hex");
|
|
148
|
+
}
|
|
149
|
+
get storeId() {
|
|
150
|
+
return this._storeIdHex;
|
|
151
|
+
}
|
|
152
|
+
get rootHash() {
|
|
153
|
+
return this._rootHashHex;
|
|
154
|
+
}
|
|
155
|
+
get storeIdBase32() {
|
|
156
|
+
return this.formatBufferAsEncoding(this._storeIdHex, "base32");
|
|
157
|
+
}
|
|
158
|
+
get rootHashBase32() {
|
|
159
|
+
return this._rootHashHex ? this.formatBufferAsEncoding(this._rootHashHex, "base32") : null;
|
|
160
|
+
}
|
|
161
|
+
get storeIdBase64() {
|
|
162
|
+
return this.formatBufferAsEncoding(this._storeIdHex, "base64");
|
|
163
|
+
}
|
|
164
|
+
get rootHashBase64() {
|
|
165
|
+
return this._rootHashHex ? this.formatBufferAsEncoding(this._rootHashHex, "base64") : null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
exports.Udi = Udi;
|
|
169
|
+
Udi.nid = "dig";
|
|
170
|
+
Udi.namespace = `urn:${Udi.nid}`;
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { DigConfig } from "../types";
|
|
2
2
|
export declare const NETWORK_AGG_SIG_DATA = "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb";
|
|
3
|
+
export declare const MAIN_NET_GENISES_CHALLENGE = "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb";
|
|
3
4
|
export declare const MIN_HEIGHT = 5777842;
|
|
4
5
|
export declare const MIN_HEIGHT_HEADER_HASH = "b29a4daac2434fd17a36e15ba1aac5d65012d4a66f99bed0bf2b5342e92e562c";
|
|
5
6
|
export declare const DIG_FOLDER_PATH: string;
|
|
6
7
|
export declare const STORE_PATH: string;
|
|
7
8
|
export declare const USER_DIR_PATH: string;
|
|
8
9
|
export declare const CONFIG_FILE_PATH: string;
|
|
9
|
-
export declare const getManifestFilePath: (storeId: string) => string;
|
|
10
10
|
export declare const getHeightFilePath: (storeId: string) => string;
|
|
11
11
|
export declare const createInitialConfig: () => void;
|
|
12
12
|
export declare const setRemote: (remote: string) => void;
|
|
@@ -20,9 +20,10 @@ export declare const getCoinState: (storeId: string) => {
|
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
|
-
* Retrieves
|
|
23
|
+
* Retrieves the list of valid store folders.
|
|
24
|
+
* If the STORE_PATH directory does not exist, it is created.
|
|
24
25
|
*
|
|
25
|
-
* @returns {string[]} An array of valid folder names.
|
|
26
|
+
* @returns {string[]} An array of valid store folder names.
|
|
26
27
|
*/
|
|
27
28
|
export declare const getStoresList: () => string[];
|
|
28
29
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAMrC,eAAO,MAAM,oBAAoB,qEACmC,CAAC;AAErE,eAAO,MAAM,0BAA0B,qEAAuB,CAAC;AAE/D,eAAO,MAAM,UAAU,UAAU,CAAC;AAClC,eAAO,MAAM,sBAAsB,qEACiC,CAAC;AAErE,eAAO,MAAM,eAAe,QACqC,CAAC;AAElE,eAAO,MAAM,UAAU,QAAuC,CAAC;AAE/D,eAAO,MAAM,aAAa,QAAkC,CAAC;AAC7D,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAE9E,eAAO,MAAM,iBAAiB,YAAa,MAAM,KAAG,MACL,CAAC;AAEhD,eAAO,MAAM,mBAAmB,QAAO,IAItC,CAAC;AAEF,eAAO,MAAM,SAAS,WAAY,MAAM,KAAG,IAQ1C,CAAC;AAEF,eAAO,MAAM,cAAc,YAAa,MAAM,KAAG,IAQhD,CAAC;AAqBF,eAAO,MAAM,YAAY,YACd,MAAM,KACd;IACD,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CAYH,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,MAAM,EAYtC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,MAAM,GAAG,IAAI,CAkC9D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,YAAa,MAAM,KAAG,SAS/C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,YAAa,MAAM,KAAG,SAoBjD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,YACjB,MAAM,OACV,MAAM,SACJ,GAAG,KACT,IAMF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAAa,MAAM,OAAO,MAAM,KAAG,IAcjE,CAAC"}
|
package/dist/utils/config.js
CHANGED
|
@@ -26,20 +26,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.deleteDigConfigKey = exports.setDigConfigKey = exports.ensureDigConfig = exports.loadDigConfig = exports.getActiveStoreId = exports.getStoresList = exports.getCoinState = exports.setActiveStore = exports.setRemote = exports.createInitialConfig = exports.getHeightFilePath = exports.
|
|
29
|
+
exports.deleteDigConfigKey = exports.setDigConfigKey = exports.ensureDigConfig = exports.loadDigConfig = exports.getActiveStoreId = exports.getStoresList = exports.getCoinState = exports.setActiveStore = exports.setRemote = exports.createInitialConfig = exports.getHeightFilePath = exports.CONFIG_FILE_PATH = exports.USER_DIR_PATH = exports.STORE_PATH = exports.DIG_FOLDER_PATH = exports.MIN_HEIGHT_HEADER_HASH = exports.MIN_HEIGHT = exports.MAIN_NET_GENISES_CHALLENGE = exports.NETWORK_AGG_SIG_DATA = void 0;
|
|
30
30
|
const fs = __importStar(require("fs"));
|
|
31
31
|
const path = __importStar(require("path"));
|
|
32
32
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
33
33
|
const os_1 = __importDefault(require("os"));
|
|
34
|
+
const Environment_1 = require("./Environment");
|
|
34
35
|
exports.NETWORK_AGG_SIG_DATA = "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb";
|
|
36
|
+
exports.MAIN_NET_GENISES_CHALLENGE = exports.NETWORK_AGG_SIG_DATA;
|
|
35
37
|
exports.MIN_HEIGHT = 5777842;
|
|
36
38
|
exports.MIN_HEIGHT_HEADER_HASH = "b29a4daac2434fd17a36e15ba1aac5d65012d4a66f99bed0bf2b5342e92e562c";
|
|
37
|
-
exports.DIG_FOLDER_PATH =
|
|
39
|
+
exports.DIG_FOLDER_PATH = Environment_1.Environment.DIG_FOLDER_PATH || path.join(process.cwd(), ".dig");
|
|
38
40
|
exports.STORE_PATH = path.join(exports.DIG_FOLDER_PATH, "stores");
|
|
39
41
|
exports.USER_DIR_PATH = path.join(os_1.default.homedir(), ".dig");
|
|
40
42
|
exports.CONFIG_FILE_PATH = path.join(exports.DIG_FOLDER_PATH, "dig.config.json");
|
|
41
|
-
const getManifestFilePath = (storeId) => path.join(exports.STORE_PATH, storeId, "manifest.dat");
|
|
42
|
-
exports.getManifestFilePath = getManifestFilePath;
|
|
43
43
|
const getHeightFilePath = (storeId) => path.join(exports.STORE_PATH, storeId, "height.json");
|
|
44
44
|
exports.getHeightFilePath = getHeightFilePath;
|
|
45
45
|
const createInitialConfig = () => {
|
|
@@ -82,7 +82,7 @@ const promptUserForSelection = async (options) => {
|
|
|
82
82
|
return answer.selectedStore;
|
|
83
83
|
};
|
|
84
84
|
const getCoinState = (storeId) => {
|
|
85
|
-
const stateFile = path.join(exports.
|
|
85
|
+
const stateFile = path.join(exports.USER_DIR_PATH, `${storeId}.json`);
|
|
86
86
|
if (!fs.existsSync(stateFile)) {
|
|
87
87
|
return {
|
|
88
88
|
metadata: { rootHash: "", bytes: "", label: "", description: "" },
|
|
@@ -94,11 +94,16 @@ const getCoinState = (storeId) => {
|
|
|
94
94
|
};
|
|
95
95
|
exports.getCoinState = getCoinState;
|
|
96
96
|
/**
|
|
97
|
-
* Retrieves
|
|
97
|
+
* Retrieves the list of valid store folders.
|
|
98
|
+
* If the STORE_PATH directory does not exist, it is created.
|
|
98
99
|
*
|
|
99
|
-
* @returns {string[]} An array of valid folder names.
|
|
100
|
+
* @returns {string[]} An array of valid store folder names.
|
|
100
101
|
*/
|
|
101
102
|
const getStoresList = () => {
|
|
103
|
+
// Check if the STORE_PATH exists, create it if not
|
|
104
|
+
if (!fs.existsSync(exports.STORE_PATH)) {
|
|
105
|
+
fs.mkdirSync(exports.STORE_PATH, { recursive: true });
|
|
106
|
+
}
|
|
102
107
|
const folders = fs.readdirSync(exports.STORE_PATH);
|
|
103
108
|
return folders.filter((folder) => /^[a-f0-9]{64}$/.test(folder) &&
|
|
104
109
|
fs.lstatSync(path.join(exports.STORE_PATH, folder)).isDirectory());
|
|
@@ -123,7 +128,7 @@ const getActiveStoreId = async () => {
|
|
|
123
128
|
return Buffer.from(config.active_store, "hex");
|
|
124
129
|
}
|
|
125
130
|
const validFolders = (0, exports.getStoresList)();
|
|
126
|
-
if (validFolders.length === 1 ||
|
|
131
|
+
if (validFolders.length === 1 || Environment_1.Environment.REMOTE_NODE) {
|
|
127
132
|
// If only one valid folder exists, set it as the active_store and return it
|
|
128
133
|
config.active_store = validFolders[0];
|
|
129
134
|
fs.writeFileSync(configFilePath, JSON.stringify(config, null, 4));
|
|
@@ -6,4 +6,20 @@ export declare const addDirectory: (datalayer: DataIntegrityTree, dirPath: strin
|
|
|
6
6
|
* @returns The total size of the folder in bytes.
|
|
7
7
|
*/
|
|
8
8
|
export declare const calculateFolderSize: (folderPath: string) => bigint;
|
|
9
|
+
/**
|
|
10
|
+
* Represents the result of listing files.
|
|
11
|
+
* - If `groupSize` is not provided, returns an array of relative file paths.
|
|
12
|
+
* - If `groupSize` is provided, returns an array of arrays, each containing up to `groupSize` file paths.
|
|
13
|
+
*/
|
|
14
|
+
type ListFilesResult = string[] | string[][];
|
|
15
|
+
/**
|
|
16
|
+
* Recursively lists all files in a directory, excluding specified folders and respecting `.gitignore` rules.
|
|
17
|
+
* Optionally groups the list into batches of a specified size.
|
|
18
|
+
*
|
|
19
|
+
* @param {string} baseDir - The base directory path to start listing files from.
|
|
20
|
+
* @param {number} [groupSize] - Optional. The number of files per group. If provided, the result will be an array of arrays.
|
|
21
|
+
* @returns {ListFilesResult} - A flat list of relative file paths or grouped lists based on `groupSize`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function listFilesRecursively(baseDir: string, groupSize?: number): ListFilesResult;
|
|
24
|
+
export {};
|
|
9
25
|
//# sourceMappingURL=directoryUtils.d.ts.map
|
|
@@ -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;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"}
|
|
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;AAEF;;;;GAIG;AACH,KAAK,eAAe,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC;AAE7C;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,CAiEjB"}
|
|
@@ -27,6 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.calculateFolderSize = exports.addDirectory = void 0;
|
|
30
|
+
exports.listFilesRecursively = listFilesRecursively;
|
|
30
31
|
const path = __importStar(require("path"));
|
|
31
32
|
const fs = __importStar(require("fs"));
|
|
32
33
|
const ignore_1 = __importDefault(require("ignore"));
|
|
@@ -108,3 +109,68 @@ const calculateFolderSize = (folderPath) => {
|
|
|
108
109
|
return totalSize;
|
|
109
110
|
};
|
|
110
111
|
exports.calculateFolderSize = calculateFolderSize;
|
|
112
|
+
/**
|
|
113
|
+
* Recursively lists all files in a directory, excluding specified folders and respecting `.gitignore` rules.
|
|
114
|
+
* Optionally groups the list into batches of a specified size.
|
|
115
|
+
*
|
|
116
|
+
* @param {string} baseDir - The base directory path to start listing files from.
|
|
117
|
+
* @param {number} [groupSize] - Optional. The number of files per group. If provided, the result will be an array of arrays.
|
|
118
|
+
* @returns {ListFilesResult} - A flat list of relative file paths or grouped lists based on `groupSize`.
|
|
119
|
+
*/
|
|
120
|
+
function listFilesRecursively(baseDir, groupSize) {
|
|
121
|
+
// Initialize the ignore instance
|
|
122
|
+
const ig = (0, ignore_1.default)();
|
|
123
|
+
// Path to .gitignore
|
|
124
|
+
const gitignorePath = path.join(baseDir, ".gitignore");
|
|
125
|
+
// Load and parse .gitignore if it exists
|
|
126
|
+
if (fs.existsSync(gitignorePath)) {
|
|
127
|
+
const gitignoreContent = fs.readFileSync(gitignorePath, "utf-8");
|
|
128
|
+
ig.add(gitignoreContent);
|
|
129
|
+
}
|
|
130
|
+
// Initialize result containers
|
|
131
|
+
const allFiles = [];
|
|
132
|
+
let groupedFiles = [];
|
|
133
|
+
/**
|
|
134
|
+
* Recursively traverses directories to collect files.
|
|
135
|
+
*
|
|
136
|
+
* @param {string} currentDir - The current directory path being traversed.
|
|
137
|
+
*/
|
|
138
|
+
function traverseDirectory(currentDir) {
|
|
139
|
+
let entries;
|
|
140
|
+
try {
|
|
141
|
+
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
console.error(`Failed to read directory: ${currentDir}. Error: ${err.message}`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
for (const entry of entries) {
|
|
148
|
+
const entryName = entry.name;
|
|
149
|
+
const fullPath = path.join(currentDir, entryName);
|
|
150
|
+
const relativePath = path.relative(baseDir, fullPath).replace(/\\/g, "/"); // Normalize to forward slashes
|
|
151
|
+
// Skip .git and .dig directories and any ignored paths
|
|
152
|
+
if (entryName === ".git" || entryName === ".dig" || ig.ignores(relativePath)) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (entry.isDirectory()) {
|
|
156
|
+
traverseDirectory(fullPath); // Recurse into subdirectory
|
|
157
|
+
}
|
|
158
|
+
else if (entry.isFile()) {
|
|
159
|
+
allFiles.push(relativePath);
|
|
160
|
+
}
|
|
161
|
+
// Optionally handle symbolic links or other types if needed
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Start traversal from the base directory
|
|
165
|
+
traverseDirectory(baseDir);
|
|
166
|
+
// If groupSize is provided and valid, group the files accordingly
|
|
167
|
+
if (groupSize && Number.isInteger(groupSize) && groupSize > 0) {
|
|
168
|
+
groupedFiles = [];
|
|
169
|
+
for (let i = 0; i < allFiles.length; i += groupSize) {
|
|
170
|
+
groupedFiles.push(allFiles.slice(i, i + groupSize));
|
|
171
|
+
}
|
|
172
|
+
return groupedFiles;
|
|
173
|
+
}
|
|
174
|
+
// Return the flat list of files if grouping is not required
|
|
175
|
+
return allFiles;
|
|
176
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export * from './config';
|
|
2
2
|
export * from './connectionUtils';
|
|
3
3
|
export * from './credentialsUtils';
|
|
4
|
-
export * from './deltaUtils';
|
|
5
4
|
export * from './directoryUtils';
|
|
6
5
|
export * from './encryption';
|
|
7
6
|
export * from './FileCache';
|
|
@@ -11,4 +10,9 @@ export * from './network';
|
|
|
11
10
|
export * from './spinnerUtils';
|
|
12
11
|
export * from './ssl';
|
|
13
12
|
export * from './validationUtils';
|
|
13
|
+
export * from './Environment';
|
|
14
|
+
export * from './promiseUtils';
|
|
15
|
+
export * from './PeerRanker';
|
|
16
|
+
export * from './DigCache';
|
|
17
|
+
export * from './Udi';
|
|
14
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC"}
|
package/dist/utils/index.js
CHANGED
|
@@ -17,7 +17,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./config"), exports);
|
|
18
18
|
__exportStar(require("./connectionUtils"), exports);
|
|
19
19
|
__exportStar(require("./credentialsUtils"), exports);
|
|
20
|
-
__exportStar(require("./deltaUtils"), exports);
|
|
21
20
|
__exportStar(require("./directoryUtils"), exports);
|
|
22
21
|
__exportStar(require("./encryption"), exports);
|
|
23
22
|
__exportStar(require("./FileCache"), exports);
|
|
@@ -27,3 +26,8 @@ __exportStar(require("./network"), exports);
|
|
|
27
26
|
__exportStar(require("./spinnerUtils"), exports);
|
|
28
27
|
__exportStar(require("./ssl"), exports);
|
|
29
28
|
__exportStar(require("./validationUtils"), exports);
|
|
29
|
+
__exportStar(require("./Environment"), exports);
|
|
30
|
+
__exportStar(require("./promiseUtils"), exports);
|
|
31
|
+
__exportStar(require("./PeerRanker"), exports);
|
|
32
|
+
__exportStar(require("./DigCache"), exports);
|
|
33
|
+
__exportStar(require("./Udi"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merkle.d.ts","sourceRoot":"","sources":["../../src/utils/merkle.ts"],"names":[],"mappings":"AAIA,wBAAsB,oBAAoB,CACtC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CA6BlB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.merkleIntegrityCheck = merkleIntegrityCheck;
|
|
7
|
+
const DataIntegrityTree_1 = require("../DataIntegrityTree");
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
async function merkleIntegrityCheck(treePath, tmpDir, dataPath, roothash) {
|
|
11
|
+
const rootHashContent = fs_1.default.readFileSync(treePath, "utf-8");
|
|
12
|
+
const tree = JSON.parse(rootHashContent);
|
|
13
|
+
// Extract expected sha256 from dataPath
|
|
14
|
+
const expectedSha256 = dataPath.replace("data", "").replace(/\//g, "");
|
|
15
|
+
console.log("expectedSha256", expectedSha256);
|
|
16
|
+
// Find the hexKey in the tree based on matching sha256
|
|
17
|
+
const hexKey = Object.keys(tree.files).find((key) => {
|
|
18
|
+
const fileData = tree.files[key]; // Inline type definition
|
|
19
|
+
return fileData.sha256 === expectedSha256;
|
|
20
|
+
});
|
|
21
|
+
if (!hexKey) {
|
|
22
|
+
throw new Error(`No matching file found with sha256: ${expectedSha256}`);
|
|
23
|
+
}
|
|
24
|
+
// Validate the integrity with the foreign tree
|
|
25
|
+
const integrity = await DataIntegrityTree_1.DataIntegrityTree.validateKeyIntegrityWithForeignTree(hexKey, expectedSha256, tree, roothash, path_1.default.join(tmpDir, "data"));
|
|
26
|
+
console.log("Integrity check result:", integrity);
|
|
27
|
+
return integrity;
|
|
28
|
+
}
|
package/dist/utils/network.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/utils/network.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/utils/network.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,MAAM,GAAG,SAAS,CA+ChE,CAAC;AAIF,eAAO,MAAM,UAAU,SAAU,MAAM,KAAG,MAUzC,CAAC"}
|
package/dist/utils/network.js
CHANGED
|
@@ -3,36 +3,61 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.formatHost = exports.getPublicHost = void 0;
|
|
7
7
|
const superagent_1 = __importDefault(require("superagent"));
|
|
8
8
|
const MAX_RETRIES = 5;
|
|
9
9
|
const RETRY_DELAY = 2000; // in milliseconds
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
// Regular expression for validating both IPv4 and IPv6 addresses
|
|
11
|
+
const ipv4Regex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
12
|
+
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)|(([0-9a-fA-F]{1,7}|:):){1,7}([0-9a-fA-F]{1,4}|:))$/;
|
|
13
|
+
// Regular expression for validating hostnames
|
|
14
|
+
const hostnameRegex = /^(([a-zA-Z0-9](-*[a-zA-Z0-9])*)\.)*[a-zA-Z]{2,}$/;
|
|
15
|
+
// Helper function to validate the IP address or hostname
|
|
16
|
+
const isValidHost = (host) => {
|
|
17
|
+
return ipv4Regex.test(host) || ipv6Regex.test(host) || hostnameRegex.test(host);
|
|
18
|
+
};
|
|
19
|
+
const getPublicHost = async () => {
|
|
20
|
+
const publicHost = process.env.PUBLIC_IP;
|
|
21
|
+
if (publicHost) {
|
|
22
|
+
console.log("Public IP/Hostname from env:", publicHost);
|
|
23
|
+
if (isValidHost(publicHost)) {
|
|
24
|
+
return publicHost;
|
|
25
|
+
}
|
|
26
|
+
console.error("Invalid public IP/Hostname in environment variable");
|
|
27
|
+
return undefined;
|
|
15
28
|
}
|
|
16
29
|
let attempt = 0;
|
|
17
30
|
while (attempt < MAX_RETRIES) {
|
|
18
31
|
try {
|
|
19
|
-
const response = await superagent_1.default.get(
|
|
32
|
+
const response = await superagent_1.default.get("https://api.datalayer.storage/user/v1/get_user_ip");
|
|
20
33
|
if (response.body && response.body.success) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
throw new Error(
|
|
34
|
+
const ipAddress = response.body.ip_address;
|
|
35
|
+
if (isValidHost(ipAddress)) {
|
|
36
|
+
return ipAddress;
|
|
37
|
+
}
|
|
38
|
+
throw new Error("Invalid IP address or hostname format received");
|
|
26
39
|
}
|
|
40
|
+
throw new Error("Failed to retrieve public host");
|
|
27
41
|
}
|
|
28
42
|
catch (error) {
|
|
29
43
|
attempt++;
|
|
30
|
-
console.error(`Error fetching public
|
|
44
|
+
console.error(`Error fetching public host (Attempt ${attempt}):`, error.message);
|
|
31
45
|
if (attempt >= MAX_RETRIES) {
|
|
32
|
-
throw new Error(
|
|
46
|
+
throw new Error("Could not retrieve public host after several attempts");
|
|
33
47
|
}
|
|
34
48
|
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY));
|
|
35
49
|
}
|
|
36
50
|
}
|
|
37
51
|
};
|
|
38
|
-
exports.
|
|
52
|
+
exports.getPublicHost = getPublicHost;
|
|
53
|
+
// Helper function to wrap IPv6 addresses in brackets
|
|
54
|
+
const formatHost = (host) => {
|
|
55
|
+
const ipv6Pattern = /^[a-fA-F0-9:]+$/; // Simple regex to match raw IPv6 addresses (without brackets)
|
|
56
|
+
const hasBrackets = /^\[.*\]$/; // Regex to check if the address already has brackets
|
|
57
|
+
// If it's an IPv6 address without brackets, add them
|
|
58
|
+
if (ipv6Pattern.test(host) && !hasBrackets.test(host)) {
|
|
59
|
+
return `[${host}]`;
|
|
60
|
+
}
|
|
61
|
+
return host; // Return the host as is (IPv4, hostname, or already bracketed IPv6)
|
|
62
|
+
};
|
|
63
|
+
exports.formatHost = formatHost;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Processes items in sequential batches with a concurrency limit.
|
|
3
|
+
* Adds a cooldown between batches.
|
|
4
|
+
* @param {number} limit - The maximum number of concurrent executions per batch.
|
|
5
|
+
* @param {Array<T>} items - The array of items to process.
|
|
6
|
+
* @param {(item: T) => Promise<R>} iteratorFn - The async function to apply to each item.
|
|
7
|
+
* @param {number} cooldownMs - The cooldown duration between batches in milliseconds.
|
|
8
|
+
* @returns {Promise<Array<R>>} - A promise that resolves when all items have been processed.
|
|
9
|
+
*/
|
|
10
|
+
export declare function asyncPool<T, R>(limit: number, items: T[], iteratorFn: (item: T) => Promise<R>, cooldownMs?: number): Promise<R[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Helper function to add a timeout to a promise.
|
|
13
|
+
* @param promise The original promise.
|
|
14
|
+
* @param ms Timeout in milliseconds.
|
|
15
|
+
* @param timeoutMessage The error message when the timeout is reached.
|
|
16
|
+
* @returns Promise that resolves before the timeout or rejects with an error.
|
|
17
|
+
*/
|
|
18
|
+
export declare const withTimeout: <T>(promise: Promise<T>, ms: number, timeoutMessage: string) => Promise<T>;
|
|
19
|
+
/**
|
|
20
|
+
* Wraps a promise to execute a callback every 30 seconds while the promise is pending.
|
|
21
|
+
*
|
|
22
|
+
* @param {Promise<T>} promise - The promise to wrap.
|
|
23
|
+
* @param {() => void} callback - The callback function to call every 30 seconds.
|
|
24
|
+
* @returns {Promise<T>} - A new promise that resolves or rejects with the original promise's result.
|
|
25
|
+
*/
|
|
26
|
+
export declare const withIntervalCallback: <T>(promise: Promise<T>, callback: () => void) => Promise<T>;
|
|
27
|
+
//# sourceMappingURL=promiseUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promiseUtils.d.ts","sourceRoot":"","sources":["../../src/utils/promiseUtils.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,CAAC,EAClC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,CAAC,EAAE,EACV,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EACnC,UAAU,GAAE,MAAY,GACvB,OAAO,CAAC,CAAC,EAAE,CAAC,CAkBd;AACC;;;;;;EAMC;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,WAClB,OAAO,CAAC,CAAC,CAAC,MACf,MAAM,kBACM,MAAM,KACrB,OAAO,CAAC,CAAC,CAOX,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,WAC3B,OAAO,CAAC,CAAC,CAAC,YACT,MAAM,IAAI,KACnB,OAAO,CAAC,CAAC,CAoBX,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withIntervalCallback = exports.withTimeout = void 0;
|
|
4
|
+
exports.asyncPool = asyncPool;
|
|
5
|
+
/**
|
|
6
|
+
* Processes items in sequential batches with a concurrency limit.
|
|
7
|
+
* Adds a cooldown between batches.
|
|
8
|
+
* @param {number} limit - The maximum number of concurrent executions per batch.
|
|
9
|
+
* @param {Array<T>} items - The array of items to process.
|
|
10
|
+
* @param {(item: T) => Promise<R>} iteratorFn - The async function to apply to each item.
|
|
11
|
+
* @param {number} cooldownMs - The cooldown duration between batches in milliseconds.
|
|
12
|
+
* @returns {Promise<Array<R>>} - A promise that resolves when all items have been processed.
|
|
13
|
+
*/
|
|
14
|
+
async function asyncPool(limit, items, iteratorFn, cooldownMs = 500 // Default cooldown of 500ms
|
|
15
|
+
) {
|
|
16
|
+
const ret = [];
|
|
17
|
+
for (let i = 0; i < items.length; i += limit) {
|
|
18
|
+
const batchItems = items.slice(i, i + limit);
|
|
19
|
+
const batchPromises = batchItems.map((item) => iteratorFn(item));
|
|
20
|
+
// Wait for the current batch to complete before starting the next one
|
|
21
|
+
const batchResults = await Promise.all(batchPromises);
|
|
22
|
+
ret.push(...batchResults);
|
|
23
|
+
// Add a cooldown between batches, except after the last batch
|
|
24
|
+
if (i + limit < items.length) {
|
|
25
|
+
await new Promise((resolve) => setTimeout(resolve, cooldownMs));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return ret;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Helper function to add a timeout to a promise.
|
|
32
|
+
* @param promise The original promise.
|
|
33
|
+
* @param ms Timeout in milliseconds.
|
|
34
|
+
* @param timeoutMessage The error message when the timeout is reached.
|
|
35
|
+
* @returns Promise that resolves before the timeout or rejects with an error.
|
|
36
|
+
*/
|
|
37
|
+
const withTimeout = (promise, ms, timeoutMessage) => {
|
|
38
|
+
return Promise.race([
|
|
39
|
+
promise,
|
|
40
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(timeoutMessage)), ms)),
|
|
41
|
+
]);
|
|
42
|
+
};
|
|
43
|
+
exports.withTimeout = withTimeout;
|
|
44
|
+
/**
|
|
45
|
+
* Wraps a promise to execute a callback every 30 seconds while the promise is pending.
|
|
46
|
+
*
|
|
47
|
+
* @param {Promise<T>} promise - The promise to wrap.
|
|
48
|
+
* @param {() => void} callback - The callback function to call every 30 seconds.
|
|
49
|
+
* @returns {Promise<T>} - A new promise that resolves or rejects with the original promise's result.
|
|
50
|
+
*/
|
|
51
|
+
const withIntervalCallback = (promise, callback) => {
|
|
52
|
+
const intervalTime = 30000; // 30 seconds in milliseconds
|
|
53
|
+
let intervalId;
|
|
54
|
+
// Start the interval that calls the callback every 30 seconds
|
|
55
|
+
intervalId = setInterval(() => {
|
|
56
|
+
callback();
|
|
57
|
+
}, intervalTime);
|
|
58
|
+
// Return a new promise that clears the interval when the original promise settles
|
|
59
|
+
return promise
|
|
60
|
+
.then((result) => {
|
|
61
|
+
clearInterval(intervalId);
|
|
62
|
+
return result;
|
|
63
|
+
})
|
|
64
|
+
.catch((error) => {
|
|
65
|
+
clearInterval(intervalId);
|
|
66
|
+
throw error;
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
exports.withIntervalCallback = withIntervalCallback;
|