@trap_stevo/filetide 0.0.39 → 0.0.41

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.
@@ -4,6 +4,7 @@ function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a
4
4
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
5
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"); }
6
6
  const fs = require("fs");
7
+ const FileTransferRecoveryManager = require("./FileTransferRecoveryManager.js");
7
8
  var _FileTransferManager_brand = /*#__PURE__*/new WeakSet();
8
9
  class FileTransferManager {
9
10
  constructor({
@@ -17,25 +18,135 @@ class FileTransferManager {
17
18
  this.maxRetries = maxRetries;
18
19
  this.chunkSize = chunkSize;
19
20
  }
20
- sendFile(file, {
21
+ async sendFile(file, {
21
22
  fileDetails,
23
+ originDetails,
22
24
  onSendChunk,
23
25
  onComplete,
24
26
  onProgress,
25
27
  onStart
26
- }) {
28
+ }, clientTide) {
27
29
  const transferId = _assertClassBrand(_FileTransferManager_brand, this, _generateTransferId).call(this, fileDetails);
28
- return _assertClassBrand(_FileTransferManager_brand, this, _startTransfer).call(this, file, transferId, fileDetails, onSendChunk, onComplete, onProgress, onStart);
30
+ return await _assertClassBrand(_FileTransferManager_brand, this, _startTransfer).call(this, file, transferId, fileDetails, originDetails, onSendChunk, onComplete, onProgress, onStart, clientTide);
31
+ }
32
+ async sendLargeFile(fileHandle, {
33
+ fileDetails,
34
+ originDetails,
35
+ recipientID,
36
+ onSendChunk,
37
+ onComplete,
38
+ onProgress,
39
+ onStart,
40
+ onTiding
41
+ }, clientTide) {
42
+ const transferId = _assertClassBrand(_FileTransferManager_brand, this, _generateTransferId).call(this, fileDetails);
43
+ const recoveredTransferState = (await clientTide.emitEventWithResponse(originDetails.senderID, "get-client-transfer-state", "sent-current-transfer-state", {
44
+ recipientID,
45
+ senderID: originDetails.senderID,
46
+ filePath: fileDetails.destinationPath
47
+ }, 30000)) || {
48
+ transferredSize: 0,
49
+ lastChunkSent: 0
50
+ };
51
+ const totalChunks = Math.ceil(fileDetails.size / this.chunkSize);
52
+ this.activeTransfers.set(transferId, {
53
+ totalChunks,
54
+ transferredSize: recoveredTransferState.transferredSize,
55
+ completedChunks: recoveredTransferState.lastChunkSent,
56
+ activeChunks: 0,
57
+ failedChunks: new Map(),
58
+ currentChunk: recoveredTransferState.lastChunkSent,
59
+ size: fileDetails.size
60
+ });
61
+ const updateProgress = () => {
62
+ const transferState = this.activeTransfers.get(transferId);
63
+ if (onProgress) {
64
+ onProgress(transferState.completedChunks / transferState.totalChunks * 100, this.chunkSize);
65
+ }
66
+ };
67
+ const exponentialBackoff = retryCount => Math.min(1000 * 2 ** retryCount, 10000);
68
+ let nextExpectedChunk = recoveredTransferState.lastChunkSent;
69
+ const chunkBuffer = new Map();
70
+ const sendChunk = async chunkIndex => {
71
+ const start = chunkIndex * this.chunkSize;
72
+ const end = Math.min(start + this.chunkSize, fileDetails.size);
73
+ const {
74
+ buffer
75
+ } = await fileHandle.read(Buffer.alloc(end - start), 0, end - start, start);
76
+ const transferState = this.activeTransfers.get(transferId);
77
+ chunkBuffer.set(chunkIndex, buffer);
78
+ while (chunkBuffer.has(nextExpectedChunk)) {
79
+ const nextChunkBuffer = chunkBuffer.get(nextExpectedChunk);
80
+ await onSendChunk(transferId, nextExpectedChunk, this.chunkSize, nextChunkBuffer, totalChunks, this.activeTransfers.get(transferId).completedChunks + 1);
81
+ chunkBuffer.delete(nextExpectedChunk);
82
+ nextExpectedChunk++;
83
+ transferState.transferredSize += this.chunkSize;
84
+ transferState.completedChunks++;
85
+ updateProgress();
86
+ }
87
+ if (transferState.completedChunks === transferState.totalChunks) {
88
+ return onComplete(transferId).then(() => {
89
+ this.activeTransfers.delete(transferId);
90
+ });
91
+ }
92
+ };
93
+ const sendChunkBatch = async (startChunkIndex, batchSize = 100, miniBatchSize = 10) => {
94
+ for (let i = 0; i < batchSize && startChunkIndex + i < totalChunks; i += miniBatchSize) {
95
+ const miniBatchPromises = [];
96
+ for (let j = 0; j < miniBatchSize && startChunkIndex + i + j < totalChunks; j++) {
97
+ const chunkIndex = startChunkIndex + i + j;
98
+ miniBatchPromises.push(sendChunk(chunkIndex));
99
+ }
100
+ await Promise.all(miniBatchPromises);
101
+ await new Promise(resolve => setTimeout(resolve, 5));
102
+ }
103
+ };
104
+ const transferState = this.activeTransfers.get(transferId);
105
+ let currentBatchStart = transferState.currentChunk;
106
+ const keepAliveInterval = setInterval(() => {
107
+ if (onTiding) onTiding();
108
+ }, 5000);
109
+ try {
110
+ let adaptiveBatchSize = 100;
111
+ while (currentBatchStart < totalChunks) {
112
+ if (transferState.activeChunks < this.parallelChunks) {
113
+ adaptiveBatchSize = Math.min(adaptiveBatchSize + 10, 100);
114
+ } else {
115
+ adaptiveBatchSize = Math.max(adaptiveBatchSize - 10, 10);
116
+ }
117
+ await sendChunkBatch(currentBatchStart, adaptiveBatchSize);
118
+ currentBatchStart += adaptiveBatchSize;
119
+ await new Promise(resolve => setTimeout(resolve, 30));
120
+ }
121
+ } finally {
122
+ clearInterval(keepAliveInterval);
123
+ }
124
+ return new Promise((resolve, reject) => {
125
+ fileHandle.on("close", resolve);
126
+ fileHandle.on("error", error => {
127
+ this.activeTransfers.delete(transferId);
128
+ reject(error);
129
+ });
130
+ });
29
131
  }
30
132
  }
31
- function _startTransfer(file, transferId, fileDetails, onSendChunk, onComplete, onProgress, onStart) {
133
+ async function _startTransfer(file, transferId, fileDetails, originDetails, onSendChunk, onComplete, onProgress, onStart, clientTide) {
134
+ const recoveredTransferState = (await clientTide.emitEventWithResponse(originDetails.senderID, "get-client-transfer-state", "sent-current-transfer-state", {
135
+ recipientID: originDetails.recipientID,
136
+ senderID: originDetails.senderID,
137
+ filePath: fileDetails.destinationPath
138
+ }, 30000)) || {
139
+ transferredSize: 0,
140
+ lastChunkSent: 0
141
+ };
32
142
  const totalChunks = Math.ceil(file.length / this.chunkSize);
33
143
  this.activeTransfers.set(transferId, {
34
144
  totalChunks,
35
- completedChunks: 0,
145
+ transferredSize: recoveredTransferState.transferredSize,
146
+ completedChunks: recoveredTransferState.lastChunkSent,
36
147
  activeChunks: 0,
37
148
  failedChunks: new Map(),
38
- currentChunk: 0,
149
+ currentChunk: recoveredTransferState.lastChunkSent,
39
150
  size: fileDetails.size
40
151
  });
41
152
  const updateProgress = () => {
@@ -44,10 +155,13 @@ function _startTransfer(file, transferId, fileDetails, onSendChunk, onComplete,
44
155
  onProgress(transferState.completedChunks / transferState.totalChunks * 100, this.chunkSize);
45
156
  }
46
157
  };
158
+ const exponentialBackoff = retryCount => Math.min(1000 * 2 ** retryCount, 10000);
47
159
  return new Promise((resolve, reject) => {
48
- const sendChunk = chunkIndex => {
160
+ const sendChunk = async chunkIndex => {
49
161
  const transferState = this.activeTransfers.get(transferId);
50
- if (chunkIndex >= transferState.totalChunks) return;
162
+ if (chunkIndex >= transferState.totalChunks) {
163
+ return;
164
+ }
51
165
  const start = chunkIndex * this.chunkSize;
52
166
  const end = Math.min(start + this.chunkSize, file.length);
53
167
  const chunk = file.slice(start, end);
@@ -60,7 +174,8 @@ function _startTransfer(file, transferId, fileDetails, onSendChunk, onComplete,
60
174
  });
61
175
  }
62
176
  transferState.activeChunks++;
63
- onSendChunk(transferId, chunkIndex, this.chunkSize, chunk, transferState.totalChunks).then(() => {
177
+ try {
178
+ await onSendChunk(transferId, chunkIndex, this.chunkSize, chunk, transferState.totalChunks, transferState.completedChunks + 1);
64
179
  transferState.completedChunks++;
65
180
  transferState.activeChunks--;
66
181
  updateProgress();
@@ -68,23 +183,22 @@ function _startTransfer(file, transferId, fileDetails, onSendChunk, onComplete,
68
183
  sendChunk(transferState.currentChunk++);
69
184
  }
70
185
  if (transferState.completedChunks === transferState.totalChunks) {
71
- onComplete(transferId).then(() => {
72
- this.activeTransfers.delete(transferId);
73
- resolve();
74
- }).catch(reject);
186
+ await onComplete(transferId);
187
+ this.activeTransfers.delete(transferId);
188
+ resolve();
75
189
  }
76
- }).catch(error => {
77
- console.error(`Did not send chunk ${chunkIndex}: ${error.message}`);
190
+ } catch (error) {
191
+ console.error(`Did not send chunk ${chunkIndex} ~ ${error.message}`);
78
192
  transferState.activeChunks--;
79
- if (transferState.failedChunks.get(chunkIndex) >= this.maxRetries) {
193
+ const retryCount = (transferState.failedChunks.get(chunkIndex) || 0) + 1;
194
+ if (retryCount > this.maxRetries) {
80
195
  this.activeTransfers.delete(transferId);
81
196
  reject(new Error(`Did not send chunk ${chunkIndex} after ${this.maxRetries} retries.`));
82
197
  } else {
83
- const retryCount = (transferState.failedChunks.get(chunkIndex) || 0) + 1;
84
198
  transferState.failedChunks.set(chunkIndex, retryCount);
85
- sendChunk(chunkIndex);
199
+ setTimeout(() => sendChunk(chunkIndex), exponentialBackoff(retryCount));
86
200
  }
87
- });
201
+ }
88
202
  };
89
203
  const transferState = this.activeTransfers.get(transferId);
90
204
  for (let i = 0; i < Math.min(this.parallelChunks, transferState.totalChunks); i++) {
@@ -72,7 +72,7 @@ class FileTransferReceiverManager {
72
72
  }
73
73
  } catch (error) {
74
74
  if (onComplete) {
75
- onComplete(data, this.activeTransfers, false);
75
+ onComplete(data, this.activeTransfers, false, error);
76
76
  }
77
77
  }
78
78
  }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+
3
+ const path = require("path");
4
+ const fs = require("fs");
5
+ class FileTransferRecoveryManager {
6
+ constructor(storagePath = `${process.cwd()}/transfer_states`) {
7
+ if (FileTransferRecoveryManager.instance) {
8
+ return FileTransferRecoveryManager.instance;
9
+ }
10
+ this.storagePath = storagePath;
11
+ this.memoryStorage = new Map();
12
+ this.ensureStorageDirectory();
13
+ FileTransferRecoveryManager.instance = this;
14
+ }
15
+ ensureStorageDirectory() {
16
+ if (!fs.existsSync(this.storagePath)) {
17
+ fs.mkdirSync(this.storagePath, {
18
+ recursive: true
19
+ });
20
+ }
21
+ }
22
+ sanitizeFileName(fileName) {
23
+ return fileName.replace(/[^a-zA-Z0-9-_\.]/g, "-").replace(/-+/g, "-").trim();
24
+ }
25
+ generateKey(clientName, senderName, filePath) {
26
+ const normalizedPath = this.sanitizeFileName(filePath);
27
+ return `${clientName}_${senderName}_${normalizedPath}.json`;
28
+ }
29
+ getStorageFilePath(clientName, senderName, filePath) {
30
+ return path.join(this.storagePath, this.generateKey(clientName, senderName, filePath));
31
+ }
32
+ saveTransferState(clientName, senderName, filePath, chunkIndex, transferredSize) {
33
+ const key = this.generateKey(clientName, senderName, filePath);
34
+ const transferState = {
35
+ transferredSize,
36
+ senderName,
37
+ clientName,
38
+ filePath,
39
+ lastChunkSent: chunkIndex
40
+ };
41
+ this.memoryStorage.set(key, transferState);
42
+ }
43
+ saveToDisk(clientName, senderName, filePath) {
44
+ const key = this.generateKey(clientName, senderName, filePath);
45
+ const storageFile = this.getStorageFilePath(clientName, senderName, filePath);
46
+ const transferState = this.memoryStorage.get(key);
47
+ if (transferState) {
48
+ try {
49
+ fs.writeFileSync(storageFile, JSON.stringify(transferState, null, 2));
50
+ console.log(`Saved transfer state to disk: ${storageFile}`);
51
+ } catch (error) {
52
+ console.error(`Error saving transfer state for ${key}: ${error.message}`);
53
+ }
54
+ }
55
+ }
56
+ getTransferState(clientName, senderName, filePath) {
57
+ const key = this.generateKey(clientName, senderName, filePath);
58
+ if (this.memoryStorage.has(key)) {
59
+ return this.memoryStorage.get(key);
60
+ }
61
+ const storageFile = this.getStorageFilePath(clientName, senderName, filePath);
62
+ if (fs.existsSync(storageFile)) {
63
+ const transferState = JSON.parse(fs.readFileSync(storageFile, "utf-8"));
64
+ return transferState;
65
+ }
66
+ return null;
67
+ }
68
+ getLastChunk(clientName, senderName, filePath) {
69
+ const transferState = this.getTransferState(clientName, senderName, filePath);
70
+ return transferState ? transferState.lastChunkSent : null;
71
+ }
72
+ clearTransferState(clientName, senderName, filePath) {
73
+ const key = this.generateKey(clientName, senderName, filePath);
74
+ this.memoryStorage.delete(key);
75
+ const storageFile = this.getStorageFilePath(clientName, senderName, filePath);
76
+ if (fs.existsSync(storageFile)) {
77
+ fs.unlinkSync(storageFile);
78
+ }
79
+ }
80
+ flushToDisk() {
81
+ console.log(this.memoryStorage);
82
+ for (const [key, state] of this.memoryStorage.entries()) {
83
+ const {
84
+ clientName,
85
+ senderName,
86
+ filePath
87
+ } = state;
88
+ console.log("Saving current state ~ ", state);
89
+ this.saveToDisk(clientName, senderName, filePath);
90
+ }
91
+ ;
92
+ }
93
+ }
94
+ module.exports = new FileTransferRecoveryManager();
@@ -67,15 +67,18 @@ class FileUtilityManager {
67
67
  /**
68
68
  * Function to list all paths across the system using wildcard '*'.
69
69
  * @param {number} depth - The maximum depth limit (from the root). Defaults to 1.
70
+ * @param {Function} onDirectory - Callback that outputs each directory's contents on the go.
70
71
  * @returns {Promise<Array>} - A promise that resolves to an array of file and directory metadata across the system.
71
72
  */
72
- static async listAllPathsInOS(depth = 1) {
73
+ static async listAllPathsInOS(depth = 1, onDirectory, onFile) {
73
74
  const rootPaths = ["/", "C:/"];
74
75
  let allResults = [];
75
76
  const rootPromises = rootPaths.map(async rootPath => {
76
77
  if (await this.exists(rootPath)) {
77
- const subResult = await this.listPaths(rootPath, depth);
78
- allResults.push(...subResult.results);
78
+ const subResult = await this.listPaths(rootPath, depth, 0, onDirectory);
79
+ if (depth <= 3) {
80
+ allResults.push(...subResult.results);
81
+ }
79
82
  }
80
83
  });
81
84
  await Promise.all(rootPromises);
@@ -83,85 +86,114 @@ class FileUtilityManager {
83
86
  }
84
87
 
85
88
  /**
86
- * Function to list all paths and their metadata recursively.
87
- * @param {string} dir - The directory path to scan.
88
- * @param {number} maxDepth - The maximum depth limit (from the root). Defaults to 1.
89
- * @param {number} currentDepth - The current depth level. Starts at 0 (for the root).
90
- * @returns {Promise<object>} - A promise that resolves to an object containing a list of files/directories with metadata.
91
- */
92
- static async listPaths(dir, maxDepth = 1, currentDepth = 0) {
89
+ * Function to list all paths and their metadata recursively.
90
+ * @param {string} dir - The directory path to scan.
91
+ * @param {number} maxDepth - The maximum depth limit (from the root). Defaults to 1.
92
+ * @param {number} currentDepth - The current depth level. Starts at 0 (for the root).
93
+ * @param {Function} onDirectory - Callback that outputs each directory's contents on the go.
94
+ * @returns {Promise<object>} - A promise that resolves to an object containing a list of files/directories with metadata.
95
+ */
96
+ static async listPaths(dir, maxDepth = 1, currentDepth = 0, onDirectory, onContent) {
93
97
  let results = [];
94
- if (!maxDepth || currentDepth === undefined || currentDepth === null || currentDepth > maxDepth) {
98
+ if (currentDepth > maxDepth) {
95
99
  return {
96
100
  totalItems: 0,
97
101
  totalSize: 0,
98
102
  results
99
103
  };
100
104
  }
101
- const list = await fsAsync.readdir(dir, {
102
- withFileTypes: true
103
- });
104
- const stats = await fsAsync.stat(dir);
105
- const dirMetadata = {
106
- totalItems: 0,
107
- totalSize: 0,
108
- createdTime: stats.birthtime,
109
- lastModified: stats.mtime,
110
- type: "directory",
111
- path: dir
112
- };
113
- results.push(dirMetadata);
114
- const promises = list.map(async file => {
115
- const filePath = this.getTidePath(path.join(dir, file.name));
116
- try {
117
- if (file.isDirectory()) {
118
- const subDirResult = await this.listPaths(filePath, maxDepth, currentDepth + 1);
119
- dirMetadata.totalItems += subDirResult.totalItems;
120
- dirMetadata.totalSize += subDirResult.totalSize;
121
- results.push(...subDirResult.results);
122
- } else {
123
- const fileStats = await fsAsync.stat(filePath);
124
- const fileMetadata = {
125
- createdTime: fileStats.birthtime,
126
- lastModified: fileStats.mtime,
127
- size: fileStats.size,
128
- path: filePath,
129
- type: "file"
130
- };
131
- dirMetadata.totalSize += fileStats.size;
132
- dirMetadata.totalItems += 1;
133
- results.push(fileMetadata);
105
+ try {
106
+ const list = await fsAsync.readdir(dir, {
107
+ withFileTypes: true
108
+ });
109
+ const dirStats = await fsAsync.stat(dir);
110
+ const dirMetadata = {
111
+ totalItems: 0,
112
+ totalSize: 0,
113
+ createdTime: dirStats.birthtime,
114
+ lastModified: dirStats.mtime,
115
+ type: "directory",
116
+ path: dir
117
+ };
118
+ results.push(dirMetadata);
119
+ const processEntries = list.map(async file => {
120
+ const filePath = path.join(dir, file.name);
121
+ try {
122
+ if (file.isDirectory()) {
123
+ console.log(`[FileTide] Depth >> ${currentDepth} | Including directory ~ ${filePath}`);
124
+ const subDirResult = await this.listPaths(filePath, maxDepth, currentDepth + 1, onDirectory);
125
+ dirMetadata.totalItems += subDirResult.totalItems;
126
+ dirMetadata.totalSize += subDirResult.totalSize;
127
+ results.push(...subDirResult.results);
128
+ if (onDirectory) {
129
+ onDirectory(subDirResult.totalItems, subDirResult.results);
130
+ }
131
+ } else {
132
+ console.log(`[FileTide] Depth >> ${currentDepth} | Including file ~ ${filePath}`);
133
+ const fileStats = await fsAsync.stat(filePath);
134
+ const fileMetadata = {
135
+ createdTime: fileStats.birthtime,
136
+ lastModified: fileStats.mtime,
137
+ size: fileStats.size,
138
+ path: filePath,
139
+ type: "file"
140
+ };
141
+ dirMetadata.totalItems += 1;
142
+ dirMetadata.totalSize += fileStats.size;
143
+ results.push(fileMetadata);
144
+ }
145
+ } catch (error) {
146
+ if (error.code === "ENOENT") {
147
+ console.log(`[FileTide] Warning ~ File or directory not found - ${filePath}`);
148
+ } else {
149
+ console.log(`[FileTide] Error processing path ~ ${filePath} ~ `, error);
150
+ }
134
151
  }
135
- } catch (error) {
136
- console.log(`[FileTide] Path not found: ${filePath}`);
152
+ });
153
+ const concurrencyLimit = 5;
154
+ for (let i = 0; i < processEntries.length; i += concurrencyLimit) {
155
+ await Promise.all(processEntries.slice(i, i + concurrencyLimit));
137
156
  }
138
- });
139
- await Promise.all(promises);
140
- return {
141
- totalItems: dirMetadata.totalItems,
142
- totalSize: dirMetadata.totalSize,
143
- results
144
- };
157
+ return {
158
+ totalItems: dirMetadata.totalItems,
159
+ totalSize: dirMetadata.totalSize,
160
+ results
161
+ };
162
+ } catch (error) {
163
+ if (error.code === 'ENOENT') {
164
+ console.log(`[FileTide] Warning ~ Directory not found - ${dir}`);
165
+ } else {
166
+ console.log(`[FileTide] Error processing directory ~ ${dir} ~ `, error);
167
+ }
168
+ return {
169
+ totalItems: 0,
170
+ totalSize: 0,
171
+ results
172
+ };
173
+ }
145
174
  }
146
175
 
147
176
  /**
148
177
  * Allows for listing files in a specific directory or all files in the system '*'.
149
178
  * @param {Array} directories - Array of directories to scan or '*' for entire system.
150
179
  * @param {number} depth - The maximum depth limit (from the root). Defaults to 1.
180
+ * @param {Funtion} onDirectory - Callback that outputs each directory's contents on the go.
151
181
  * @returns {Promise<Array>} - A promise that resolves to an array of file and directory metadata from specified directories or the entire system.
152
182
  */
153
- static async listFiles(directories, depth = 1) {
183
+ static async listFiles(directories, depth = 1, onDirectory) {
154
184
  let fileList = [];
155
185
  if (directories.includes("*")) {
156
- fileList = await this.listAllPathsInOS(depth);
186
+ fileList = await this.listAllPathsInOS(depth, onDirectory);
157
187
  } else {
158
188
  const dirPromises = directories.map(async dir => {
159
189
  const currentDir = this.getTidePath(dir);
160
190
  if (await this.exists(currentDir)) {
161
- const subResult = await this.listPaths(currentDir, depth);
162
- fileList.push(...subResult.results);
191
+ const subResult = await this.listPaths(currentDir, depth, 0, onDirectory);
192
+ if (depth <= 3) {
193
+ fileList.push(...subResult.results);
194
+ }
163
195
  } else {
164
- console.warn(`Directory does not exist: ${currentDir}`);
196
+ console.warn(`Directory does not exist ~ ${currentDir}`);
165
197
  }
166
198
  });
167
199
  await Promise.all(dirPromises);
@@ -286,15 +318,28 @@ class FileUtilityManager {
286
318
  console.log(`Directory at path ${dirPath} not found.`);
287
319
  return [];
288
320
  }
321
+ const largeFileThreshold = 2 * 1024 * 1024 * 1024;
289
322
  const filesData = [];
290
323
  async function readDirectory(currentPath) {
291
324
  const files = await FileUtilityManager.filterFilesAndDirectories(currentPath, filterContent);
292
325
  for (const file of files) {
293
326
  const stats = await fs.promises.stat(file.path);
294
327
  if (stats.isFile()) {
295
- const fileData = await FileUtilityManager.getFileData(file.path);
296
- if (fileData) {
297
- filesData.push(fileData);
328
+ if (stats.size > largeFileThreshold) {
329
+ const currentFilePath = FileUtilityManager.getTidePath(file.path);
330
+ console.log(`Detected large file at ${currentFilePath}, size ~ ${stats.size} bytes.`);
331
+ filesData.push({
332
+ fileName: path.basename(currentFilePath),
333
+ filePath: currentFilePath,
334
+ fileSize: stats.size,
335
+ largeFile: true,
336
+ type: "file"
337
+ });
338
+ } else if (stats.size <= largeFileThreshold) {
339
+ const fileData = await FileUtilityManager.getFileData(file.path);
340
+ if (fileData) {
341
+ filesData.push(fileData);
342
+ }
298
343
  }
299
344
  } else if (stats.isDirectory()) {
300
345
  await readDirectory(file.path);
@@ -351,10 +396,22 @@ class FileUtilityManager {
351
396
  console.log(`Path at ${currentInputPath} not found.`);
352
397
  return null;
353
398
  }
399
+ const largeFileThreshold = 2 * 1024 * 1024 * 1024;
354
400
  const stats = fs.statSync(currentInputPath);
355
401
  if (stats.isFile()) {
402
+ if (stats.size > largeFileThreshold) {
403
+ console.log(`Detected large file at ${currentInputPath}, size ~ ${stats.size} bytes.`);
404
+ return {
405
+ fileName: path.basename(currentInputPath),
406
+ filePath: currentInputPath,
407
+ fileSize: stats.size,
408
+ largeFile: true,
409
+ type: "file"
410
+ };
411
+ }
356
412
  return {
357
413
  content: await this.getFileData(currentInputPath),
414
+ largeFile: false,
358
415
  type: "file"
359
416
  };
360
417
  } else if (stats.isDirectory()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trap_stevo/filetide",
3
- "version": "0.0.39",
3
+ "version": "0.0.41",
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": {
@@ -30,8 +30,8 @@
30
30
  "license": "See License in LICENSE.md",
31
31
  "dependencies": {
32
32
  "@trap_stevo/iotide": "^0.0.37",
33
- "@trap_stevo/iotide-client": "^0.0.20",
34
- "@trap_stevo/legendarybuilderpronodejs-utilities": "^1.0.40",
33
+ "@trap_stevo/iotide-client": "^0.0.23",
34
+ "@trap_stevo/legendarybuilderpronodejs-utilities": "^1.0.42",
35
35
  "chalk": "^4.1.2",
36
36
  "readline": "^1.3.0"
37
37
  },