@trap_stevo/filetide 0.0.51 → 0.0.53
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/cjs/FileMessager.js +71 -27
- package/dist/cjs/FileMessagerClient.js +16 -12
- package/dist/cjs/FileTide.js +80 -36
- package/dist/cjs/HUDComponents/ConsoleProgressBarManager.js +21 -68
- package/dist/cjs/HUDManagers/FileNetClientManager.js +11 -0
- package/dist/cjs/HUDManagers/FileNetUtilityManager.js +60 -14
- package/dist/cjs/HUDManagers/FileTideDebugUtilityManager.js +73 -0
- package/dist/cjs/HUDManagers/FileTransferManager.js +17 -10
- package/dist/cjs/HUDManagers/FileTransferReceiverManager.js +30 -21
- package/dist/cjs/HUDManagers/FileTransferTrackingManager.js +84 -0
- package/package.json +3 -2
package/dist/cjs/FileMessager.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
|
|
4
|
+
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
5
|
+
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
|
3
6
|
const {
|
|
4
7
|
OmniMap
|
|
5
8
|
} = require("@trap_stevo/legendarybuilderpronodejs-utilities/HUDStructs");
|
|
@@ -7,6 +10,9 @@ const IoTide = require("@trap_stevo/iotide");
|
|
|
7
10
|
const {
|
|
8
11
|
FileMessagerConfigManager
|
|
9
12
|
} = require("./HUDManagers/FileMessagerConfigManager");
|
|
13
|
+
const {
|
|
14
|
+
FileNetUtilityManager
|
|
15
|
+
} = require("./HUDManagers/FileNetUtilityManager");
|
|
10
16
|
const {
|
|
11
17
|
FileNetClientManager
|
|
12
18
|
} = require("./HUDManagers/FileNetClientManager");
|
|
@@ -14,6 +20,7 @@ const {
|
|
|
14
20
|
FileTransferManager
|
|
15
21
|
} = require("./HUDManagers/FileTransferManager");
|
|
16
22
|
const HUDTargetQueue = require("./HUDManagers/HUDTargetQueueManager");
|
|
23
|
+
var _FileMessager_brand = /*#__PURE__*/new WeakSet();
|
|
17
24
|
class FileMessager {
|
|
18
25
|
constructor(options = {
|
|
19
26
|
pingTimeout: 3600000,
|
|
@@ -21,7 +28,8 @@ class FileMessager {
|
|
|
21
28
|
}, transportOptions = {
|
|
22
29
|
parallelChunks: 3,
|
|
23
30
|
maxRetries: 3
|
|
24
|
-
}) {
|
|
31
|
+
}, debugMode = false) {
|
|
32
|
+
_classPrivateMethodInitSpec(this, _FileMessager_brand);
|
|
25
33
|
const serverOptions = FileMessagerConfigManager.getServerOptions(options);
|
|
26
34
|
this.transporter = new FileTransferManager(transportOptions);
|
|
27
35
|
this.transferQueue = new HUDTargetQueue();
|
|
@@ -30,6 +38,7 @@ class FileMessager {
|
|
|
30
38
|
this.currentTidingTransfers = new Map();
|
|
31
39
|
this.fileNet = new IoTide(serverOptions.port, serverOptions, true, this.onConnect.bind(this), this.onDisconnect.bind(this));
|
|
32
40
|
this.onlineClients = new OmniMap();
|
|
41
|
+
this.debugMode = debugMode;
|
|
33
42
|
return;
|
|
34
43
|
}
|
|
35
44
|
onConnect(socket) {
|
|
@@ -46,6 +55,7 @@ class FileMessager {
|
|
|
46
55
|
this.fileNet.on("get-client-transfer-barrier-response", this.handleClientTransferBarrierResponse.bind(this));
|
|
47
56
|
this.fileNet.on("get-client-transfer-state", this.handleGetClientTransferState.bind(this));
|
|
48
57
|
this.fileNet.on("get-client", this.handleGetClient.bind(this));
|
|
58
|
+
this.fileNet.on("acknowledge-transfer-tide", this.handleAcknowledgeTransferTide.bind(this));
|
|
49
59
|
this.fileNet.on("notify-transfer-barrier", this.handleNotifyTransferBarrier.bind(this));
|
|
50
60
|
this.fileNet.on("send-current-transfer-state", this.handleSendCurrentTransferState.bind(this));
|
|
51
61
|
this.fileNet.on("sent-file-list-to-client", this.handleSentFileListToClient.bind(this));
|
|
@@ -121,11 +131,13 @@ class FileMessager {
|
|
|
121
131
|
path: filePath,
|
|
122
132
|
fileSize
|
|
123
133
|
});
|
|
124
|
-
|
|
134
|
+
_assertClassBrand(_FileMessager_brand, this, _log).call(this, `[FileTide ~ File Messager] ~ Sent chunk ${chunkIndex} of ${fileName} to client ~ ${clientData.userID}!`);
|
|
125
135
|
if (senderClient) {
|
|
126
136
|
this.fileNet.emitToTide(senderClient.tideID, "transfer-status", {
|
|
127
137
|
status: `Chunk ${chunkIndex} of ${fileName} sent to client ${clientData.userID}!`,
|
|
128
138
|
recipientID: clientData.userID,
|
|
139
|
+
senderName: senderData.userID,
|
|
140
|
+
senderID: senderData.id,
|
|
129
141
|
success: true,
|
|
130
142
|
fileName,
|
|
131
143
|
chunkIndex,
|
|
@@ -136,7 +148,7 @@ class FileMessager {
|
|
|
136
148
|
});
|
|
137
149
|
}
|
|
138
150
|
}
|
|
139
|
-
handleRequestTransferFromClient(transferData) {
|
|
151
|
+
handleRequestTransferFromClient(senderTide, transferData) {
|
|
140
152
|
const {
|
|
141
153
|
requesterID,
|
|
142
154
|
senderID,
|
|
@@ -145,7 +157,7 @@ class FileMessager {
|
|
|
145
157
|
} = transferData;
|
|
146
158
|
this.requestFromClient(requesterID, senderID, filePath, destinationPath);
|
|
147
159
|
}
|
|
148
|
-
handleSentFileListToClient(listData) {
|
|
160
|
+
handleSentFileListToClient(senderTide, listData) {
|
|
149
161
|
const {
|
|
150
162
|
totalItemsSent,
|
|
151
163
|
recipientID,
|
|
@@ -164,10 +176,11 @@ class FileMessager {
|
|
|
164
176
|
totalItemsSent
|
|
165
177
|
});
|
|
166
178
|
} catch (error) {
|
|
179
|
+
console.error(`[FileTide ~ Net Scanner] ~ `, error);
|
|
167
180
|
return;
|
|
168
181
|
}
|
|
169
182
|
}
|
|
170
|
-
handleSendFileListToClient(listData) {
|
|
183
|
+
handleSendFileListToClient(senderTide, listData) {
|
|
171
184
|
const {
|
|
172
185
|
listedFiles,
|
|
173
186
|
totalItems,
|
|
@@ -188,10 +201,11 @@ class FileMessager {
|
|
|
188
201
|
listedFiles
|
|
189
202
|
});
|
|
190
203
|
} catch (error) {
|
|
204
|
+
console.error(`[FileTide ~ Net Scanner] ~ `, error);
|
|
191
205
|
return;
|
|
192
206
|
}
|
|
193
207
|
}
|
|
194
|
-
handleListClientFiles(clientData) {
|
|
208
|
+
handleListClientFiles(senderTide, clientData) {
|
|
195
209
|
const {
|
|
196
210
|
requesterID,
|
|
197
211
|
recipientID,
|
|
@@ -211,10 +225,11 @@ class FileMessager {
|
|
|
211
225
|
depth
|
|
212
226
|
});
|
|
213
227
|
} catch (error) {
|
|
228
|
+
console.error(`[FileTide ~ Net Scanner] ~ `, error);
|
|
214
229
|
return;
|
|
215
230
|
}
|
|
216
231
|
}
|
|
217
|
-
handleClientToClientTransfer(transferData) {
|
|
232
|
+
handleClientToClientTransfer(senderTide, transferData) {
|
|
218
233
|
try {
|
|
219
234
|
const {
|
|
220
235
|
chunkBatch
|
|
@@ -233,7 +248,7 @@ class FileMessager {
|
|
|
233
248
|
completedChunks,
|
|
234
249
|
totalChunks
|
|
235
250
|
} = chunkData;
|
|
236
|
-
|
|
251
|
+
_assertClassBrand(_FileMessager_brand, this, _log).call(this, `[FileTide ~ File Messager] ~ Transferring file ~ ${fileName} | chunk ${chunkIndex + 1} >> ${completedChunks} of ${totalChunks} to client (${recipientId})`);
|
|
237
252
|
const recipientClient = FileNetClientManager.getOnlineClient(recipientId);
|
|
238
253
|
const senderClient = FileNetClientManager.getOnlineClient(senderID);
|
|
239
254
|
this.sendFileChunkToClient({
|
|
@@ -277,7 +292,7 @@ class FileMessager {
|
|
|
277
292
|
completedChunks,
|
|
278
293
|
totalChunks
|
|
279
294
|
} = transferData;
|
|
280
|
-
|
|
295
|
+
_assertClassBrand(_FileMessager_brand, this, _log).call(this, `[FileTide ~ File Messager] ~ Transferring file ~ ${fileName} | chunk ${chunkIndex + 1} >> ${completedChunks} of ${totalChunks} to client (${recipientId})`);
|
|
281
296
|
const recipientClient = FileNetClientManager.getOnlineClient(recipientId);
|
|
282
297
|
const senderClient = FileNetClientManager.getOnlineClient(senderID);
|
|
283
298
|
this.sendFileChunkToClient({
|
|
@@ -307,11 +322,11 @@ class FileMessager {
|
|
|
307
322
|
}
|
|
308
323
|
}
|
|
309
324
|
} catch (error) {
|
|
310
|
-
console.
|
|
325
|
+
console.error(`[FileTide ~ Net Transporter] ~ `, error);
|
|
311
326
|
return;
|
|
312
327
|
}
|
|
313
328
|
}
|
|
314
|
-
handleClientTransferBarrierResponse(data) {
|
|
329
|
+
handleClientTransferBarrierResponse(senderTide, data) {
|
|
315
330
|
console.log(`[FileTide ~ Net] Checking ${data.recipientID}'s transfer barrier for transfer ~ ${data.transferID}...`);
|
|
316
331
|
try {
|
|
317
332
|
const recipientConnectionID = FileNetClientManager.getOnlineClient(data.recipientID).id;
|
|
@@ -319,6 +334,7 @@ class FileMessager {
|
|
|
319
334
|
const senderClient = this.getClientFromID(senderConnectionID);
|
|
320
335
|
const client = this.getClientFromID(recipientConnectionID);
|
|
321
336
|
if (!client || !senderClient) {
|
|
337
|
+
console.log(`[FileTide ~ Net Barrier] ~ Both, recipient and sender connection authorization required.`);
|
|
322
338
|
return;
|
|
323
339
|
}
|
|
324
340
|
this.fileNet.emitToTide(client.tideID, "queue-incoming-transfer", {
|
|
@@ -341,18 +357,20 @@ class FileMessager {
|
|
|
341
357
|
...data
|
|
342
358
|
});
|
|
343
359
|
}).catch(error => {
|
|
344
|
-
console.error(error.message);
|
|
360
|
+
console.error(`[FileTide ~ Net Barrier] ~ ${error.message}`);
|
|
345
361
|
});
|
|
346
362
|
return;
|
|
347
363
|
} catch (error) {
|
|
364
|
+
console.error(`[FileTide ~ Net Barrier] ~ `, error);
|
|
348
365
|
return;
|
|
349
366
|
}
|
|
350
367
|
}
|
|
351
|
-
handleSendCurrentTransferState(data) {
|
|
368
|
+
handleSendCurrentTransferState(senderTide, data) {
|
|
352
369
|
try {
|
|
353
370
|
const senderConnectionID = FileNetClientManager.getOnlineClient(data.senderID).id;
|
|
354
371
|
const senderClient = this.getClientFromID(senderConnectionID);
|
|
355
372
|
if (!senderClient) {
|
|
373
|
+
console.log(`[FileTide ~ Net Transfers] ~ Sender ~ ${senderConnectionID.truncate(0, senderConnectionID.length / 2)}... not found.`);
|
|
356
374
|
return;
|
|
357
375
|
}
|
|
358
376
|
this.fileNet.emitToTide(senderClient.tideID, "sent-current-transfer-state", data.transferState || {
|
|
@@ -360,10 +378,11 @@ class FileMessager {
|
|
|
360
378
|
lastChunkSent: 0
|
|
361
379
|
});
|
|
362
380
|
} catch (error) {
|
|
381
|
+
console.error(`[FileTide ~ Net Transfers] ~ `, error);
|
|
363
382
|
return;
|
|
364
383
|
}
|
|
365
384
|
}
|
|
366
|
-
handleGetClientTransferState(data) {
|
|
385
|
+
handleGetClientTransferState(senderTide, data) {
|
|
367
386
|
const filePath = data.filePath || data.path;
|
|
368
387
|
console.log(`[FileTide ~ Net] ~ Getting ${data.recipientID}'s transfer state for ~ ${filePath}...`);
|
|
369
388
|
try {
|
|
@@ -378,10 +397,11 @@ class FileMessager {
|
|
|
378
397
|
filePath
|
|
379
398
|
});
|
|
380
399
|
} catch (error) {
|
|
400
|
+
console.error(`[FileTide ~ Net Transfers] ~ `, error);
|
|
381
401
|
return;
|
|
382
402
|
}
|
|
383
403
|
}
|
|
384
|
-
handleGetClient(data) {
|
|
404
|
+
handleGetClient(senderTide, data) {
|
|
385
405
|
console.log(`[FileTide ~ Net] ~ Getting client ~ ${data.clientID}...`);
|
|
386
406
|
try {
|
|
387
407
|
const senderConnectionID = FileNetClientManager.getOnlineClient(data.senderID).id;
|
|
@@ -394,15 +414,23 @@ class FileMessager {
|
|
|
394
414
|
console.log(`[FileTide ~ Net] Got client ~ ${data.clientID}!`);
|
|
395
415
|
this.fileNet.emitToTide(senderClient.tideID, "retrieved-current-client", client);
|
|
396
416
|
} catch (error) {
|
|
417
|
+
console.error(`[FileTide ~ Net Activity] ~ `, error);
|
|
397
418
|
return;
|
|
398
419
|
}
|
|
399
420
|
}
|
|
400
|
-
|
|
421
|
+
handleAcknowledgeTransferTide(senderTide, data) {
|
|
422
|
+
try {
|
|
423
|
+
console.log(`[FileTide ~ Net Activity] ~ ${data.recipientName} acknowledged tide transfer from ${data.senderName}.\n\n\t~ [${data.fileName}-${data.transferStats.startTime}] ~\n\n\t\tFile Name ~ ${data.fileName}\n\t\tDestination ~ ${data.path}\n\n\t\t\tProgress ~ ${data.transferStats.progress.toFixed(2)}%\n\t\t\tETA ~ ${data.transferStats.timeLeft <= 0 ? "Now" : FileNetUtilityManager.convertSeconds(data.transferStats.timeLeft.toFixed(2))}\n\t\t\tSpeed ~ ${FileNetUtilityManager.getFormattedSize(data.transferStats.speed, true)}/s\n\t\t\tSize ~ ${FileNetUtilityManager.getFormattedSize(data.transferStats.totalSize, true)}\n\t\t\tTransferred ~ ${FileNetUtilityManager.getFormattedSize(data.transferStats.current, true)}\n`);
|
|
424
|
+
} catch (error) {
|
|
425
|
+
console.error(`[FileTide ~ Net Activity] ~ ${data.recipientName} acknowledged tide transfer from ${data.senderName}.\n\n${error}`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
handleNotifyTransferBarrier(senderTide, data, emitToChannel) {
|
|
401
429
|
const accepted = data.accepted;
|
|
402
430
|
const transferID = data.data.transferID;
|
|
403
431
|
this.currentTransferBarrierTransfers.set(transferID, accepted);
|
|
404
432
|
}
|
|
405
|
-
handleFileTransferStart(data, emitToChannel) {
|
|
433
|
+
handleFileTransferStart(senderTide, data, emitToChannel) {
|
|
406
434
|
console.log(`[FileTide ~ File Messager] ~ Alerting client of incoming transfer from ${data.senderID}...`);
|
|
407
435
|
try {
|
|
408
436
|
const recipientConnectionID = FileNetClientManager.getOnlineClient(data.recipientID).id;
|
|
@@ -417,7 +445,7 @@ class FileMessager {
|
|
|
417
445
|
...data,
|
|
418
446
|
currentSender: data.senderID
|
|
419
447
|
});
|
|
420
|
-
if (!this.currentTidingTransfers.get(senderID) || this.currentTidingTransfers.get(senderID).length <= 0) {
|
|
448
|
+
if (!this.currentTidingTransfers.get(data.senderID) || this.currentTidingTransfers.get(data.senderID).length <= 0) {
|
|
421
449
|
const tidingTransfers = new Map();
|
|
422
450
|
tidingTransfers.set(data.recipientID, {
|
|
423
451
|
recipientID: data.recipientID,
|
|
@@ -428,23 +456,24 @@ class FileMessager {
|
|
|
428
456
|
this.currentTidingTransfers.set(data.senderID, tidingTransfers);
|
|
429
457
|
return;
|
|
430
458
|
}
|
|
431
|
-
this.currentTidingTransfers.get(senderID).set(data.recipientID, {
|
|
459
|
+
this.currentTidingTransfers.get(data.senderID).set(data.recipientID, {
|
|
432
460
|
recipientID: data.recipientID,
|
|
433
461
|
startedOn: new Date(),
|
|
434
462
|
size: data.fileSize,
|
|
435
463
|
path: data.path
|
|
436
464
|
});
|
|
437
465
|
} catch (error) {
|
|
466
|
+
console.error(`[FileTide ~ Net Transfers] ~ `, error);
|
|
438
467
|
return;
|
|
439
468
|
}
|
|
440
469
|
}
|
|
441
|
-
handleFileTransferProgress(data, emitToChannel) {
|
|
470
|
+
handleFileTransferProgress(senderTide, data, emitToChannel) {
|
|
442
471
|
console.log(`Progress: ${data.progress}`);
|
|
443
472
|
}
|
|
444
|
-
handleFileTransferComplete(data) {
|
|
473
|
+
handleFileTransferComplete(senderTide, data) {
|
|
445
474
|
console.log(`File transfer completed: ${data.fileName}`);
|
|
446
475
|
}
|
|
447
|
-
handleCheckClientOnline(data) {
|
|
476
|
+
handleCheckClientOnline(senderTide, data) {
|
|
448
477
|
console.log(`[FileTide ~ Net Activity] ~ Checking if client ~ ${data.clientID} online...`);
|
|
449
478
|
try {
|
|
450
479
|
const client = FileNetClientManager.getOnlineClient(data.clientID);
|
|
@@ -468,7 +497,7 @@ class FileMessager {
|
|
|
468
497
|
return;
|
|
469
498
|
}
|
|
470
499
|
}
|
|
471
|
-
handleClientsOnline(clientID) {
|
|
500
|
+
handleClientsOnline(senderTide, clientID) {
|
|
472
501
|
const connectionDetails = FileNetClientManager.getOnlineClient(clientID);
|
|
473
502
|
if (!connectionDetails) {
|
|
474
503
|
console.log(`[FileTide ~ Net Activity] ~ Client ~ ${clientID} not authorized.`);
|
|
@@ -482,13 +511,21 @@ class FileMessager {
|
|
|
482
511
|
this.fileNet.emitToTide(connectionDetails.tideID, "current-online-clients", Object.fromEntries(FileNetClientManager.getOnlineClients()));
|
|
483
512
|
return;
|
|
484
513
|
}
|
|
485
|
-
handleClientOnline(clientID, tideID, pClientID, connectionID, activeTransferBarrier) {
|
|
514
|
+
handleClientOnline(senderTide, clientID, tideID, pClientID, connectionID, activeTransferBarrier) {
|
|
486
515
|
if (!this.onlineClients.contains(connectionID)) {
|
|
487
516
|
return;
|
|
488
517
|
}
|
|
489
518
|
if (FileNetClientManager.getOnlineClient(clientID) && this.onlineClients.get(connectionID)) {
|
|
490
|
-
|
|
519
|
+
const nClientID = `${clientID}_${connectionID.slice(0, 4)}`;
|
|
520
|
+
const currentClientID = clientID;
|
|
521
|
+
clientID = nClientID;
|
|
491
522
|
this.fileNet.emitToTide(tideID, "current-client-id-already-online", clientID);
|
|
523
|
+
FileNetClientManager.updateOnlineClient(nClientID, {
|
|
524
|
+
pClientID: currentClientID,
|
|
525
|
+
clientID: nClientID,
|
|
526
|
+
tideID: senderTide.tideID,
|
|
527
|
+
id: senderTide.id
|
|
528
|
+
});
|
|
492
529
|
return;
|
|
493
530
|
}
|
|
494
531
|
FileNetClientManager.addOnlineClient(clientID, pClientID, tideID, connectionID);
|
|
@@ -501,7 +538,7 @@ class FileMessager {
|
|
|
501
538
|
this.fileNet.emit("current-clients", currentOnlineClients);
|
|
502
539
|
return;
|
|
503
540
|
}
|
|
504
|
-
handleClientOffline(clientData) {
|
|
541
|
+
handleClientOffline(senderTide, clientData) {
|
|
505
542
|
console.log(`[FileTide ~ Net Activity] ~ Client ~ ${clientData.clientID} | connection origin ~ ${clientData.connectionID} going offline...`);
|
|
506
543
|
try {
|
|
507
544
|
const clientDetails = FileNetClientManager.getOnlineClient(clientData.clientID);
|
|
@@ -535,7 +572,7 @@ class FileMessager {
|
|
|
535
572
|
}
|
|
536
573
|
return;
|
|
537
574
|
}
|
|
538
|
-
handleClientTiding(data) {
|
|
575
|
+
handleClientTiding(senderTide, data) {
|
|
539
576
|
try {
|
|
540
577
|
const senderConnectionID = FileNetClientManager.getOnlineClient(data.senderID).id;
|
|
541
578
|
const senderClient = this.getClientFromID(senderConnectionID);
|
|
@@ -548,9 +585,16 @@ class FileMessager {
|
|
|
548
585
|
});
|
|
549
586
|
return;
|
|
550
587
|
} catch (error) {
|
|
588
|
+
console.error(`[FileTide ~ Net Activity] ~ `, error);
|
|
551
589
|
return;
|
|
552
590
|
}
|
|
553
591
|
}
|
|
554
592
|
}
|
|
593
|
+
function _log(...message) {
|
|
594
|
+
if (!this.debugMode) {
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
console.log(...message);
|
|
598
|
+
}
|
|
555
599
|
;
|
|
556
600
|
module.exports = FileMessager;
|
|
@@ -7,10 +7,13 @@ const chalk = require("chalk");
|
|
|
7
7
|
const path = require("path");
|
|
8
8
|
const fs = require("fs");
|
|
9
9
|
const {
|
|
10
|
-
|
|
10
|
+
FileTideDebugUtilityManager,
|
|
11
11
|
significantMessageColors,
|
|
12
12
|
errorMessageColors
|
|
13
|
-
} = require("./HUDManagers/
|
|
13
|
+
} = require("./HUDManagers/FileTideDebugUtilityManager");
|
|
14
|
+
const {
|
|
15
|
+
FileTransferTrackingManager
|
|
16
|
+
} = require("./HUDManagers/FileTransferTrackingManager.js");
|
|
14
17
|
const FileTransferRecoveryManager = require("./HUDManagers/FileTransferRecoveryManager");
|
|
15
18
|
const {
|
|
16
19
|
FileMessagerConfigManager
|
|
@@ -46,12 +49,13 @@ class FileMessagerClient {
|
|
|
46
49
|
transports: ["websocket"],
|
|
47
50
|
...options
|
|
48
51
|
}, headers, authURL, authHeaders, useAuthentication, queryAuthToken, onConnect, () => {
|
|
52
|
+
FileTransferTrackingManager.outputCurrentTransfers();
|
|
49
53
|
FileTransferRecoveryManager.flushToDisk();
|
|
50
54
|
if (onDisconnect) {
|
|
51
55
|
onDisconnect();
|
|
52
56
|
}
|
|
53
57
|
});
|
|
54
|
-
|
|
58
|
+
FileTideDebugUtilityManager.outputGradient(`\n[FileTide ~ File Messager] ~ Created client with ID ${clientID} and socket ${clientID}!`, significantMessageColors);
|
|
55
59
|
return clientID;
|
|
56
60
|
}
|
|
57
61
|
joinRoom(userID, roomName, options = {}, headers = {}, onConnect = null, onDisconnect = null, authURL = "", authHeaders = {}, useAuthentication = false, queryAuthToken = false) {
|
|
@@ -60,7 +64,7 @@ class FileMessagerClient {
|
|
|
60
64
|
}, options, headers, onConnect, onDisconnect, authURL, authHeaders, useAuthentication, queryAuthToken);
|
|
61
65
|
return () => {
|
|
62
66
|
this.clientTide.joinChannel(socketName, roomName, userID, () => {
|
|
63
|
-
|
|
67
|
+
FileTideDebugUtilityManager.outputGradient(`\n[FileTide ~ File Messager] ~ Client ~ ${userID} joined room ${roomName} successfully!`, significantMessageColors);
|
|
64
68
|
this.clients.set(userID, {
|
|
65
69
|
roomName
|
|
66
70
|
});
|
|
@@ -109,18 +113,18 @@ class FileMessagerClient {
|
|
|
109
113
|
transferType
|
|
110
114
|
}, transferExpirationTime);
|
|
111
115
|
if (!transferAccepted) {
|
|
112
|
-
|
|
116
|
+
FileTideDebugUtilityManager.outputGradient(`[FileTide ~ File Messager] ${recipientID} denied your transfer.`, errorMessageColors);
|
|
113
117
|
return false;
|
|
114
118
|
} else if (transferAccepted) {
|
|
115
|
-
|
|
119
|
+
FileTideDebugUtilityManager.outputGradient(`[FileTide ~ File Messager] ${recipientID} accepted your transfer!`, significantMessageColors);
|
|
116
120
|
return true;
|
|
117
121
|
}
|
|
118
122
|
} catch (error) {
|
|
119
123
|
if (error.message.startsWith("Timeout: No response")) {
|
|
120
|
-
|
|
124
|
+
FileTideDebugUtilityManager.outputGradient("[FileTide ~ File Messager] Transfer approval timed out.", errorMessageColors);
|
|
121
125
|
return false;
|
|
122
126
|
}
|
|
123
|
-
|
|
127
|
+
FileTideDebugUtilityManager.outputGradient(`[FileTide ~ File Messager] Transfer approval refused.\n${error}`, errorMessageColors);
|
|
124
128
|
return false;
|
|
125
129
|
}
|
|
126
130
|
}
|
|
@@ -163,7 +167,7 @@ class FileMessagerClient {
|
|
|
163
167
|
});
|
|
164
168
|
Promise.all(sendFilePromises).then(() => console.log("\nAll files in directory transferred successfully!")).catch(error => console.error("Did not transfer directory: ", error));
|
|
165
169
|
} catch (error) {
|
|
166
|
-
|
|
170
|
+
FileTideDebugUtilityManager.outputGradient(`[FileTide ~ File Messager] ~ Refused directory transfer: ${error}`, errorMessageColors);
|
|
167
171
|
}
|
|
168
172
|
}
|
|
169
173
|
async sendDirectoryLargeFile(clientID, recipientId, fileName, filePath = process.cwd(), destinationPath = null, fileSize, index = 0, tideSize = 500, minTideSize = 10, maxTideSize = 2000, transferRequestExpirationTime = 30000) {
|
|
@@ -192,7 +196,7 @@ class FileMessagerClient {
|
|
|
192
196
|
}
|
|
193
197
|
async sendFile(clientID, recipientId, fileName, filePath = process.cwd(), destination = process.cwd(), fileSize, tideSize = 500, minTideSize = 10, maxTideSize = 2000, initiatingTransfer = true, inDirectory = false, largeFile = false, transferRequestExpirationTime = 30000) {
|
|
194
198
|
const destinationPath = FileUtilityManager.normalizePath(path.join(destination, fileName));
|
|
195
|
-
|
|
199
|
+
FileTideDebugUtilityManager.outputGradient(largeFile ? `[FileTide ~ File Messager] ~ Requesting to transfer large file ~ ${destinationPath} to ${recipientId}!` : `[FileTide ~ File Messager] ~ Requesting to transfer ~ ${destinationPath} to ${recipientId}!`, significantMessageColors);
|
|
196
200
|
const incomingType = this.activeTransferTypes.get(filePath);
|
|
197
201
|
if (!inDirectory && initiatingTransfer) {
|
|
198
202
|
const transferAllowed = incomingType && incomingType === "requestedTransfer" ? true : await this.allowedTransfer(clientID, recipientId, destinationPath, filePath, fileSize, 1, "file", "send", transferRequestExpirationTime);
|
|
@@ -298,9 +302,9 @@ class FileMessagerClient {
|
|
|
298
302
|
});
|
|
299
303
|
}
|
|
300
304
|
}, this.clientTide);
|
|
301
|
-
|
|
305
|
+
FileTideDebugUtilityManager.outputGradient(largeFile ? `[FileTide ~ File Messager] ~ Large file ~ ${fileName} transfer complete!` : `[FileTide ~ File Messager] ~ File ~ ${fileName} transfer complete!`, significantMessageColors);
|
|
302
306
|
} catch (error) {
|
|
303
|
-
|
|
307
|
+
FileTideDebugUtilityManager.outputGradient(largeFile ? `[FileTide ~ File Messager] ~ Error transferring large file: ${error.message}` : `[FileTide ~ File Messager] ~ Error transferring file ~ ${error.message}`, errorMessageColors);
|
|
304
308
|
} finally {
|
|
305
309
|
await fileHandle.close();
|
|
306
310
|
}
|
package/dist/cjs/FileTide.js
CHANGED
|
@@ -11,10 +11,13 @@ const chalk = require("chalk");
|
|
|
11
11
|
const path = require("path");
|
|
12
12
|
const fs = require("fs");
|
|
13
13
|
const {
|
|
14
|
-
|
|
14
|
+
FileTideDebugUtilityManager,
|
|
15
15
|
significantMessageColors,
|
|
16
16
|
errorMessageColors
|
|
17
|
-
} = require("./HUDManagers/
|
|
17
|
+
} = require("./HUDManagers/FileTideDebugUtilityManager.js");
|
|
18
|
+
const {
|
|
19
|
+
FileTransferTrackingManager
|
|
20
|
+
} = require("./HUDManagers/FileTransferTrackingManager.js");
|
|
18
21
|
const {
|
|
19
22
|
FileTransferReceiverManager
|
|
20
23
|
} = require("./HUDManagers/FileTransferReceiverManager.js");
|
|
@@ -32,7 +35,7 @@ const FileMessagerClient = require("./FileMessagerClient");
|
|
|
32
35
|
const FileMessager = require("./FileMessager");
|
|
33
36
|
var _FileTide_brand = /*#__PURE__*/new WeakSet();
|
|
34
37
|
class FileTide {
|
|
35
|
-
constructor() {
|
|
38
|
+
constructor(debugMode = true) {
|
|
36
39
|
/**
|
|
37
40
|
* Set up file transfer event listeners natively.
|
|
38
41
|
* Automatically checks and creates directories as needed.
|
|
@@ -45,10 +48,12 @@ class FileTide {
|
|
|
45
48
|
this.transferBarrier = false;
|
|
46
49
|
this.clients = new Map();
|
|
47
50
|
this.currentUserID = "";
|
|
51
|
+
this.inDebugMode = debugMode;
|
|
52
|
+
FileTideDebugUtilityManager.setDebugMode(debugMode);
|
|
48
53
|
return;
|
|
49
54
|
}
|
|
50
55
|
static outputGradient(text, colors) {
|
|
51
|
-
|
|
56
|
+
FileTideDebugUtilityManager.outputGradient(text, colors);
|
|
52
57
|
return;
|
|
53
58
|
}
|
|
54
59
|
|
|
@@ -104,7 +109,7 @@ class FileTide {
|
|
|
104
109
|
const newClient = new FileMessagerClient(clientOptions, transportOptions, messagerSettings);
|
|
105
110
|
const enterRoom = newClient.joinRoom(userID, roomName, connectionOptions, headers, onConnect, onDisconnect, authURL, authHeaders, useAuthentication, queryAuthToken);
|
|
106
111
|
this.transferBarrier = enableTransferBarrier;
|
|
107
|
-
this.clientShorePolicies.set(userID, [FileUtilityManager.getTidePath(">
|
|
112
|
+
this.clientShorePolicies.set(userID, [FileUtilityManager.getTidePath(">Downloads"), FileUtilityManager.getTidePath(">Documents"), FileUtilityManager.getTidePath(">Pictures"), FileUtilityManager.getTidePath(">Desktop"), FileUtilityManager.getTidePath(">Videos"), FileUtilityManager.getTidePath(">Music")]);
|
|
108
113
|
this.clients.set(userID, newClient);
|
|
109
114
|
FileTide.outputGradient(`[FileTide] ~ Messager launched successfully for client ~ ${userID}!`, significantMessageColors);
|
|
110
115
|
_assertClassBrand(_FileTide_brand, this, _setupFileEventListeners).call(this, userID, newClient, onTransferProgress, onIncomingTransfer, onIncomingFile, onTransferBarrier, options);
|
|
@@ -142,7 +147,7 @@ class FileTide {
|
|
|
142
147
|
const clientID = this.currentUserID;
|
|
143
148
|
const clientMessager = this.clients.get(clientID);
|
|
144
149
|
if (!clientMessager) {
|
|
145
|
-
FileTide.outputGradient(`[FileTide] Client ~ ${clientID} not found.`,
|
|
150
|
+
FileTide.outputGradient(`[FileTide] Client ~ ${clientID} not found.`, errorMessageColors);
|
|
146
151
|
return;
|
|
147
152
|
}
|
|
148
153
|
clientMessager.listFiles(clientID, recipientID, depth);
|
|
@@ -153,7 +158,7 @@ class FileTide {
|
|
|
153
158
|
clearShorePolicies(clientID, shores = []) {
|
|
154
159
|
let clientShorePolicies = this.clientShorePolicies.get(clientID);
|
|
155
160
|
if (!shores || shores.length <= 0 || !clientShorePolicies || !clientID) {
|
|
156
|
-
FileTide.outputGradient(`[FileTide] Did not clear from client ~ ${clientID} shore policies.`,
|
|
161
|
+
FileTide.outputGradient(`[FileTide] Did not clear from client ~ ${clientID} shore policies.`, errorMessageColors);
|
|
157
162
|
return false;
|
|
158
163
|
}
|
|
159
164
|
const shorePolicies = Array.from(clientShorePolicies.values());
|
|
@@ -164,7 +169,7 @@ class FileTide {
|
|
|
164
169
|
addShorePolicies(clientID, shores = []) {
|
|
165
170
|
const clientShorePolicies = this.clientShorePolicies.get(clientID);
|
|
166
171
|
if (!shores || shores.length <= 0 || !clientShorePolicies || !clientID) {
|
|
167
|
-
FileTide.outputGradient(`[FileTide] Did not add to client ~ ${clientID} shore policies.`,
|
|
172
|
+
FileTide.outputGradient(`[FileTide] Did not add to client ~ ${clientID} shore policies.`, errorMessageColors);
|
|
168
173
|
return false;
|
|
169
174
|
}
|
|
170
175
|
this.clientShorePolicies.set(clientID, [...new Set([...clientShorePolicies, ...shores])]);
|
|
@@ -190,33 +195,33 @@ class FileTide {
|
|
|
190
195
|
const clientID = this.currentUserID;
|
|
191
196
|
const clientMessager = this.clients.get(clientID);
|
|
192
197
|
if (!clientMessager) {
|
|
193
|
-
FileTide.outputGradient(`[FileTide] Client ~ ${clientID} not found.`,
|
|
198
|
+
FileTide.outputGradient(`[FileTide] Client ~ ${clientID} not found.`, errorMessageColors);
|
|
194
199
|
return false;
|
|
195
200
|
}
|
|
196
201
|
const recipientOnline = await clientMessager.clientTide.emitEventWithResponse(clientID, "check-client-online", "retrieved-client-online", {
|
|
197
202
|
clientID: recipientID
|
|
198
203
|
}, 5000);
|
|
199
204
|
if (!recipientOnline || !recipientOnline.online) {
|
|
200
|
-
FileTide.outputGradient(`[FileTide] ${recipientID} currently not tiding.`,
|
|
205
|
+
FileTide.outputGradient(`[FileTide] ${recipientID} currently not tiding.`, errorMessageColors);
|
|
201
206
|
return false;
|
|
202
207
|
}
|
|
203
208
|
const fileDetails = await this.getPathData(filePath, filterDirectoryContent);
|
|
204
209
|
if (!fileDetails) {
|
|
205
|
-
FileTide.outputGradient(`[${clientID}] File at path ${filePath} not found.`,
|
|
210
|
+
FileTide.outputGradient(`[${clientID}] File at path ${filePath} not found.`, errorMessageColors);
|
|
206
211
|
return false;
|
|
207
212
|
}
|
|
208
213
|
if (fileDetails.type === "file") {
|
|
209
214
|
if (fileDetails.largeFile) {
|
|
210
|
-
FileTide.outputGradient(`[${clientID}] Sending large file ~ ${fileDetails.fileName} to client ~ ${recipientID}...`,
|
|
215
|
+
FileTide.outputGradient(`[${clientID}] Sending large file ~ ${fileDetails.fileName} to client ~ ${recipientID}...`, significantMessageColors);
|
|
211
216
|
await clientMessager.sendFile(clientID, recipientID, fileDetails.fileName, fileDetails.filePath, destinationPath, fileDetails.fileSize, tidalSize, minTideSize, maxTideSize, true, false, true, transferRequestExpirationTime);
|
|
212
217
|
return true;
|
|
213
218
|
}
|
|
214
|
-
FileTide.outputGradient(`[${clientID}] Sending file ~ ${fileDetails.content.fileName} to client ~ ${recipientID}...`,
|
|
219
|
+
FileTide.outputGradient(`[${clientID}] Sending file ~ ${fileDetails.content.fileName} to client ~ ${recipientID}...`, significantMessageColors);
|
|
215
220
|
await clientMessager.sendFile(clientID, recipientID, fileDetails.content.fileName, fileDetails.content.filePath, destinationPath, fileDetails.content.size, tideSize, minTideSize, maxTideSize, transferRequestExpirationTime);
|
|
216
221
|
return true;
|
|
217
222
|
}
|
|
218
223
|
if (fileDetails.type === "directory") {
|
|
219
|
-
FileTide.outputGradient(`[${clientID}] Sending ${fileDetails.content.length} files in directory ~ ${path.basename(filePath)} to client ~ ${recipientID}...`,
|
|
224
|
+
FileTide.outputGradient(`[${clientID}] Sending ${fileDetails.content.length} files in directory ~ ${path.basename(filePath)} to client ~ ${recipientID}...`, significantMessageColors);
|
|
220
225
|
await clientMessager.sendDirectoryFiles(clientID, recipientID, fileDetails.content, this.getTidePath(filePath), destinationPath, tideSize, minTideSize, maxTideSize, transferRequestExpirationTime);
|
|
221
226
|
return true;
|
|
222
227
|
}
|
|
@@ -439,7 +444,7 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
|
|
|
439
444
|
onIncomingFile(verifiedSender, {
|
|
440
445
|
...data,
|
|
441
446
|
stats: taskBarStats
|
|
442
|
-
},
|
|
447
|
+
}, FileTransferTrackingManager.activeTransfers);
|
|
443
448
|
}
|
|
444
449
|
if (verifiedSender && !fs.existsSync(saveDir)) {
|
|
445
450
|
fs.mkdirSync(saveDir, {
|
|
@@ -465,6 +470,8 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
|
|
|
465
470
|
});
|
|
466
471
|
client.clientTide.onEvent(userID, "transfer-progress", async data => {
|
|
467
472
|
if (!data || data.fileChunk === undefined || data.fileChunk === null) {
|
|
473
|
+
FileTideDebugUtilityManager.log("notice", true, `Received invalid data chunk from ~ ${data.senderName} in transfer progress ~ ${data.fileName}`);
|
|
474
|
+
FileTransferTrackingManager.outputCurrentTransfers();
|
|
468
475
|
return;
|
|
469
476
|
}
|
|
470
477
|
await fileTransferReceiver.handleTransferProgress(data);
|
|
@@ -474,8 +481,16 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
|
|
|
474
481
|
};
|
|
475
482
|
currentTransferState.transferredSize += data.chunkSize || 512 * 1024;
|
|
476
483
|
FileTransferRecoveryManager.saveTransferState(userID, data.senderName, `${data.path}-${data.fileName}`, data.chunkIndex, currentTransferState.transferredSize);
|
|
484
|
+
const taskBarStats = this.progressBarManager.getTaskBar(data.fileName);
|
|
485
|
+
client.clientTide.emitEvent(userID, "acknowledge-transfer-tide", {
|
|
486
|
+
fileName: data.fileName,
|
|
487
|
+
senderName: data.senderName,
|
|
488
|
+
recipientName: userID,
|
|
489
|
+
transferStateID: `${data.path}-${data.fileName}`,
|
|
490
|
+
path: data.path,
|
|
491
|
+
transferStats: taskBarStats
|
|
492
|
+
});
|
|
477
493
|
if (onTransferProgress) {
|
|
478
|
-
const taskBarStats = this.progressBarManager.getTaskBar(data.fileName);
|
|
479
494
|
onTransferProgress({
|
|
480
495
|
...data,
|
|
481
496
|
stats: taskBarStats
|
|
@@ -490,12 +505,15 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
|
|
|
490
505
|
fileSize
|
|
491
506
|
} = data;
|
|
492
507
|
if (chunkIndex === 0) {
|
|
508
|
+
FileTransferTrackingManager.trackTransfer(data);
|
|
493
509
|
this.progressBarManager.addTask({
|
|
494
510
|
name: fileName,
|
|
495
511
|
size: fileSize
|
|
496
512
|
});
|
|
513
|
+
} else if (chunkIndex > 0) {
|
|
514
|
+
FileTransferTrackingManager.updateTransfer(data);
|
|
515
|
+
this.progressBarManager.updateTaskProgress(fileName, chunkSize);
|
|
497
516
|
}
|
|
498
|
-
this.progressBarManager.updateTaskProgress(fileName, chunkSize);
|
|
499
517
|
if (onTransferStatus) {
|
|
500
518
|
const taskBarStats = this.progressBarManager.getTaskBar(fileName);
|
|
501
519
|
onTransferStatus({
|
|
@@ -508,35 +526,61 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
|
|
|
508
526
|
client.clientTide.onEvent(userID, "transfer-complete", data => {
|
|
509
527
|
const savePath = FileUtilityManager.getTidePath(path.join(data.filePath, data.fileName));
|
|
510
528
|
try {
|
|
511
|
-
_FileTide.outputGradient(`[${userID}] File transfer complete
|
|
512
|
-
const transferState =
|
|
529
|
+
_FileTide.outputGradient(`[${userID}] File transfer complete ~ ${data.fileName}`, significantMessageColors);
|
|
530
|
+
const transferState = FileTransferTrackingManager.getTransfer(data.fileName);
|
|
531
|
+
FileTideDebugUtilityManager.log("notice", true, `Transfer state ~ ${data.fileName} active | ${transferState !== null && transferState !== undefined ? true : false}`);
|
|
513
532
|
if (!transferState) {
|
|
514
533
|
return;
|
|
515
534
|
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
535
|
+
if (transferState.fileStream) {
|
|
536
|
+
fileTransferReceiver.completeTransfer(data, (transferData, transfers, success, error) => {
|
|
537
|
+
if (success) {
|
|
538
|
+
FileTransferRecoveryManager.clearTransferState(userID, data.senderID, `${data.filePath}-${data.fileName}`);
|
|
539
|
+
_FileTide.outputGradient(`[${userID}] File saved at ~ ${savePath}\n`, significantMessageColors);
|
|
540
|
+
} else if (!success) {
|
|
541
|
+
_FileTide.outputGradient(`[${userID}] Did not save file at ~ ${savePath}\n\t${error}\n`, errorMessageColors);
|
|
542
|
+
}
|
|
543
|
+
if (onTransferComplete) {
|
|
544
|
+
const taskBarStats = this.progressBarManager.getTaskBar(data.fileName);
|
|
545
|
+
onTransferComplete({
|
|
546
|
+
...data,
|
|
547
|
+
stats: taskBarStats
|
|
548
|
+
}, FileTransferTrackingManager.activeTransfers, success);
|
|
549
|
+
}
|
|
550
|
+
setTimeout(() => {
|
|
551
|
+
FileTransferTrackingManager.outputCurrentTransfers();
|
|
552
|
+
this.progressBarManager.clearTaskBar(data.fileName);
|
|
553
|
+
}, this.progressBarManager.completionTimeout);
|
|
554
|
+
});
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
FileTransferRecoveryManager.clearTransferState(userID, data.senderID, `${data.filePath}-${data.fileName}`);
|
|
558
|
+
FileTransferTrackingManager.untrackTransfer(data.fileName);
|
|
559
|
+
_FileTide.outputGradient(`[${userID}] Transfer successfully sent to ~ ${data.recipientId} and saved at ~ ${path.join(data.filePath, data.fileName)}\n`, significantMessageColors);
|
|
560
|
+
if (onTransferComplete) {
|
|
561
|
+
const taskBarStats = this.progressBarManager.getTaskBar(data.fileName);
|
|
562
|
+
onTransferComplete({
|
|
563
|
+
...data,
|
|
564
|
+
stats: taskBarStats
|
|
565
|
+
}, FileTransferTrackingManager.activeTransfers, true);
|
|
566
|
+
}
|
|
567
|
+
setTimeout(() => {
|
|
568
|
+
FileTransferTrackingManager.outputCurrentTransfers();
|
|
569
|
+
this.progressBarManager.clearTaskBar(data.fileName);
|
|
570
|
+
}, this.progressBarManager.completionTimeout);
|
|
531
571
|
} catch (error) {
|
|
532
|
-
_FileTide.outputGradient(`[${userID}] Did not save file at
|
|
572
|
+
_FileTide.outputGradient(`[${userID}] Did not save file at ~ ${savePath}\n${error}`, errorMessageColors);
|
|
533
573
|
if (onTransferComplete) {
|
|
534
574
|
const taskBarStats = this.progressBarManager.getTaskBar(data.fileName);
|
|
535
575
|
onTransferComplete({
|
|
536
576
|
...data,
|
|
537
577
|
stats: taskBarStats
|
|
538
|
-
},
|
|
578
|
+
}, FileTransferTrackingManager.activeTransfers, false);
|
|
539
579
|
}
|
|
580
|
+
setTimeout(() => {
|
|
581
|
+
FileTransferTrackingManager.outputCurrentTransfers();
|
|
582
|
+
this.progressBarManager.clearTaskBar(data.fileName);
|
|
583
|
+
}, this.progressBarManager.completionTimeout);
|
|
540
584
|
}
|
|
541
585
|
});
|
|
542
586
|
client.clientTide.onEvent(userID, "transfer-requested", async data => {
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
const readline = require("readline");
|
|
4
4
|
const chalk = require("chalk");
|
|
5
|
+
const {
|
|
6
|
+
FileTideDebugUtilityManager
|
|
7
|
+
} = require("../HUDManagers/FileTideDebugUtilityManager.js");
|
|
8
|
+
const {
|
|
9
|
+
FileNetUtilityManager
|
|
10
|
+
} = require("../HUDManagers/FileNetUtilityManager");
|
|
5
11
|
class ConsoleProgressBarManager {
|
|
6
12
|
constructor(tasks = [], options = {}) {
|
|
7
13
|
const rows = process.stdout.rows || 24;
|
|
@@ -20,41 +26,6 @@ class ConsoleProgressBarManager {
|
|
|
20
26
|
this.allTasksCompleted = false;
|
|
21
27
|
this.taskBars = tasks.map((task, index) => this.createTaskBar(task, index));
|
|
22
28
|
}
|
|
23
|
-
convertSeconds(seconds) {
|
|
24
|
-
if (seconds === 0) return "0 s";
|
|
25
|
-
const units = [{
|
|
26
|
-
name: "y",
|
|
27
|
-
seconds: 60 * 60 * 24 * 365
|
|
28
|
-
}, {
|
|
29
|
-
name: "mo",
|
|
30
|
-
seconds: 60 * 60 * 24 * 30
|
|
31
|
-
}, {
|
|
32
|
-
name: "w",
|
|
33
|
-
seconds: 60 * 60 * 24 * 7
|
|
34
|
-
}, {
|
|
35
|
-
name: "d",
|
|
36
|
-
seconds: 60 * 60 * 24
|
|
37
|
-
}, {
|
|
38
|
-
name: "h",
|
|
39
|
-
seconds: 60 * 60
|
|
40
|
-
}, {
|
|
41
|
-
name: "m",
|
|
42
|
-
seconds: 60
|
|
43
|
-
}, {
|
|
44
|
-
name: "s",
|
|
45
|
-
seconds: 1
|
|
46
|
-
}];
|
|
47
|
-
let remainingSeconds = seconds;
|
|
48
|
-
let result = "";
|
|
49
|
-
for (const unit of units) {
|
|
50
|
-
const count = Math.floor(remainingSeconds / unit.seconds);
|
|
51
|
-
if (count > 0) {
|
|
52
|
-
result += `${count}${unit.name} `;
|
|
53
|
-
remainingSeconds %= unit.seconds;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return result.trim();
|
|
57
|
-
}
|
|
58
29
|
createTaskBar(task, index) {
|
|
59
30
|
const defaultOptions = {
|
|
60
31
|
barLength: 40,
|
|
@@ -81,32 +52,6 @@ class ConsoleProgressBarManager {
|
|
|
81
52
|
startTime: Date.now(),
|
|
82
53
|
taskIndex: index,
|
|
83
54
|
completed: false,
|
|
84
|
-
getFormattedSize: size => {
|
|
85
|
-
if (!settings.dynamicUnits) return `${size.toFixed(1)} B`;
|
|
86
|
-
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
87
|
-
let unitIndex = 0;
|
|
88
|
-
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
89
|
-
size /= 1024;
|
|
90
|
-
unitIndex++;
|
|
91
|
-
}
|
|
92
|
-
return `${size.toFixed(2)} ${units[unitIndex]}`;
|
|
93
|
-
},
|
|
94
|
-
getUnitData: size => {
|
|
95
|
-
if (!settings.dynamicUnits) return {
|
|
96
|
-
current: size.toFixed(1),
|
|
97
|
-
unit: "B"
|
|
98
|
-
};
|
|
99
|
-
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
100
|
-
let unitIndex = 0;
|
|
101
|
-
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
102
|
-
size /= 1024;
|
|
103
|
-
unitIndex++;
|
|
104
|
-
}
|
|
105
|
-
return {
|
|
106
|
-
current: size.toFixed(2),
|
|
107
|
-
unit: units[unitIndex]
|
|
108
|
-
};
|
|
109
|
-
},
|
|
110
55
|
redraw: () => {
|
|
111
56
|
if (!isNaN(newBar.taskIndex) && !isNaN(this.barsPerPage) && process.stdout.isTTY) {
|
|
112
57
|
readline.cursorTo(process.stdout, 0, newBar.taskIndex % this.barsPerPage);
|
|
@@ -119,7 +64,7 @@ class ConsoleProgressBarManager {
|
|
|
119
64
|
const percentage = newBar.current / newBar.totalSize * 100;
|
|
120
65
|
const elapsedTime = (Date.now() - newBar.startTime) / 1000;
|
|
121
66
|
const speed = newBar.current / elapsedTime;
|
|
122
|
-
const speedData =
|
|
67
|
+
const speedData = FileNetUtilityManager.getFormattedSize(speed, settings.dynamicUnits);
|
|
123
68
|
const timeLeft = (newBar.totalSize - newBar.current) / (speed || 1);
|
|
124
69
|
newBar.progress = percentage;
|
|
125
70
|
newBar.timeLeft = timeLeft;
|
|
@@ -127,7 +72,7 @@ class ConsoleProgressBarManager {
|
|
|
127
72
|
const filledLength = Math.round(settings.barLength * (newBar.current / newBar.totalSize));
|
|
128
73
|
const bar = settings.barColor(settings.filledChar.repeat(filledLength)) + settings.unfilledChar.repeat(settings.barLength - filledLength);
|
|
129
74
|
try {
|
|
130
|
-
process.stdout.write(`${settings.taskNameColor(newBar.taskName)} > ${settings.totalSizeColor(
|
|
75
|
+
process.stdout.write(`${settings.taskNameColor(newBar.taskName)} > ${settings.totalSizeColor(FileNetUtilityManager.getFormattedSize(newBar.totalSize, settings.dynamicUnits))} | ${settings.sizeTransferredColor(FileNetUtilityManager.getFormattedSize(newBar.current, settings.dynamicUnits))} ${settings.speedColor(`${speedData}/s`)} | ${settings.taskETAColor(FileNetUtilityManager.convertSeconds(timeLeft.toFixed(2)))} [${bar}] ${settings.percentageColor(percentage.toFixed(2) + "%")}`);
|
|
131
76
|
} catch (error) {
|
|
132
77
|
console.log(error);
|
|
133
78
|
}
|
|
@@ -165,7 +110,9 @@ class ConsoleProgressBarManager {
|
|
|
165
110
|
setTimeout(() => {
|
|
166
111
|
this.completionFeed = this.completionFeed.filter(task => task !== newBar.taskName);
|
|
167
112
|
}, this.completionTimeout);
|
|
113
|
+
FileTideDebugUtilityManager.log("notice", true, `Tasks Completion Status ~\n\n\tTasks ~ (${this.completedTasksCount}/${this.totalTasks})`);
|
|
168
114
|
if (this.completedTasksCount === this.totalTasks) {
|
|
115
|
+
FileTideDebugUtilityManager.log("notice", true, `All Tasks Complete!`);
|
|
169
116
|
this.allTasksCompleted = true;
|
|
170
117
|
this.exitInputListener();
|
|
171
118
|
this.displayPage();
|
|
@@ -211,7 +158,7 @@ class ConsoleProgressBarManager {
|
|
|
211
158
|
getCurrentStats() {
|
|
212
159
|
const completedTasks = this.taskBars.filter(bar => bar.completed).length;
|
|
213
160
|
const totalTasks = this.taskBars.length;
|
|
214
|
-
const overallProgress = this.taskBars.reduce((acc, bar) => acc + bar.current / bar.totalSize * 100, 0) / totalTasks;
|
|
161
|
+
const overallProgress = totalTasks === 0 ? 0 : this.taskBars.reduce((acc, bar) => acc + bar.current / bar.totalSize * 100, 0) / totalTasks;
|
|
215
162
|
const stats = {
|
|
216
163
|
completedTasks,
|
|
217
164
|
totalTasks,
|
|
@@ -220,10 +167,10 @@ class ConsoleProgressBarManager {
|
|
|
220
167
|
taskName: bar.taskName,
|
|
221
168
|
progress: `${(bar.current / bar.totalSize * 100).toFixed(2)}%`,
|
|
222
169
|
completed: bar.completed,
|
|
223
|
-
currentSize:
|
|
224
|
-
totalSize:
|
|
225
|
-
speed: `${
|
|
226
|
-
timeLeft:
|
|
170
|
+
currentSize: FileNetUtilityManager.getFormattedSize(bar.current, true),
|
|
171
|
+
totalSize: FileNetUtilityManager.getFormattedSize(bar.totalSize, true),
|
|
172
|
+
speed: `${FileNetUtilityManager.getUnitData(bar.speed, true).current} ${FileNetUtilityManager.getUnitData(bar.speed, true).unit}/s`,
|
|
173
|
+
timeLeft: FileNetUtilityManager.convertSeconds(bar.timeLeft.toFixed(2))
|
|
227
174
|
}))
|
|
228
175
|
};
|
|
229
176
|
return stats;
|
|
@@ -317,14 +264,20 @@ class ConsoleProgressBarManager {
|
|
|
317
264
|
}
|
|
318
265
|
exitInputListener() {
|
|
319
266
|
process.stdin.removeListener("data", this.inputListener);
|
|
267
|
+
FileTideDebugUtilityManager.log("notice", true, `Exiting input listener...`);
|
|
268
|
+
FileTideDebugUtilityManager.log("notice", true, `Process TTY ~ ${process.stdout.isTTY}`);
|
|
320
269
|
if (process.stdout.isTTY) {
|
|
321
270
|
process.stdin.setRawMode(false);
|
|
322
271
|
process.stdin.resume();
|
|
272
|
+
FileTideDebugUtilityManager.log("notice", true, `Resumed process.`);
|
|
323
273
|
}
|
|
274
|
+
FileTideDebugUtilityManager.log("notice", true, `Exited input listener.`);
|
|
324
275
|
}
|
|
325
276
|
displayCompletionMessage() {
|
|
326
277
|
const lastLine = Math.min(this.taskBars.length, this.barsPerPage);
|
|
327
278
|
readline.cursorTo(process.stdout, 0, lastLine);
|
|
279
|
+
FileTideDebugUtilityManager.log("notice", true, `Displaying task completion message...`);
|
|
280
|
+
FileTideDebugUtilityManager.log("notice", true, `Process TTY ~ ${process.stdout.isTTY}`);
|
|
328
281
|
if (process.stdout.isTTY) {
|
|
329
282
|
process.stdout.clearLine();
|
|
330
283
|
}
|
|
@@ -14,6 +14,17 @@ class FileNetClientManager {
|
|
|
14
14
|
});
|
|
15
15
|
return currentOnlineClients;
|
|
16
16
|
}
|
|
17
|
+
static updateOnlineClient(clientID, data) {
|
|
18
|
+
const onlineClient = currentOnlineClients.get(clientID);
|
|
19
|
+
if (!onlineClient) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
currentOnlineClients.set(clientID, {
|
|
23
|
+
...onlineClient,
|
|
24
|
+
...data
|
|
25
|
+
});
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
17
28
|
static clearOnlineClient(clientID) {
|
|
18
29
|
if (!currentOnlineClients.get(clientID)) {
|
|
19
30
|
return currentOnlineClients;
|
|
@@ -3,23 +3,69 @@
|
|
|
3
3
|
const {
|
|
4
4
|
HUDUtilityManager
|
|
5
5
|
} = require("@trap_stevo/legendarybuilderpronodejs-utilities");
|
|
6
|
-
const chalk = require("chalk");
|
|
7
|
-
const significantMessageColors = ["#00C897", "#00E0FF"];
|
|
8
|
-
const errorMessageColors = ["#F94144", "#F3722C"];
|
|
9
6
|
class FileNetUtilityManager {
|
|
10
|
-
static
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
static convertSeconds(seconds) {
|
|
8
|
+
if (seconds === 0) return "0 s";
|
|
9
|
+
const units = [{
|
|
10
|
+
name: "y",
|
|
11
|
+
seconds: 60 * 60 * 24 * 365
|
|
12
|
+
}, {
|
|
13
|
+
name: "mo",
|
|
14
|
+
seconds: 60 * 60 * 24 * 30
|
|
15
|
+
}, {
|
|
16
|
+
name: "w",
|
|
17
|
+
seconds: 60 * 60 * 24 * 7
|
|
18
|
+
}, {
|
|
19
|
+
name: "d",
|
|
20
|
+
seconds: 60 * 60 * 24
|
|
21
|
+
}, {
|
|
22
|
+
name: "h",
|
|
23
|
+
seconds: 60 * 60
|
|
24
|
+
}, {
|
|
25
|
+
name: "m",
|
|
26
|
+
seconds: 60
|
|
27
|
+
}, {
|
|
28
|
+
name: "s",
|
|
29
|
+
seconds: 1
|
|
30
|
+
}];
|
|
31
|
+
let remainingSeconds = seconds;
|
|
32
|
+
let result = "";
|
|
33
|
+
for (const unit of units) {
|
|
34
|
+
const count = Math.floor(remainingSeconds / unit.seconds);
|
|
35
|
+
if (count > 0) {
|
|
36
|
+
result += `${count}${unit.name} `;
|
|
37
|
+
remainingSeconds %= unit.seconds;
|
|
38
|
+
}
|
|
16
39
|
}
|
|
17
|
-
|
|
18
|
-
|
|
40
|
+
return result.trim();
|
|
41
|
+
}
|
|
42
|
+
static getFormattedSize(size, dynamicUnits = true) {
|
|
43
|
+
if (!dynamicUnits) return `${size.toFixed(1)} B`;
|
|
44
|
+
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
45
|
+
let unitIndex = 0;
|
|
46
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
47
|
+
size /= 1024;
|
|
48
|
+
unitIndex++;
|
|
49
|
+
}
|
|
50
|
+
return `${size.toFixed(2)} ${units[unitIndex]}`;
|
|
51
|
+
}
|
|
52
|
+
static getUnitData(size, dynamicUnits = true) {
|
|
53
|
+
if (!dynamicUnits) return {
|
|
54
|
+
current: size.toFixed(1),
|
|
55
|
+
unit: "B"
|
|
56
|
+
};
|
|
57
|
+
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
58
|
+
let unitIndex = 0;
|
|
59
|
+
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
60
|
+
size /= 1024;
|
|
61
|
+
unitIndex++;
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
current: size.toFixed(2),
|
|
65
|
+
unit: units[unitIndex]
|
|
66
|
+
};
|
|
19
67
|
}
|
|
20
68
|
}
|
|
21
69
|
module.exports = {
|
|
22
|
-
FileNetUtilityManager
|
|
23
|
-
significantMessageColors,
|
|
24
|
-
errorMessageColors
|
|
70
|
+
FileNetUtilityManager
|
|
25
71
|
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
HUDUtilityManager
|
|
5
|
+
} = require("@trap_stevo/legendarybuilderpronodejs-utilities");
|
|
6
|
+
const chalk = require("chalk");
|
|
7
|
+
const significantMessageColors = ["#00C897", "#00E0FF"];
|
|
8
|
+
const noticeMessageColors = ["#4A90E2", "#A3D8F4"];
|
|
9
|
+
const errorMessageColors = ["#F94144", "#F3722C"];
|
|
10
|
+
const infoMessageColors = ["#028090", "#56cfe1"];
|
|
11
|
+
const logHandler = {
|
|
12
|
+
"significant": function (includeDate = false, ...message) {
|
|
13
|
+
const log = includeDate ? `[${new Date().toLocaleString()}] ~ ` : "";
|
|
14
|
+
outputGradient(log + message.join(" "), significantMessageColors);
|
|
15
|
+
},
|
|
16
|
+
"notice": function (includeDate = false, ...message) {
|
|
17
|
+
const log = includeDate ? `[${new Date().toLocaleString()}] ~ ` : "";
|
|
18
|
+
outputGradient(log + message.join(" "), noticeMessageColors);
|
|
19
|
+
},
|
|
20
|
+
"error": function (includeDate = false, ...message) {
|
|
21
|
+
const log = includeDate ? `[${new Date().toLocaleString()}] ~ ` : "";
|
|
22
|
+
outputGradient(log + message.join(" "), errorMessageColors);
|
|
23
|
+
},
|
|
24
|
+
"info": function (includeDate = false, ...message) {
|
|
25
|
+
const log = includeDate ? `[${new Date().toLocaleString()}] ~ ` : "";
|
|
26
|
+
outputGradient(log + message.join(" "), infoMessageColors);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
function outputGradient(text, colors) {
|
|
30
|
+
const gradient = HUDUtilityManager.generateGradientColors(colors, text.length);
|
|
31
|
+
let coloredText = "";
|
|
32
|
+
for (let i = 0; i < text.length; i++) {
|
|
33
|
+
const [r, g, b] = gradient[i];
|
|
34
|
+
coloredText += chalk.rgb(r, g, b)(text[i]);
|
|
35
|
+
}
|
|
36
|
+
console.log(coloredText);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
;
|
|
40
|
+
class FileTideDebugUtilityManager {
|
|
41
|
+
constructor() {
|
|
42
|
+
if (FileTideDebugUtilityManager.instance) {
|
|
43
|
+
return FileTideDebugUtilityManager.instance;
|
|
44
|
+
}
|
|
45
|
+
this.debugMode = false;
|
|
46
|
+
FileTideDebugUtilityManager.instance = this;
|
|
47
|
+
}
|
|
48
|
+
outputGradient(text, colors) {
|
|
49
|
+
outputGradient(text, colors);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
setDebugMode(mode) {
|
|
53
|
+
this.debugMode = mode;
|
|
54
|
+
}
|
|
55
|
+
log(type = "info", includeDate = false, ...message) {
|
|
56
|
+
if (!this.debugMode && type !== "error") {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (logHandler[type]) {
|
|
60
|
+
logHandler[type](includeDate, ...message);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
console.log(new Date().toLocaleString(), chalk.gray("Unknown log type ~ "), type, ...message);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const instance = new FileTideDebugUtilityManager();
|
|
67
|
+
module.exports = {
|
|
68
|
+
FileTideDebugUtilityManager: instance,
|
|
69
|
+
significantMessageColors,
|
|
70
|
+
noticeMessageColors,
|
|
71
|
+
errorMessageColors,
|
|
72
|
+
infoMessageColors
|
|
73
|
+
};
|
|
@@ -77,16 +77,23 @@ class FileTransferManager {
|
|
|
77
77
|
} = await fileHandle.read(Buffer.alloc(end - start), 0, end - start, start);
|
|
78
78
|
const transferState = this.activeTransfers.get(transferId);
|
|
79
79
|
chunkBuffer.set(chunkIndex, buffer);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
80
|
+
try {
|
|
81
|
+
while (chunkBuffer.has(nextExpectedChunk)) {
|
|
82
|
+
const nextChunkBuffer = chunkBuffer.get(nextExpectedChunk);
|
|
83
|
+
await onSendChunk(transferId, nextExpectedChunk, this.chunkSize, nextChunkBuffer, totalChunks, this.activeTransfers.get(transferId).completedChunks + 1);
|
|
84
|
+
chunkBuffer.delete(nextExpectedChunk);
|
|
85
|
+
nextExpectedChunk++;
|
|
86
|
+
transferState.transferredSize += this.chunkSize;
|
|
87
|
+
transferState.completedChunks++;
|
|
88
|
+
updateProgress();
|
|
89
|
+
}
|
|
90
|
+
if (transferState.completedChunks === transferState.totalChunks) {
|
|
91
|
+
return onComplete(transferId).then(() => {
|
|
92
|
+
this.activeTransfers.delete(transferId);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error(`[FileTide ~ Transporter] ~ Did not send chunk ${chunkIndex} ~ ${error.message}`);
|
|
90
97
|
return onComplete(transferId).then(() => {
|
|
91
98
|
this.activeTransfers.delete(transferId);
|
|
92
99
|
});
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const fs = require("fs");
|
|
4
3
|
const path = require("path");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const {
|
|
6
|
+
FileTransferTrackingManager
|
|
7
|
+
} = require("./FileTransferTrackingManager.js");
|
|
8
|
+
const {
|
|
9
|
+
FileTideDebugUtilityManager
|
|
10
|
+
} = require("./FileTideDebugUtilityManager.js");
|
|
5
11
|
const {
|
|
6
12
|
FileUtilityManager
|
|
7
13
|
} = require("./FileUtilityManager.js");
|
|
8
14
|
class FileTransferReceiverManager {
|
|
9
|
-
constructor() {
|
|
10
|
-
this.activeTransfers = new Map();
|
|
11
|
-
}
|
|
15
|
+
constructor() {}
|
|
12
16
|
async initializeTransfer(data, onError) {
|
|
13
17
|
const savePath = FileUtilityManager.getTidePath(path.join(data.path || data.filePath, data.fileName));
|
|
14
|
-
|
|
18
|
+
FileTideDebugUtilityManager.log("notice", true, `Initializing transfer ~ ${data.fileName} | ${savePath}...`);
|
|
19
|
+
if (FileTransferTrackingManager.containsTransfer(data.fileName)) {
|
|
20
|
+
FileTideDebugUtilityManager.log("notice", true, `Transfer ~ ${data.fileName} | ${savePath} already initialized.`);
|
|
15
21
|
return;
|
|
16
22
|
}
|
|
17
|
-
const totalChunks = data.totalChunks || Math.ceil(data.fileSize / (data.chunkSize || 512 * 1024));
|
|
18
|
-
const chunkSize = data.chunkSize || 512 * 1024;
|
|
19
23
|
try {
|
|
20
24
|
const dir = path.dirname(savePath);
|
|
21
25
|
if (!fs.existsSync(dir)) {
|
|
@@ -26,53 +30,58 @@ class FileTransferReceiverManager {
|
|
|
26
30
|
const fileStream = fs.createWriteStream(savePath, {
|
|
27
31
|
flags: "w"
|
|
28
32
|
});
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
fileInfo: data,
|
|
32
|
-
totalChunks,
|
|
33
|
-
fileStream,
|
|
34
|
-
chunkSize
|
|
35
|
-
});
|
|
33
|
+
FileTransferTrackingManager.trackTransfer(data, fileStream);
|
|
34
|
+
FileTideDebugUtilityManager.log("notice", true, `Initialized transfer ~ ${data.fileName} | ${savePath}!`);
|
|
36
35
|
} catch (error) {
|
|
36
|
+
FileTideDebugUtilityManager.log("error", true, `Did not initialize transfer ~ ${data.fileName} | ${savePath}.\n\t\t${error}`);
|
|
37
37
|
if (onError) {
|
|
38
38
|
onError(`[${data.fileName}] Did not initialize transfer ~ ${error.message}`);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
async handleTransferProgress(data, onError) {
|
|
43
|
-
let transferState =
|
|
43
|
+
let transferState = FileTransferTrackingManager.getTransfer(data.fileName);
|
|
44
44
|
if (!transferState) {
|
|
45
45
|
await this.initializeTransfer(data);
|
|
46
|
-
transferState =
|
|
46
|
+
transferState = tFileTransferTrackingManager.getTransfer(data.fileName);
|
|
47
47
|
}
|
|
48
48
|
const chunkBuffer = Buffer.from(data.fileChunk);
|
|
49
49
|
try {
|
|
50
50
|
transferState.fileStream.write(chunkBuffer);
|
|
51
51
|
transferState.receivedChunks.add(data.chunkIndex);
|
|
52
52
|
} catch (error) {
|
|
53
|
+
FileTideDebugUtilityManager.log("error", true, `Did not write chunk ${data.chunkIndex} ~ ${data.fileName}.\n\t\t${error}`);
|
|
53
54
|
if (onError) {
|
|
54
55
|
onError(`[${data.fileName}] Did not write chunk ${data.chunkIndex} ~ ${error.message}`);
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
async completeTransfer(data, onComplete) {
|
|
59
|
-
let transferState =
|
|
60
|
+
let transferState = FileTransferTrackingManager.getTransfer(data.fileName);
|
|
61
|
+
FileTideDebugUtilityManager.log("notice", true, `Completing transfer ~ ${data.fileName}...`);
|
|
60
62
|
if (!transferState) {
|
|
63
|
+
FileTideDebugUtilityManager.log("notice", true, `Did not get transfer state ~ ${data.fileName}...re-initializing....`);
|
|
61
64
|
await this.initializeTransfer(data);
|
|
62
|
-
transferState =
|
|
65
|
+
transferState = FileTransferTrackingManager.getTransfer(data.fileName);
|
|
63
66
|
}
|
|
64
67
|
try {
|
|
68
|
+
FileTideDebugUtilityManager.log("notice", true, `Verifying transfer state ~ ${data.fileName} completion (${transferState.receivedChunks.size}/${transferState.totalChunks})...`);
|
|
69
|
+
FileTideDebugUtilityManager.log("notice", true, `Transfer state ~ ${data.fileName} completed ~ (${transferState.receivedChunks.size === transferState.totalChunks}).`);
|
|
65
70
|
if (transferState.receivedChunks.size === transferState.totalChunks) {
|
|
66
71
|
transferState.fileStream.end();
|
|
67
72
|
console.log(`[${data.fileName}] Transfer complete. All chunks received and file written.`);
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
FileTransferTrackingManager.untrackTransfer(data.fileName);
|
|
74
|
+
FileTideDebugUtilityManager.log("notice", true, `Cleared transfer state ~ ${data.fileName}.`);
|
|
75
|
+
FileTransferTrackingManager.outputCurrentTransfers();
|
|
76
|
+
if (onComplete) onComplete(data, FileTransferTrackingManager.activeTransfers, true);
|
|
70
77
|
} else {
|
|
78
|
+
FileTideDebugUtilityManager.log("error", true, `Transfer incomplete. Received ${transferState.receivedChunks.size}/${transferState.totalChunks} chunks.`);
|
|
71
79
|
throw new Error(`[${data.fileName}] Transfer incomplete. Received ${transferState.receivedChunks.size}/${transferState.totalChunks} chunks.`);
|
|
72
80
|
}
|
|
73
81
|
} catch (error) {
|
|
82
|
+
FileTideDebugUtilityManager.log("error", true, `Transfer incomplete.\n\t\t${error}`);
|
|
74
83
|
if (onComplete) {
|
|
75
|
-
onComplete(data,
|
|
84
|
+
onComplete(data, FileTransferTrackingManager.activeTransfers, false, error);
|
|
76
85
|
}
|
|
77
86
|
}
|
|
78
87
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
FileTideDebugUtilityManager
|
|
5
|
+
} = require("./FileTideDebugUtilityManager.js");
|
|
6
|
+
class FileTransferTrackingManager {
|
|
7
|
+
constructor() {
|
|
8
|
+
if (FileTransferTrackingManager.instance) {
|
|
9
|
+
return FileTransferTrackingManager.instance;
|
|
10
|
+
}
|
|
11
|
+
this.activeTransfers = new Map();
|
|
12
|
+
FileTransferTrackingManager.instance = this;
|
|
13
|
+
}
|
|
14
|
+
trackTransfer(data, fileStream) {
|
|
15
|
+
FileTideDebugUtilityManager.log("notice", true, `Tracking transfer ~ ${data.fileName} | ${data.senderName}...`);
|
|
16
|
+
if (this.containsTransfer(data.fileName)) {
|
|
17
|
+
FileTideDebugUtilityManager.log("notice", true, `Transfer ~ ${data.fileName} | ${data.senderName} already tracked.`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const totalChunks = data.totalChunks || Math.ceil(data.fileSize / (data.chunkSize || 512 * 1024));
|
|
21
|
+
const chunkSize = data.chunkSize || 512 * 1024;
|
|
22
|
+
this.activeTransfers.set(data.fileName, {
|
|
23
|
+
receivedChunks: new Set(),
|
|
24
|
+
fileInfo: data,
|
|
25
|
+
totalChunks,
|
|
26
|
+
fileStream,
|
|
27
|
+
chunkSize
|
|
28
|
+
});
|
|
29
|
+
FileTideDebugUtilityManager.log("notice", true, `Tracked transfer ~ ${data.fileName} | ${data.senderName}!`);
|
|
30
|
+
}
|
|
31
|
+
updateTransfer(data) {
|
|
32
|
+
FileTideDebugUtilityManager.log("notice", true, `Updating tracked transfer ~ ${data.fileName} | ${data.senderName}...`);
|
|
33
|
+
if (!this.containsTransfer(data.fileName)) {
|
|
34
|
+
FileTideDebugUtilityManager.log("notice", true, `Transfer ~ ${data.fileName} | ${data.senderName} not tracked.`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const transferState = this.getTransfer(data.fileName);
|
|
38
|
+
transferState.receivedChunks.add(data.chunkIndex);
|
|
39
|
+
FileTideDebugUtilityManager.log("notice", true, `Updated tracked transfer ~ ${data.fileName} | ${data.senderName}!`);
|
|
40
|
+
}
|
|
41
|
+
containsTransfer(transferID) {
|
|
42
|
+
return this.activeTransfers.has(transferID);
|
|
43
|
+
}
|
|
44
|
+
getTransfer(transferID) {
|
|
45
|
+
return this.activeTransfers.get(transferID);
|
|
46
|
+
}
|
|
47
|
+
untrackTransfer(transferID) {
|
|
48
|
+
FileTideDebugUtilityManager.log("notice", true, `Untracking transfer ~ ${transferID}...`);
|
|
49
|
+
if (this.containsTransfer(transferID)) {
|
|
50
|
+
this.activeTransfers.delete(transferID);
|
|
51
|
+
FileTideDebugUtilityManager.log("notice", true, `Transfer ~ ${transferID} untracked!`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
FileTideDebugUtilityManager.log("notice", true, `Transfer ~ ${transferID} already untracked.`);
|
|
55
|
+
}
|
|
56
|
+
outputCurrentTransfers() {
|
|
57
|
+
if (this.activeTransfers.size === 0) {
|
|
58
|
+
FileTideDebugUtilityManager.log("notice", true, "No active file transfers.");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
FileTideDebugUtilityManager.log("notice", true, "Ongoing Transfers ~\n");
|
|
62
|
+
this.activeTransfers.forEach((transfer, fileName) => {
|
|
63
|
+
const {
|
|
64
|
+
totalChunks,
|
|
65
|
+
receivedChunks,
|
|
66
|
+
fileInfo
|
|
67
|
+
} = transfer;
|
|
68
|
+
const percentage = (receivedChunks.size / totalChunks * 100).toFixed(2);
|
|
69
|
+
FileTideDebugUtilityManager.log("notice", false, `\nFile Name ~ ${fileName}`);
|
|
70
|
+
FileTideDebugUtilityManager.log("notice", false, `File Path ~ ${fileInfo.path || fileInfo.filePath}`);
|
|
71
|
+
FileTideDebugUtilityManager.log("notice", false, `File Size ~ ${fileInfo.fileSize} bytes`);
|
|
72
|
+
FileTideDebugUtilityManager.log("notice", false, `Chunk Size ~ ${transfer.chunkSize} bytes`);
|
|
73
|
+
FileTideDebugUtilityManager.log("notice", false, `Total Chunks ~ ${totalChunks}`);
|
|
74
|
+
FileTideDebugUtilityManager.log("notice", false, `Received Chunks ~ ${receivedChunks.size}`);
|
|
75
|
+
FileTideDebugUtilityManager.log("notice", false, `Progress ~ ${percentage}%`);
|
|
76
|
+
});
|
|
77
|
+
FileTideDebugUtilityManager.log("notice", false, "=================================\n");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
;
|
|
81
|
+
const instance = new FileTransferTrackingManager();
|
|
82
|
+
module.exports = {
|
|
83
|
+
FileTransferTrackingManager: instance
|
|
84
|
+
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trap_stevo/filetide",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.53",
|
|
4
4
|
"description": "Revolutionizing real-time file transfer with seamless, instant communication across any device. Deliver files instantly, regardless of platform, and experience unparalleled speed and control in managing transfers. Elevate your file-sharing capabilities with a tool designed for precision, efficiency, and effortless connectivity.",
|
|
5
5
|
"main": "dist/cjs/FileTide.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "babel src -d dist/cjs --env-name cjs",
|
|
8
|
+
"start-file-generation": "node demos/FileGenerator.js",
|
|
8
9
|
"start-messager": "node demos/FileTideClientDemo.js",
|
|
9
10
|
"start-net": "node demos/FileTideNetDemo.js",
|
|
10
11
|
"start": "node dist/cjs/FileTide.js"
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
"author": "Steven Compton",
|
|
34
35
|
"license": "See License in LICENSE.md",
|
|
35
36
|
"dependencies": {
|
|
36
|
-
"@trap_stevo/iotide": "^0.0.
|
|
37
|
+
"@trap_stevo/iotide": "^0.0.41",
|
|
37
38
|
"@trap_stevo/iotide-client": "^0.0.23",
|
|
38
39
|
"@trap_stevo/legendarybuilderpronodejs-utilities": "^1.0.43",
|
|
39
40
|
"chalk": "^4.1.2",
|