@trap_stevo/filetide 0.0.38 → 0.0.39

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.
@@ -84,7 +84,7 @@ class FileMessager {
84
84
  * @param {String} fileName - The name of the file
85
85
  * @param {Number} chunkIndex - The index of the current chunk
86
86
  */
87
- sendFileChunkToClient(senderData, clientData, fileChunk, fileName, chunkIndex, totalChunks, filePath = process.cwd(), fileSize = 100) {
87
+ sendFileChunkToClient(senderData, clientData, fileChunk, fileName, chunkIndex, chunkSize, totalChunks, filePath = process.cwd(), fileSize = 100) {
88
88
  const senderClient = this.getClientFromID(senderData.id);
89
89
  const client = this.getClientFromID(clientData.id);
90
90
  if (!client) {
@@ -106,6 +106,7 @@ class FileMessager {
106
106
  fileName,
107
107
  fileChunk,
108
108
  chunkIndex,
109
+ chunkSize,
109
110
  path: filePath,
110
111
  fileSize
111
112
  });
@@ -173,6 +174,7 @@ class FileMessager {
173
174
  fileSize,
174
175
  filePath,
175
176
  chunkIndex,
177
+ chunkSize,
176
178
  totalChunks
177
179
  } = transferData;
178
180
  console.log(`Transferring file ~ ${fileName} | chunk ${chunkIndex + 1} of ${totalChunks} to client (${recipientId})`);
@@ -182,7 +184,7 @@ class FileMessager {
182
184
  }, {
183
185
  userID: recipientId,
184
186
  id: FileNetClientManager.getOnlineClient(recipientId).id
185
- }, fileChunk, fileName, chunkIndex, totalChunks, filePath, fileSize);
187
+ }, fileChunk, fileName, chunkIndex, chunkSize, totalChunks, filePath, fileSize);
186
188
  if (chunkIndex + 1 === totalChunks) {
187
189
  this.fileNet.emit("transfer-complete", {
188
190
  senderID,
@@ -154,7 +154,7 @@ class FileMessagerClient {
154
154
  });
155
155
  }
156
156
  this.transporter.sendFile(file, {
157
- onSendChunk: (transferId, chunkIndex, chunkData, totalChunks) => {
157
+ onSendChunk: (transferId, chunkIndex, chunkSize, chunkData, totalChunks) => {
158
158
  if (chunkIndex === 0) {
159
159
  this.progressBarManager.addTask({
160
160
  name: fileName,
@@ -169,6 +169,7 @@ class FileMessagerClient {
169
169
  fileChunk: chunkData,
170
170
  totalChunks,
171
171
  chunkIndex,
172
+ chunkSize,
172
173
  filePath,
173
174
  fileSize
174
175
  });
@@ -186,8 +187,8 @@ class FileMessagerClient {
186
187
  resolve();
187
188
  });
188
189
  },
189
- onProgress: progress => {
190
- this.progressBarManager.updateTaskProgress(fileName, 512 * 1024);
190
+ onProgress: (progress, chunkSize) => {
191
+ this.progressBarManager.updateTaskProgress(fileName, chunkSize);
191
192
  },
192
193
  originDetails: {
193
194
  recipientID: recipientId,
@@ -224,7 +225,7 @@ class FileMessagerClient {
224
225
  path: filePath
225
226
  });
226
227
  this.transporter.sendFile(file, {
227
- onSendChunk: (transferId, chunkIndex, chunkData, totalChunks) => {
228
+ onSendChunk: (transferId, chunkIndex, chunkSize, chunkData, totalChunks) => {
228
229
  if (chunkIndex === 0) {
229
230
  this.progressBarManager.addTask({
230
231
  name: fileName,
@@ -239,6 +240,7 @@ class FileMessagerClient {
239
240
  fileChunk: chunkData,
240
241
  totalChunks,
241
242
  chunkIndex,
243
+ chunkSize,
242
244
  filePath,
243
245
  fileSize
244
246
  });
@@ -256,8 +258,8 @@ class FileMessagerClient {
256
258
  resolve();
257
259
  });
258
260
  },
259
- onProgress: progress => {
260
- this.progressBarManager.updateTaskProgress(fileName, 512 * 1024);
261
+ onProgress: (progress, chunkSize) => {
262
+ this.progressBarManager.updateTaskProgress(fileName, chunkSize);
261
263
  },
262
264
  originDetails: {
263
265
  recipientID: recipientId,
@@ -12,6 +12,9 @@ const {
12
12
  significantMessageColors,
13
13
  errorMessageColors
14
14
  } = require("./HUDManagers/FileNetUtilityManager.js");
15
+ const {
16
+ FileTransferReceiverManager
17
+ } = require("./HUDManagers/FileTransferReceiverManager.js");
15
18
  const {
16
19
  FileNetConfigManager
17
20
  } = require("./HUDManagers/FileNetConfigManager.js");
@@ -266,7 +269,7 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
266
269
  return content;
267
270
  }
268
271
  });
269
- let activeTransfers = new Map();
272
+ const fileTransferReceiver = new FileTransferReceiverManager();
270
273
  client.clientTide.onEvent(userID, "current-online-clients", data => {
271
274
  const currentClients = {};
272
275
  Object.keys(data).forEach(key => {
@@ -325,14 +328,10 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
325
328
  this.progressBarManager.displayPage("Page Number:", "Press 'n' for next page, 'p' for previous page.", chalk.blue, chalk.magenta);
326
329
  this.progressBarManager.listenForInput("Page Number:", "Press 'n' for next page, 'p' for previous page.", chalk.blue, chalk.magenta, chalk.yellow);
327
330
  });
328
- client.clientTide.onEvent(userID, "incoming-file", data => {
331
+ client.clientTide.onEvent(userID, "incoming-file", async data => {
329
332
  try {
330
333
  _FileTide.outputGradient(`[${userID}] Preparing to receive file : ${data.fileName}`, significantMessageColors);
331
- activeTransfers.set(data.fileName, {
332
- receivedChunks: [],
333
- totalChunks: data.totalChunks,
334
- fileInfo: data
335
- });
334
+ await fileTransferReceiver.initializeTransfer(data);
336
335
  const saveDir = FileUtilityManager.getTidePath(data.path);
337
336
  const verifiedSender = data.senderID && data.senderID !== userID;
338
337
  if (verifiedSender) {
@@ -342,7 +341,7 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
342
341
  });
343
342
  }
344
343
  if (onIncomingFile) {
345
- onIncomingFile(verifiedSender, data, activeTransfers);
344
+ onIncomingFile(verifiedSender, data, fileTransferReceiver.activeTransfers);
346
345
  }
347
346
  if (verifiedSender && !fs.existsSync(saveDir)) {
348
347
  fs.mkdirSync(saveDir, {
@@ -366,17 +365,12 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
366
365
  onTransferBarrier(data);
367
366
  }
368
367
  });
369
- client.clientTide.onEvent(userID, "transfer-progress", data => {
368
+ client.clientTide.onEvent(userID, "transfer-progress", async data => {
370
369
  if (!data || data.fileChunk === undefined || data.fileChunk === null) {
371
370
  return;
372
371
  }
373
- const transferState = activeTransfers.get(data.fileName);
374
- if (!transferState) {
375
- return;
376
- }
377
- transferState.receivedChunks[data.chunkIndex] = Buffer.from(data.fileChunk);
378
- const progress = (data.chunkIndex + 1) / transferState.totalChunks * 100;
379
- this.progressBarManager.updateTaskProgress(data.fileName, 512 * 1024);
372
+ await fileTransferReceiver.handleTransferProgress(data);
373
+ this.progressBarManager.updateTaskProgress(data.fileName, data.chunkSize || 512 * 1024);
380
374
  if (onTransferProgress) {
381
375
  onTransferProgress(data);
382
376
  }
@@ -391,22 +385,24 @@ function _setupFileEventListeners(userID, client, onTransferProgress, onIncoming
391
385
  const savePath = FileUtilityManager.getTidePath(path.join(data.filePath, data.fileName));
392
386
  try {
393
387
  _FileTide.outputGradient(`[${userID}] File transfer complete : ${data.fileName}`, significantMessageColors);
394
- const transferState = activeTransfers.get(data.fileName);
388
+ const transferState = fileTransferReceiver.activeTransfers.get(data.fileName);
395
389
  if (!transferState) {
396
390
  return;
397
391
  }
398
- const fullFile = Buffer.concat(transferState.receivedChunks);
399
- fs.writeFileSync(savePath, fullFile);
400
- _FileTide.outputGradient(`[${userID}] File saved at : ${savePath}`, significantMessageColors);
401
- activeTransfers.delete(data.fileName);
402
- if (onTransferComplete) {
403
- onTransferComplete(data, activeTransfers, true);
404
- }
392
+ fileTransferReceiver.completeTransfer(data, (transferData, transfers, success) => {
393
+ if (success) {
394
+ _FileTide.outputGradient(`[${userID}] File saved at : ${savePath}\n`, significantMessageColors);
395
+ } else if (!success) {
396
+ _FileTide.outputGradient(`[${userID}] Did not save file at : ${savePath}\n`, errorMessageColors);
397
+ }
398
+ if (onTransferComplete) {
399
+ onTransferComplete(data, fileTransferReceiver.activeTransfers, success);
400
+ }
401
+ });
405
402
  } catch (error) {
406
403
  _FileTide.outputGradient(`[${userID}] Did not save file at : ${savePath}\n${error}`, errorMessageColors);
407
- activeTransfers.delete(data.fileName);
408
404
  if (onTransferComplete) {
409
- onTransferComplete(data, activeTransfers, false);
405
+ onTransferComplete(data, fileTransferReceiver.activeTransfers, false);
410
406
  }
411
407
  }
412
408
  });
@@ -41,7 +41,7 @@ function _startTransfer(file, transferId, fileDetails, onSendChunk, onComplete,
41
41
  const updateProgress = () => {
42
42
  const transferState = this.activeTransfers.get(transferId);
43
43
  if (onProgress) {
44
- onProgress(transferState.completedChunks / transferState.totalChunks * 100);
44
+ onProgress(transferState.completedChunks / transferState.totalChunks * 100, this.chunkSize);
45
45
  }
46
46
  };
47
47
  return new Promise((resolve, reject) => {
@@ -60,7 +60,7 @@ function _startTransfer(file, transferId, fileDetails, onSendChunk, onComplete,
60
60
  });
61
61
  }
62
62
  transferState.activeChunks++;
63
- onSendChunk(transferId, chunkIndex, chunk, transferState.totalChunks).then(() => {
63
+ onSendChunk(transferId, chunkIndex, this.chunkSize, chunk, transferState.totalChunks).then(() => {
64
64
  transferState.completedChunks++;
65
65
  transferState.activeChunks--;
66
66
  updateProgress();
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const {
6
+ FileUtilityManager
7
+ } = require("./FileUtilityManager.js");
8
+ class FileTransferReceiverManager {
9
+ constructor() {
10
+ this.activeTransfers = new Map();
11
+ }
12
+ async initializeTransfer(data, onError) {
13
+ const savePath = FileUtilityManager.getTidePath(path.join(data.path || data.filePath, data.fileName));
14
+ if (this.activeTransfers.has(data.fileName)) {
15
+ return;
16
+ }
17
+ const totalChunks = data.totalChunks || Math.ceil(data.fileSize / (data.chunkSize || 512 * 1024));
18
+ const chunkSize = data.chunkSize || 512 * 1024;
19
+ try {
20
+ const dir = path.dirname(savePath);
21
+ if (!fs.existsSync(dir)) {
22
+ fs.mkdirSync(dir, {
23
+ recursive: true
24
+ });
25
+ }
26
+ const fileStream = fs.createWriteStream(savePath, {
27
+ flags: "w"
28
+ });
29
+ this.activeTransfers.set(data.fileName, {
30
+ receivedChunks: new Set(),
31
+ fileInfo: data,
32
+ totalChunks,
33
+ fileStream,
34
+ chunkSize
35
+ });
36
+ } catch (error) {
37
+ if (onError) {
38
+ onError(`[${data.fileName}] Did not initialize transfer ~ ${error.message}`);
39
+ }
40
+ }
41
+ }
42
+ async handleTransferProgress(data, onError) {
43
+ let transferState = this.activeTransfers.get(data.fileName);
44
+ if (!transferState) {
45
+ await this.initializeTransfer(data);
46
+ transferState = this.activeTransfers.get(data.fileName);
47
+ }
48
+ const chunkBuffer = Buffer.from(data.fileChunk);
49
+ try {
50
+ transferState.fileStream.write(chunkBuffer);
51
+ transferState.receivedChunks.add(data.chunkIndex);
52
+ } catch (error) {
53
+ if (onError) {
54
+ onError(`[${data.fileName}] Did not write chunk ${data.chunkIndex} ~ ${error.message}`);
55
+ }
56
+ }
57
+ }
58
+ async completeTransfer(data, onComplete) {
59
+ let transferState = this.activeTransfers.get(data.fileName);
60
+ if (!transferState) {
61
+ await this.initializeTransfer(data);
62
+ transferState = this.activeTransfers.get(data.fileName);
63
+ }
64
+ try {
65
+ if (transferState.receivedChunks.size === transferState.totalChunks) {
66
+ transferState.fileStream.end();
67
+ console.log(`[${data.fileName}] Transfer complete. All chunks received and file written.`);
68
+ this.activeTransfers.delete(data.fileName);
69
+ if (onComplete) onComplete(data, this.activeTransfers, true);
70
+ } else {
71
+ throw new Error(`[${data.fileName}] Transfer incomplete. Received ${transferState.receivedChunks.size}/${transferState.totalChunks} chunks.`);
72
+ }
73
+ } catch (error) {
74
+ if (onComplete) {
75
+ onComplete(data, this.activeTransfers, false);
76
+ }
77
+ }
78
+ }
79
+ }
80
+ module.exports = {
81
+ FileTransferReceiverManager
82
+ };
@@ -292,7 +292,7 @@ class FileUtilityManager {
292
292
  for (const file of files) {
293
293
  const stats = await fs.promises.stat(file.path);
294
294
  if (stats.isFile()) {
295
- const fileData = FileUtilityManager.getFileData(file.path);
295
+ const fileData = await FileUtilityManager.getFileData(file.path);
296
296
  if (fileData) {
297
297
  filesData.push(fileData);
298
298
  }
@@ -310,22 +310,33 @@ class FileUtilityManager {
310
310
  * @param {string} inputFilePath - The full path to the file.
311
311
  * @returns {Object|null} - An object containing file data, name, path, and size or null if the file doesn't exist.
312
312
  */
313
- static getFileData(inputFilePath) {
313
+ static async getFileData(inputFilePath) {
314
314
  const filePath = this.getTidePath(inputFilePath);
315
315
  if (!fs.existsSync(filePath)) {
316
316
  console.log(`File at path ${filePath} not found.`);
317
317
  return null;
318
318
  }
319
- const fileData = fs.readFileSync(filePath, {
320
- encoding: null
321
- });
322
319
  const fileName = path.basename(filePath);
323
- return {
324
- size: fileData.length,
325
- fileName,
326
- fileData,
327
- filePath
328
- };
320
+ return new Promise((resolve, reject) => {
321
+ const fileStream = fs.createReadStream(filePath);
322
+ const chunks = [];
323
+ fileStream.on("data", chunk => {
324
+ chunks.push(chunk);
325
+ });
326
+ fileStream.on("end", () => {
327
+ const fileData = Buffer.concat(chunks);
328
+ resolve({
329
+ size: fileData.length,
330
+ fileName,
331
+ fileData,
332
+ filePath
333
+ });
334
+ });
335
+ fileStream.on("error", error => {
336
+ console.error(`Did not read file ${filePath}: `, error);
337
+ resolve(null);
338
+ });
339
+ });
329
340
  }
330
341
 
331
342
  /**
@@ -343,7 +354,7 @@ class FileUtilityManager {
343
354
  const stats = fs.statSync(currentInputPath);
344
355
  if (stats.isFile()) {
345
356
  return {
346
- content: this.getFileData(currentInputPath),
357
+ content: await this.getFileData(currentInputPath),
347
358
  type: "file"
348
359
  };
349
360
  } else if (stats.isDirectory()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trap_stevo/filetide",
3
- "version": "0.0.38",
3
+ "version": "0.0.39",
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": {