فهرست منبع

Add support of 4GB files in browsers (#350)

* Add support of files bigger than 2 GB
Dmytro 2 سال پیش
والد
کامیت
a40198a4b6
6فایلهای تغییر یافته به همراه62 افزوده شده و 6 حذف شده
  1. 2 0
      .gitignore
  2. 1 0
      gramjs/client/fs-BROWSER.ts
  3. 45 2
      gramjs/client/uploads.ts
  4. 2 2
      package-lock.json
  5. 2 2
      package.json
  6. 10 0
      prepare_dist.sh

+ 2 - 0
.gitignore

@@ -21,3 +21,5 @@ example.d.ts
 settings
 
 /browser/
+
+.DS_STORE

+ 1 - 0
gramjs/client/fs-BROWSER.ts

@@ -2,6 +2,7 @@ export const promises = {
     lstat: (...args: any): any => {},
     stat: (...args: any): any => {},
     readFile: (...args: any): any => {},
+    open: (...args: any): any => {},
 };
 export const createWriteStream: any = {};
 export const WriteStream: any = {};

+ 45 - 2
gramjs/client/uploads.ts

@@ -56,11 +56,54 @@ export class CustomFile {
     }
 }
 
+interface CustomBufferOptions {
+    filePath?: string;
+    buffer?: Buffer;
+}
+
+class CustomBuffer {
+    constructor(private readonly options: CustomBufferOptions) {
+        if (!options.buffer && !options.filePath) {
+            throw new Error("Either one of `buffer` or `filePath` should be specified");
+        }
+    }
+
+    async slice(begin: number, end: number): Promise<Buffer> {
+        const { buffer, filePath } = this.options;
+        if (buffer) {
+            return buffer.slice(begin, end);
+        } else if (filePath) {
+            const buffSize = end - begin;
+            const buff = Buffer.alloc(buffSize);
+            const fHandle = await fs.open(filePath, 'r');
+            
+            await fHandle.read(buff, 0, buffSize, begin);
+            await fHandle.close();
+            
+            return Buffer.from(buff);
+        }
+
+        return Buffer.alloc(0);
+    }
+}
+
 const KB_TO_BYTES = 1024;
 const LARGE_FILE_THRESHOLD = 10 * 1024 * 1024;
 const UPLOAD_TIMEOUT = 15 * 1000;
 const DISCONNECT_SLEEP = 1000;
 
+async function getFileBuffer(file: File | CustomFile, fileSize: number): Promise<CustomBuffer> {
+    const isBiggerThan2Gb = fileSize > 2 ** 31 - 1;
+    const options: CustomBufferOptions = {};
+    if (isBiggerThan2Gb && file instanceof CustomFile) {
+        options.filePath = file.path;
+    } else {
+        options.buffer = Buffer.from(await fileToBuffer(file));
+    }
+
+    return new CustomBuffer(options);
+}
+
 /** @hidden */
 export async function uploadFile(
     client: TelegramClient,
@@ -75,7 +118,7 @@ export async function uploadFile(
 
     const partSize = getAppropriatedPartSize(bigInt(size)) * KB_TO_BYTES;
     const partCount = Math.floor((size + partSize - 1) / partSize);
-    const buffer = Buffer.from(await fileToBuffer(file));
+    const buffer = await getFileBuffer(file, size);
 
     // Make sure a new sender can be created before starting upload
     await client.getSender(client.session.dcId);
@@ -100,7 +143,7 @@ export async function uploadFile(
         }
 
         for (let j = i; j < end; j++) {
-            const bytes = buffer.slice(j * partSize, (j + 1) * partSize);
+            const bytes = await buffer.slice(j * partSize, (j + 1) * partSize);
 
             // eslint-disable-next-line no-loop-func
             sendingParts.push(

+ 2 - 2
package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "telegram",
-  "version": "2.9.0",
+  "version": "2.9.2",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "telegram",
-      "version": "2.9.0",
+      "version": "2.9.2",
       "license": "MIT",
       "dependencies": {
         "@cryptography/aes": "^0.1.1",

+ 2 - 2
package.json

@@ -1,6 +1,6 @@
 {
   "name": "telegram",
-  "version": "2.9.0",
+  "version": "2.9.2",
   "description": "NodeJS/Browser MTProto API Telegram client library,",
   "main": "index.js",
   "types": "index.d.ts",
@@ -67,4 +67,4 @@
     "node-localstorage": "^2.2.1",
     "socks": "^2.6.2"
   }
-}
+}

+ 10 - 0
prepare_dist.sh

@@ -0,0 +1,10 @@
+tsc
+cp package.json dist/
+cp README.md dist/
+cp LICENSE dist/
+
+mkdir -p dist/tl/static
+cp gramjs/tl/static/api.tl dist/tl/static/
+cp gramjs/tl/static/schema.tl dist/tl/static/
+cp gramjs/tl/api.d.ts dist/tl/
+cp gramjs/define.d.ts dist/