@mtkruto/browser 0.119.0 → 0.120.0
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/README.md +1 -1
- package/esm/0_errors.d.ts.map +1 -1
- package/esm/0_errors.js +9 -31
- package/esm/3_errors.js +2 -12
- package/esm/4_errors.js +2 -12
- package/esm/_dnt.polyfills.d.ts +0 -99
- package/esm/_dnt.polyfills.d.ts.map +1 -1
- package/esm/_dnt.polyfills.js +1 -127
- package/esm/client/0_abortable_loop.js +26 -39
- package/esm/client/0_storage_operations.js +179 -218
- package/esm/client/1_client_plain.js +4 -22
- package/esm/client/2_account_manager.js +140 -149
- package/esm/client/2_bot_info_manager.js +26 -38
- package/esm/client/2_business_connection_manager.js +10 -23
- package/esm/client/2_client_encrypted.js +198 -215
- package/esm/client/2_file_manager.js +255 -262
- package/esm/client/2_network_statistics_manager.js +31 -44
- package/esm/client/2_payment_manager.js +7 -20
- package/esm/client/2_reaction_manager.js +7 -20
- package/esm/client/2_translations_manager.js +101 -111
- package/esm/client/2_update_manager.js +750 -745
- package/esm/client/3_client_encrypted_pool.js +10 -26
- package/esm/client/3_message_manager.js +503 -508
- package/esm/client/3_video_chat_manager.js +57 -68
- package/esm/client/4_callback_query_manager.js +18 -30
- package/esm/client/4_chat_list_manager.js +140 -146
- package/esm/client/4_chat_manager.js +161 -169
- package/esm/client/4_checklist_manager.js +26 -39
- package/esm/client/4_context.js +244 -259
- package/esm/client/4_forum_manager.js +67 -73
- package/esm/client/4_gift_manager.js +22 -35
- package/esm/client/4_inline_query_manager.js +16 -28
- package/esm/client/4_link_preview_manager.js +6 -19
- package/esm/client/4_poll_manager.js +44 -57
- package/esm/client/4_story_manager.js +41 -53
- package/esm/client/5_composer.js +13 -26
- package/esm/client/6_client.js +866 -896
- package/esm/client/6_client_dispatcher.js +308 -325
- package/esm/client/7_client_worker.js +16 -29
- package/esm/connection/1_connection_tcp.js +55 -82
- package/esm/connection/1_connection_web_socket.js +75 -91
- package/esm/deps/jsr.io/@roj/tgcrypto/1.0.1/dist/tgcrypto.js +3 -11
- package/esm/deps/jsr.io/@std/async/1.2.0/mux_async_iterator.js +31 -47
- package/esm/deps/jsr.io/@std/async/1.2.0/tee.js +11 -34
- package/esm/deps/jsr.io/@std/cache/0.2.2/lru_cache.js +30 -47
- package/esm/deps/jsr.io/@std/datetime/0.225.7/_date_time_formatter.js +4 -17
- package/esm/session/0_session_state.js +12 -38
- package/esm/session/1_session.js +49 -72
- package/esm/session/2_session_encrypted.js +422 -420
- package/esm/storage/2_storage_indexed_db.js +26 -44
- package/esm/storage/2_storage_local_storage.js +3 -16
- package/esm/storage/2_storage_memory.js +24 -41
- package/esm/storage/2_storage_session_storage.js +3 -16
- package/esm/tl/1_tl_reader.d.ts +1 -1
- package/esm/tl/1_tl_reader.d.ts.map +1 -1
- package/esm/tl/1_tl_reader.js +95 -103
- package/esm/tl/1_tl_writer.js +169 -178
- package/esm/transport/0_transport.js +1 -8
- package/esm/transport/1_transport_abridged.js +11 -24
- package/esm/transport/1_transport_intermediate.js +10 -23
- package/esm/utilities/0_mutex.js +4 -19
- package/esm/utilities/0_part_stream.js +11 -25
- package/esm/utilities/1_crypto.js +42 -53
- package/esm/utilities/2_queue.js +29 -47
- package/package.json +1 -1
- package/script/0_errors.d.ts.map +1 -1
- package/script/0_errors.js +9 -31
- package/script/3_errors.js +2 -12
- package/script/4_errors.js +2 -12
- package/script/_dnt.polyfills.d.ts +0 -99
- package/script/_dnt.polyfills.d.ts.map +1 -1
- package/script/_dnt.polyfills.js +0 -128
- package/script/client/0_abortable_loop.js +27 -40
- package/script/client/0_storage_operations.js +179 -218
- package/script/client/1_client_plain.js +4 -22
- package/script/client/2_account_manager.js +140 -149
- package/script/client/2_bot_info_manager.js +26 -38
- package/script/client/2_business_connection_manager.js +10 -23
- package/script/client/2_client_encrypted.js +199 -216
- package/script/client/2_file_manager.js +255 -262
- package/script/client/2_network_statistics_manager.js +32 -45
- package/script/client/2_payment_manager.js +7 -20
- package/script/client/2_reaction_manager.js +7 -20
- package/script/client/2_translations_manager.js +102 -112
- package/script/client/2_update_manager.js +750 -745
- package/script/client/3_client_encrypted_pool.js +10 -26
- package/script/client/3_message_manager.js +503 -508
- package/script/client/3_video_chat_manager.js +57 -68
- package/script/client/4_callback_query_manager.js +18 -30
- package/script/client/4_chat_list_manager.js +140 -146
- package/script/client/4_chat_manager.js +161 -169
- package/script/client/4_checklist_manager.js +26 -39
- package/script/client/4_context.js +244 -259
- package/script/client/4_forum_manager.js +67 -73
- package/script/client/4_gift_manager.js +22 -35
- package/script/client/4_inline_query_manager.js +16 -28
- package/script/client/4_link_preview_manager.js +6 -19
- package/script/client/4_poll_manager.js +44 -57
- package/script/client/4_story_manager.js +41 -53
- package/script/client/5_composer.js +13 -26
- package/script/client/6_client.js +866 -896
- package/script/client/6_client_dispatcher.js +308 -325
- package/script/client/7_client_worker.js +16 -29
- package/script/connection/1_connection_tcp.js +55 -82
- package/script/connection/1_connection_web_socket.js +75 -91
- package/script/deps/jsr.io/@roj/tgcrypto/1.0.1/dist/tgcrypto.js +3 -11
- package/script/deps/jsr.io/@std/async/1.2.0/mux_async_iterator.js +31 -47
- package/script/deps/jsr.io/@std/async/1.2.0/tee.js +11 -34
- package/script/deps/jsr.io/@std/cache/0.2.2/lru_cache.js +30 -47
- package/script/deps/jsr.io/@std/datetime/0.225.7/_date_time_formatter.js +4 -17
- package/script/session/0_session_state.js +12 -38
- package/script/session/1_session.js +49 -72
- package/script/session/2_session_encrypted.js +423 -421
- package/script/storage/2_storage_indexed_db.js +26 -44
- package/script/storage/2_storage_local_storage.js +3 -16
- package/script/storage/2_storage_memory.js +24 -41
- package/script/storage/2_storage_session_storage.js +3 -16
- package/script/tl/1_tl_reader.d.ts +1 -1
- package/script/tl/1_tl_reader.d.ts.map +1 -1
- package/script/tl/1_tl_reader.js +96 -104
- package/script/tl/1_tl_writer.js +170 -179
- package/script/transport/0_transport.js +1 -8
- package/script/transport/1_transport_abridged.js +11 -24
- package/script/transport/1_transport_intermediate.js +10 -23
- package/script/utilities/0_mutex.js +4 -19
- package/script/utilities/0_part_stream.js +11 -25
- package/script/utilities/1_crypto.js +43 -54
- package/script/utilities/2_queue.js +30 -48
|
@@ -18,18 +18,7 @@
|
|
|
18
18
|
* You should have received a copy of the GNU Lesser General Public License
|
|
19
19
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
20
20
|
*/
|
|
21
|
-
var
|
|
22
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
23
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
24
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
25
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
26
|
-
};
|
|
27
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
28
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
29
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
30
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
31
|
-
};
|
|
32
|
-
var _FileManager_instances, _a, _FileManager_c, _FileManager_Lupload, _FileManager_UPLOAD_MAX_CHUNK_SIZE, _FileManager_BIG_FILE_THRESHOLD, _FileManager_progressIds, _FileManager_uploadStream, _FileManager_uploadBuffer, _FileManager_uploadPart, _FileManager_handleError, _FileManager_getFileContents, _FileManager_CUSTOM_EMOJI_TTL;
|
|
21
|
+
var _a;
|
|
33
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
23
|
exports.FileManager = void 0;
|
|
35
24
|
const _0_deps_js_1 = require("../0_deps.js");
|
|
@@ -43,53 +32,54 @@ const _4_constants_js_1 = require("../4_constants.js");
|
|
|
43
32
|
const _4_errors_js_1 = require("../4_errors.js");
|
|
44
33
|
const _0_utilities_js_1 = require("./0_utilities.js");
|
|
45
34
|
class FileManager {
|
|
35
|
+
#c;
|
|
36
|
+
#Lupload;
|
|
37
|
+
static #UPLOAD_MAX_CHUNK_SIZE = 512 * _1_utilities_js_1.kilobyte;
|
|
38
|
+
static #BIG_FILE_THRESHOLD = 10 * _1_utilities_js_1.megabyte;
|
|
46
39
|
constructor(c) {
|
|
47
|
-
|
|
48
|
-
_FileManager_c.set(this, void 0);
|
|
49
|
-
_FileManager_Lupload.set(this, void 0);
|
|
50
|
-
_FileManager_progressIds.set(this, new Set());
|
|
51
|
-
__classPrivateFieldSet(this, _FileManager_c, c, "f");
|
|
40
|
+
this.#c = c;
|
|
52
41
|
const L = (0, _1_utilities_js_1.getLogger)("FileManager").client(c.id);
|
|
53
|
-
|
|
42
|
+
this.#Lupload = L.branch("upload");
|
|
54
43
|
}
|
|
44
|
+
#progressIds = new Set();
|
|
55
45
|
getProgressId() {
|
|
56
46
|
let id;
|
|
57
47
|
do {
|
|
58
48
|
id = (0, _1_utilities_js_1.getRandomId)();
|
|
59
|
-
} while (id === 0n ||
|
|
60
|
-
|
|
49
|
+
} while (id === 0n || this.#progressIds.has(id));
|
|
50
|
+
this.#progressIds.add(id);
|
|
61
51
|
return Promise.resolve(String(id));
|
|
62
52
|
}
|
|
63
53
|
async upload(file, params, checkName, allowStream = true) {
|
|
64
|
-
if (params?.progressId !== undefined && !
|
|
54
|
+
if (params?.progressId !== undefined && !this.#progressIds.has(BigInt(params.progressId))) {
|
|
65
55
|
throw new _0_errors_js_1.InputError("Invalid progressId.");
|
|
66
56
|
}
|
|
67
57
|
if (params?.progressId !== undefined) {
|
|
68
|
-
|
|
58
|
+
this.#progressIds.delete(BigInt(params.progressId));
|
|
69
59
|
}
|
|
70
|
-
let { size, name, contents } = await
|
|
60
|
+
let { size, name, contents } = await _a.#getFileContents(file, params, allowStream);
|
|
71
61
|
if (checkName) {
|
|
72
62
|
name = checkName(name);
|
|
73
63
|
}
|
|
74
64
|
if (size === 0 || size < -1) {
|
|
75
65
|
throw new _0_errors_js_1.InputError("Invalid file size.");
|
|
76
66
|
}
|
|
77
|
-
const poolSize = await
|
|
78
|
-
const chunkSize = params?.chunkSize ??
|
|
79
|
-
_a.validateChunkSize(chunkSize,
|
|
67
|
+
const poolSize = await this.#c.getUploadPoolSize();
|
|
68
|
+
const chunkSize = params?.chunkSize ?? _a.#UPLOAD_MAX_CHUNK_SIZE;
|
|
69
|
+
_a.validateChunkSize(chunkSize, _a.#UPLOAD_MAX_CHUNK_SIZE);
|
|
80
70
|
const mustTrackProgress = params?.progressId !== undefined;
|
|
81
71
|
const fileId = params?.progressId !== undefined ? BigInt(params.progressId) : (0, _1_utilities_js_1.getRandomId)();
|
|
82
|
-
const isBig = contents instanceof Uint8Array ? contents.length >
|
|
72
|
+
const isBig = contents instanceof Uint8Array ? contents.length > _a.#BIG_FILE_THRESHOLD : true;
|
|
83
73
|
const whatIsUploaded = contents instanceof Uint8Array ? (isBig ? "big file" : "file") + " of size " + size : "stream";
|
|
84
|
-
|
|
74
|
+
this.#Lupload.debug("uploading " + whatIsUploaded + " with chunk size of " + chunkSize + " and pool size of " + poolSize + " and file ID of " + fileId);
|
|
85
75
|
let result;
|
|
86
76
|
if (contents instanceof Uint8Array) {
|
|
87
|
-
result = await
|
|
77
|
+
result = await this.#uploadBuffer(contents, fileId, mustTrackProgress, chunkSize, poolSize, params?.signal);
|
|
88
78
|
}
|
|
89
79
|
else {
|
|
90
|
-
result = await
|
|
80
|
+
result = await this.#uploadStream(contents, fileId, mustTrackProgress, chunkSize, poolSize, params?.signal);
|
|
91
81
|
}
|
|
92
|
-
|
|
82
|
+
this.#Lupload.debug(`[${fileId}] uploaded ` + result.parts + " part(s)");
|
|
93
83
|
if (checkName) {
|
|
94
84
|
name = checkName(name, result.firstPart);
|
|
95
85
|
}
|
|
@@ -100,15 +90,232 @@ class FileManager {
|
|
|
100
90
|
return { _: "inputFileBig", id: fileId, name, parts: result.parts };
|
|
101
91
|
}
|
|
102
92
|
}
|
|
93
|
+
async #uploadStream(stream, fileId, mustTrackProgress, chunkSize, poolSize, signal) {
|
|
94
|
+
let part;
|
|
95
|
+
let promises = new Array();
|
|
96
|
+
let ms = 0.05;
|
|
97
|
+
let uploaded = 0;
|
|
98
|
+
let firstPart;
|
|
99
|
+
for await (part of (0, _1_utilities_js_1.iterateReadableStream)(stream.pipeThrough(new _1_utilities_js_1.PartStream(chunkSize)))) {
|
|
100
|
+
if (!part.isSmall && part.part > 0) {
|
|
101
|
+
await (0, _0_deps_js_1.delay)(ms);
|
|
102
|
+
ms = Math.max(ms * .8, 0.003);
|
|
103
|
+
}
|
|
104
|
+
if (!firstPart) {
|
|
105
|
+
firstPart = part.bytes;
|
|
106
|
+
}
|
|
107
|
+
promises.push(this.#uploadPart(fileId, part.totalParts, !part.isSmall, part.part, part.bytes, signal).then(() => {
|
|
108
|
+
if (mustTrackProgress) {
|
|
109
|
+
uploaded += part.bytes.length;
|
|
110
|
+
this.#c.handleUpdate({
|
|
111
|
+
uploadProgress: {
|
|
112
|
+
id: String(fileId),
|
|
113
|
+
uploaded,
|
|
114
|
+
total: 0,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}));
|
|
119
|
+
if (promises.length === poolSize * _0_utilities_js_1.UPLOAD_REQUEST_PER_CONNECTION) {
|
|
120
|
+
await Promise.all(promises);
|
|
121
|
+
promises = [];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
await Promise.all(promises);
|
|
125
|
+
return { isSmall: part.isSmall, parts: part.totalParts, firstPart };
|
|
126
|
+
}
|
|
127
|
+
async #uploadBuffer(buffer, fileId, mustTrackProgress, chunkSize, poolSize, signal) {
|
|
128
|
+
const isBig = buffer.byteLength > _a.#BIG_FILE_THRESHOLD;
|
|
129
|
+
const partCount = Math.ceil(buffer.byteLength / chunkSize);
|
|
130
|
+
let promises = new Array();
|
|
131
|
+
let started = false;
|
|
132
|
+
let ms = 0.05;
|
|
133
|
+
let uploaded = 0;
|
|
134
|
+
let firstPart;
|
|
135
|
+
main: for (let part = 0; part < partCount;) {
|
|
136
|
+
for (let i = 0; i < poolSize; ++i) {
|
|
137
|
+
for (let i = 0; i < _0_utilities_js_1.UPLOAD_REQUEST_PER_CONNECTION; ++i) {
|
|
138
|
+
const start = part * chunkSize;
|
|
139
|
+
const end = start + chunkSize;
|
|
140
|
+
const bytes = buffer.subarray(start, end);
|
|
141
|
+
if (!bytes.length) {
|
|
142
|
+
break main;
|
|
143
|
+
}
|
|
144
|
+
if (!started) {
|
|
145
|
+
started = true;
|
|
146
|
+
}
|
|
147
|
+
else if (isBig && part > 0) {
|
|
148
|
+
await (0, _0_deps_js_1.delay)(ms);
|
|
149
|
+
ms = Math.max(ms * .8, 0.003);
|
|
150
|
+
}
|
|
151
|
+
if (!firstPart) {
|
|
152
|
+
firstPart = bytes;
|
|
153
|
+
}
|
|
154
|
+
promises.push(this.#uploadPart(fileId, partCount, isBig, part++, bytes, signal).then(() => {
|
|
155
|
+
if (mustTrackProgress) {
|
|
156
|
+
uploaded += bytes.length;
|
|
157
|
+
this.#c.handleUpdate({
|
|
158
|
+
uploadProgress: {
|
|
159
|
+
id: String(fileId),
|
|
160
|
+
uploaded,
|
|
161
|
+
total: buffer.length,
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}));
|
|
166
|
+
if (promises.length === poolSize * _0_utilities_js_1.UPLOAD_REQUEST_PER_CONNECTION) {
|
|
167
|
+
await Promise.all(promises);
|
|
168
|
+
promises = [];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
await Promise.all(promises);
|
|
173
|
+
promises = [];
|
|
174
|
+
}
|
|
175
|
+
await Promise.all(promises);
|
|
176
|
+
return { isSmall: !isBig, parts: partCount, firstPart };
|
|
177
|
+
}
|
|
178
|
+
async #uploadPart(fileId, partCount, isBig, index, bytes, signal) {
|
|
179
|
+
let retryIn = 1;
|
|
180
|
+
let errorCount = 0;
|
|
181
|
+
while (true) {
|
|
182
|
+
try {
|
|
183
|
+
signal?.throwIfAborted();
|
|
184
|
+
this.#Lupload.debug(`[${fileId}] uploading part ` + (index + 1));
|
|
185
|
+
if (isBig) {
|
|
186
|
+
await this.#c.invoke({ _: "upload.saveBigFilePart", file_id: fileId, file_part: index, bytes, file_total_parts: partCount }, { type: "upload" });
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
await this.#c.invoke({ _: "upload.saveFilePart", file_id: fileId, bytes, file_part: index }, { type: "upload" });
|
|
190
|
+
}
|
|
191
|
+
this.#Lupload.debug(`[${fileId}] uploaded part ` + (index + 1));
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
signal?.throwIfAborted();
|
|
196
|
+
this.#Lupload.debug(`[${fileId}] failed to upload part ` + (index + 1));
|
|
197
|
+
++errorCount;
|
|
198
|
+
if (errorCount > 20) {
|
|
199
|
+
retryIn = 0;
|
|
200
|
+
errorCount = 20;
|
|
201
|
+
}
|
|
202
|
+
await this.#handleError(err, retryIn, `[${fileId}-${index + 1}]`);
|
|
203
|
+
retryIn += 2;
|
|
204
|
+
if (retryIn > 11) {
|
|
205
|
+
retryIn = 11;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async #handleError(err, retryIn, logPrefix) {
|
|
211
|
+
if (err instanceof _3_errors_js_1.TimeTooBig || err instanceof _3_errors_js_1.TimeTooSmall) {
|
|
212
|
+
throw err;
|
|
213
|
+
}
|
|
214
|
+
else if (err instanceof _4_errors_js_1.FloodWait) {
|
|
215
|
+
this.#Lupload.warning(`${logPrefix} retrying in ${err.seconds} seconds:`, err);
|
|
216
|
+
await (0, _0_deps_js_1.delay)(err.seconds * _0_deps_js_1.SECOND);
|
|
217
|
+
}
|
|
218
|
+
else if (retryIn > 0) {
|
|
219
|
+
this.#Lupload.warning(`${logPrefix} retrying in ${retryIn} seconds:`, err);
|
|
220
|
+
await (0, _0_deps_js_1.delay)(retryIn * _0_deps_js_1.SECOND);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
throw err;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
static async #getFileContents(source, params, allowStream) {
|
|
227
|
+
let name = params?.fileName?.trim() || "file";
|
|
228
|
+
let contents;
|
|
229
|
+
let size = -1;
|
|
230
|
+
if (source instanceof Uint8Array) {
|
|
231
|
+
contents = source;
|
|
232
|
+
size = source.byteLength;
|
|
233
|
+
}
|
|
234
|
+
else if (source instanceof ReadableStream) {
|
|
235
|
+
if (!allowStream) {
|
|
236
|
+
throw new _0_errors_js_1.InputError("Streamed upload not allowed.");
|
|
237
|
+
}
|
|
238
|
+
contents = source;
|
|
239
|
+
}
|
|
240
|
+
else if (typeof source === "object" && source !== null && (Symbol.iterator in source || Symbol.asyncIterator in source)) {
|
|
241
|
+
if (!allowStream) {
|
|
242
|
+
throw new _0_errors_js_1.InputError("Streamed upload not allowed.");
|
|
243
|
+
}
|
|
244
|
+
contents = new ReadableStream({
|
|
245
|
+
pull: Symbol.asyncIterator in source
|
|
246
|
+
? async (controller) => {
|
|
247
|
+
const { value, done } = await source.next();
|
|
248
|
+
done ? controller.close() : controller.enqueue(value);
|
|
249
|
+
}
|
|
250
|
+
: (controller) => {
|
|
251
|
+
const { value, done } = source.next();
|
|
252
|
+
done ? controller.close() : controller.enqueue(value);
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
let url;
|
|
258
|
+
try {
|
|
259
|
+
url = new URL(source).toString();
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
let path_;
|
|
263
|
+
if (typeof source === "string") {
|
|
264
|
+
if ((0, _0_deps_js_1.isAbsolute)(source)) {
|
|
265
|
+
path_ = source;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
// @ts-ignore: lib
|
|
269
|
+
path_ = (0, _0_deps_js_1.join)(Deno.cwd(), source);
|
|
270
|
+
}
|
|
271
|
+
url = (0, _0_deps_js_1.toFileUrl)(path_).toString();
|
|
272
|
+
name = (0, _0_deps_js_1.basename)(path_);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
(0, _0_deps_js_1.unreachable)();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const response = await fetch(url);
|
|
279
|
+
if (response.body === null) {
|
|
280
|
+
throw new _0_errors_js_1.InputError("Invalid response");
|
|
281
|
+
}
|
|
282
|
+
if (name === "file") {
|
|
283
|
+
const contentType = response.headers.get("content-type")?.split(";")[0].trim();
|
|
284
|
+
if (contentType) {
|
|
285
|
+
name += (0, _0_deps_js_1.extension)(contentType);
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
const maybeFileName = new URL(response.url).pathname.split("/")
|
|
289
|
+
.filter((v) => v)
|
|
290
|
+
.slice(-1)[0]
|
|
291
|
+
.trim();
|
|
292
|
+
if (maybeFileName) {
|
|
293
|
+
name += (0, _0_deps_js_1.extension)((0, _0_deps_js_1.extname)(maybeFileName));
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
const contentLength = Number(response.headers.get("content-length"));
|
|
298
|
+
if (contentLength && !isNaN(contentLength)) {
|
|
299
|
+
size = contentLength;
|
|
300
|
+
}
|
|
301
|
+
if (allowStream) {
|
|
302
|
+
contents = response.body;
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
contents = new Uint8Array(await response.arrayBuffer());
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return { size: params?.fileSize ? params.fileSize : size, name, contents };
|
|
309
|
+
}
|
|
103
310
|
async *downloadInner(location, dcId, params) {
|
|
104
311
|
const signal = params?.signal;
|
|
105
312
|
signal?.throwIfAborted();
|
|
106
313
|
const id = "id" in location ? location.id : "photo_id" in location ? location.photo_id : null;
|
|
107
|
-
if (id !== null &&
|
|
108
|
-
const file = await
|
|
314
|
+
if (id !== null && this.#c.storage.supportsFiles) {
|
|
315
|
+
const file = await this.#c.storage.getFile(id);
|
|
109
316
|
const partOffset = file === null ? 0 : params?.offset ? Math.ceil(10 / file[1]) - 1 : 0;
|
|
110
317
|
if (file !== null && file[0] > 0) {
|
|
111
|
-
yield*
|
|
318
|
+
yield* this.#c.storage.iterFileParts(id, file[0], partOffset, signal);
|
|
112
319
|
return;
|
|
113
320
|
}
|
|
114
321
|
}
|
|
@@ -128,18 +335,18 @@ class FileManager {
|
|
|
128
335
|
let retryIn = 1;
|
|
129
336
|
let errorCount = 0;
|
|
130
337
|
try {
|
|
131
|
-
const file = await
|
|
338
|
+
const file = await this.#c.invoke({ _: "upload.getFile", location, offset, limit }, { dc, type: "download" });
|
|
132
339
|
signal?.throwIfAborted();
|
|
133
340
|
if (_2_tl_js_1.Api.is("upload.file", file)) {
|
|
134
341
|
yield file.bytes;
|
|
135
342
|
if (id !== null) {
|
|
136
|
-
await
|
|
343
|
+
await this.#c.storage.saveFilePart(id, part, file.bytes);
|
|
137
344
|
signal?.throwIfAborted();
|
|
138
345
|
}
|
|
139
346
|
++part;
|
|
140
347
|
if (file.bytes.length < limit) {
|
|
141
348
|
if (id !== null) {
|
|
142
|
-
await
|
|
349
|
+
await this.#c.storage.setFilePartCount(id, part + 1, chunkSize);
|
|
143
350
|
signal?.throwIfAborted();
|
|
144
351
|
}
|
|
145
352
|
break;
|
|
@@ -163,7 +370,7 @@ class FileManager {
|
|
|
163
370
|
retryIn = 0;
|
|
164
371
|
errorCount = 0;
|
|
165
372
|
}
|
|
166
|
-
await
|
|
373
|
+
await this.#handleError(err, retryIn, `[${id}-${part + 1}]`);
|
|
167
374
|
signal?.throwIfAborted();
|
|
168
375
|
retryIn += 2;
|
|
169
376
|
if (retryIn > 11) {
|
|
@@ -206,7 +413,7 @@ class FileManager {
|
|
|
206
413
|
(0, _0_deps_js_1.unreachable)();
|
|
207
414
|
}
|
|
208
415
|
const big = fileId_.location.source.type === _3_types_js_1.PhotoSourceType.ChatPhotoBig;
|
|
209
|
-
const peer = await
|
|
416
|
+
const peer = await this.#c.getInputPeer(Number(fileId_.location.source.chatId));
|
|
210
417
|
const location = { _: "inputPeerPhotoFileLocation", big: big ? true : undefined, peer, photo_id: fileId_.location.id };
|
|
211
418
|
yield* this.downloadInner(location, fileId_.dcId, params);
|
|
212
419
|
break;
|
|
@@ -264,15 +471,15 @@ class FileManager {
|
|
|
264
471
|
}
|
|
265
472
|
}
|
|
266
473
|
async getStickerSetName(inputStickerSet, hash = 0) {
|
|
267
|
-
const maybeStickerSetName = await
|
|
474
|
+
const maybeStickerSetName = await this.#c.messageStorage.getStickerSetName(inputStickerSet.id, inputStickerSet.access_hash);
|
|
268
475
|
if (maybeStickerSetName !== null && Date.now() - maybeStickerSetName[1].getTime() < _4_constants_js_1.STICKER_SET_NAME_TTL) {
|
|
269
476
|
return maybeStickerSetName[0];
|
|
270
477
|
}
|
|
271
478
|
else {
|
|
272
479
|
try {
|
|
273
|
-
const stickerSet = await
|
|
480
|
+
const stickerSet = await this.#c.invoke({ _: "messages.getStickerSet", stickerset: inputStickerSet, hash });
|
|
274
481
|
const name = _2_tl_js_1.Api.as("messages.stickerSet", stickerSet).set.short_name;
|
|
275
|
-
await
|
|
482
|
+
await this.#c.messageStorage.updateStickerSetName(inputStickerSet.id, inputStickerSet.access_hash, name);
|
|
276
483
|
return name;
|
|
277
484
|
}
|
|
278
485
|
catch (err) {
|
|
@@ -285,6 +492,7 @@ class FileManager {
|
|
|
285
492
|
}
|
|
286
493
|
}
|
|
287
494
|
}
|
|
495
|
+
static #CUSTOM_EMOJI_TTL = 30 * _0_deps_js_1.MINUTE;
|
|
288
496
|
async getCustomEmojiStickers(id) {
|
|
289
497
|
id = Array.isArray(id) ? id : [id];
|
|
290
498
|
if (!id.length) {
|
|
@@ -293,8 +501,8 @@ class FileManager {
|
|
|
293
501
|
const stickers = new Array();
|
|
294
502
|
let shouldFetch = false;
|
|
295
503
|
for (const id_ of id) {
|
|
296
|
-
const maybeDocument = await
|
|
297
|
-
if (maybeDocument !== null && Date.now() - maybeDocument[1].getTime() <=
|
|
504
|
+
const maybeDocument = await this.#c.messageStorage.getCustomEmojiDocument(BigInt(id_));
|
|
505
|
+
if (maybeDocument !== null && Date.now() - maybeDocument[1].getTime() <= _a.#CUSTOM_EMOJI_TTL) {
|
|
298
506
|
const document_ = maybeDocument[0];
|
|
299
507
|
const fileId_ = {
|
|
300
508
|
type: _3_types_js_1.FileType.Document,
|
|
@@ -315,9 +523,9 @@ class FileManager {
|
|
|
315
523
|
if (!shouldFetch) {
|
|
316
524
|
return stickers;
|
|
317
525
|
}
|
|
318
|
-
const documents_ = (await
|
|
526
|
+
const documents_ = (await this.#c.invoke({ _: "messages.getCustomEmojiDocuments", document_id: id.map(BigInt) })).map((v) => _2_tl_js_1.Api.as("document", v));
|
|
319
527
|
for (const [i, document_] of documents_.entries()) {
|
|
320
|
-
await
|
|
528
|
+
await this.#c.messageStorage.setCustomEmojiDocument(document_.id, document_);
|
|
321
529
|
const fileId_ = {
|
|
322
530
|
type: _3_types_js_1.FileType.Document,
|
|
323
531
|
dcId: document_.dc_id,
|
|
@@ -333,219 +541,4 @@ class FileManager {
|
|
|
333
541
|
}
|
|
334
542
|
}
|
|
335
543
|
exports.FileManager = FileManager;
|
|
336
|
-
_a = FileManager
|
|
337
|
-
let part;
|
|
338
|
-
let promises = new Array();
|
|
339
|
-
let ms = 0.05;
|
|
340
|
-
let uploaded = 0;
|
|
341
|
-
let firstPart;
|
|
342
|
-
for await (part of (0, _1_utilities_js_1.iterateReadableStream)(stream.pipeThrough(new _1_utilities_js_1.PartStream(chunkSize)))) {
|
|
343
|
-
if (!part.isSmall && part.part > 0) {
|
|
344
|
-
await (0, _0_deps_js_1.delay)(ms);
|
|
345
|
-
ms = Math.max(ms * .8, 0.003);
|
|
346
|
-
}
|
|
347
|
-
if (!firstPart) {
|
|
348
|
-
firstPart = part.bytes;
|
|
349
|
-
}
|
|
350
|
-
promises.push(__classPrivateFieldGet(this, _FileManager_instances, "m", _FileManager_uploadPart).call(this, fileId, part.totalParts, !part.isSmall, part.part, part.bytes, signal).then(() => {
|
|
351
|
-
if (mustTrackProgress) {
|
|
352
|
-
uploaded += part.bytes.length;
|
|
353
|
-
__classPrivateFieldGet(this, _FileManager_c, "f").handleUpdate({
|
|
354
|
-
uploadProgress: {
|
|
355
|
-
id: String(fileId),
|
|
356
|
-
uploaded,
|
|
357
|
-
total: 0,
|
|
358
|
-
},
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
}));
|
|
362
|
-
if (promises.length === poolSize * _0_utilities_js_1.UPLOAD_REQUEST_PER_CONNECTION) {
|
|
363
|
-
await Promise.all(promises);
|
|
364
|
-
promises = [];
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
await Promise.all(promises);
|
|
368
|
-
return { isSmall: part.isSmall, parts: part.totalParts, firstPart };
|
|
369
|
-
}, _FileManager_uploadBuffer = async function _FileManager_uploadBuffer(buffer, fileId, mustTrackProgress, chunkSize, poolSize, signal) {
|
|
370
|
-
const isBig = buffer.byteLength > __classPrivateFieldGet(_a, _a, "f", _FileManager_BIG_FILE_THRESHOLD);
|
|
371
|
-
const partCount = Math.ceil(buffer.byteLength / chunkSize);
|
|
372
|
-
let promises = new Array();
|
|
373
|
-
let started = false;
|
|
374
|
-
let ms = 0.05;
|
|
375
|
-
let uploaded = 0;
|
|
376
|
-
let firstPart;
|
|
377
|
-
main: for (let part = 0; part < partCount;) {
|
|
378
|
-
for (let i = 0; i < poolSize; ++i) {
|
|
379
|
-
for (let i = 0; i < _0_utilities_js_1.UPLOAD_REQUEST_PER_CONNECTION; ++i) {
|
|
380
|
-
const start = part * chunkSize;
|
|
381
|
-
const end = start + chunkSize;
|
|
382
|
-
const bytes = buffer.subarray(start, end);
|
|
383
|
-
if (!bytes.length) {
|
|
384
|
-
break main;
|
|
385
|
-
}
|
|
386
|
-
if (!started) {
|
|
387
|
-
started = true;
|
|
388
|
-
}
|
|
389
|
-
else if (isBig && part > 0) {
|
|
390
|
-
await (0, _0_deps_js_1.delay)(ms);
|
|
391
|
-
ms = Math.max(ms * .8, 0.003);
|
|
392
|
-
}
|
|
393
|
-
if (!firstPart) {
|
|
394
|
-
firstPart = bytes;
|
|
395
|
-
}
|
|
396
|
-
promises.push(__classPrivateFieldGet(this, _FileManager_instances, "m", _FileManager_uploadPart).call(this, fileId, partCount, isBig, part++, bytes, signal).then(() => {
|
|
397
|
-
if (mustTrackProgress) {
|
|
398
|
-
uploaded += bytes.length;
|
|
399
|
-
__classPrivateFieldGet(this, _FileManager_c, "f").handleUpdate({
|
|
400
|
-
uploadProgress: {
|
|
401
|
-
id: String(fileId),
|
|
402
|
-
uploaded,
|
|
403
|
-
total: buffer.length,
|
|
404
|
-
},
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
}));
|
|
408
|
-
if (promises.length === poolSize * _0_utilities_js_1.UPLOAD_REQUEST_PER_CONNECTION) {
|
|
409
|
-
await Promise.all(promises);
|
|
410
|
-
promises = [];
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
await Promise.all(promises);
|
|
415
|
-
promises = [];
|
|
416
|
-
}
|
|
417
|
-
await Promise.all(promises);
|
|
418
|
-
return { isSmall: !isBig, parts: partCount, firstPart };
|
|
419
|
-
}, _FileManager_uploadPart = async function _FileManager_uploadPart(fileId, partCount, isBig, index, bytes, signal) {
|
|
420
|
-
let retryIn = 1;
|
|
421
|
-
let errorCount = 0;
|
|
422
|
-
while (true) {
|
|
423
|
-
try {
|
|
424
|
-
signal?.throwIfAborted();
|
|
425
|
-
__classPrivateFieldGet(this, _FileManager_Lupload, "f").debug(`[${fileId}] uploading part ` + (index + 1));
|
|
426
|
-
if (isBig) {
|
|
427
|
-
await __classPrivateFieldGet(this, _FileManager_c, "f").invoke({ _: "upload.saveBigFilePart", file_id: fileId, file_part: index, bytes, file_total_parts: partCount }, { type: "upload" });
|
|
428
|
-
}
|
|
429
|
-
else {
|
|
430
|
-
await __classPrivateFieldGet(this, _FileManager_c, "f").invoke({ _: "upload.saveFilePart", file_id: fileId, bytes, file_part: index }, { type: "upload" });
|
|
431
|
-
}
|
|
432
|
-
__classPrivateFieldGet(this, _FileManager_Lupload, "f").debug(`[${fileId}] uploaded part ` + (index + 1));
|
|
433
|
-
break;
|
|
434
|
-
}
|
|
435
|
-
catch (err) {
|
|
436
|
-
signal?.throwIfAborted();
|
|
437
|
-
__classPrivateFieldGet(this, _FileManager_Lupload, "f").debug(`[${fileId}] failed to upload part ` + (index + 1));
|
|
438
|
-
++errorCount;
|
|
439
|
-
if (errorCount > 20) {
|
|
440
|
-
retryIn = 0;
|
|
441
|
-
errorCount = 20;
|
|
442
|
-
}
|
|
443
|
-
await __classPrivateFieldGet(this, _FileManager_instances, "m", _FileManager_handleError).call(this, err, retryIn, `[${fileId}-${index + 1}]`);
|
|
444
|
-
retryIn += 2;
|
|
445
|
-
if (retryIn > 11) {
|
|
446
|
-
retryIn = 11;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}, _FileManager_handleError = async function _FileManager_handleError(err, retryIn, logPrefix) {
|
|
451
|
-
if (err instanceof _3_errors_js_1.TimeTooBig || err instanceof _3_errors_js_1.TimeTooSmall) {
|
|
452
|
-
throw err;
|
|
453
|
-
}
|
|
454
|
-
else if (err instanceof _4_errors_js_1.FloodWait) {
|
|
455
|
-
__classPrivateFieldGet(this, _FileManager_Lupload, "f").warning(`${logPrefix} retrying in ${err.seconds} seconds:`, err);
|
|
456
|
-
await (0, _0_deps_js_1.delay)(err.seconds * _0_deps_js_1.SECOND);
|
|
457
|
-
}
|
|
458
|
-
else if (retryIn > 0) {
|
|
459
|
-
__classPrivateFieldGet(this, _FileManager_Lupload, "f").warning(`${logPrefix} retrying in ${retryIn} seconds:`, err);
|
|
460
|
-
await (0, _0_deps_js_1.delay)(retryIn * _0_deps_js_1.SECOND);
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
throw err;
|
|
464
|
-
}
|
|
465
|
-
}, _FileManager_getFileContents = async function _FileManager_getFileContents(source, params, allowStream) {
|
|
466
|
-
let name = params?.fileName?.trim() || "file";
|
|
467
|
-
let contents;
|
|
468
|
-
let size = -1;
|
|
469
|
-
if (source instanceof Uint8Array) {
|
|
470
|
-
contents = source;
|
|
471
|
-
size = source.byteLength;
|
|
472
|
-
}
|
|
473
|
-
else if (source instanceof ReadableStream) {
|
|
474
|
-
if (!allowStream) {
|
|
475
|
-
throw new _0_errors_js_1.InputError("Streamed upload not allowed.");
|
|
476
|
-
}
|
|
477
|
-
contents = source;
|
|
478
|
-
}
|
|
479
|
-
else if (typeof source === "object" && source !== null && (Symbol.iterator in source || Symbol.asyncIterator in source)) {
|
|
480
|
-
if (!allowStream) {
|
|
481
|
-
throw new _0_errors_js_1.InputError("Streamed upload not allowed.");
|
|
482
|
-
}
|
|
483
|
-
contents = new ReadableStream({
|
|
484
|
-
pull: Symbol.asyncIterator in source
|
|
485
|
-
? async (controller) => {
|
|
486
|
-
const { value, done } = await source.next();
|
|
487
|
-
done ? controller.close() : controller.enqueue(value);
|
|
488
|
-
}
|
|
489
|
-
: (controller) => {
|
|
490
|
-
const { value, done } = source.next();
|
|
491
|
-
done ? controller.close() : controller.enqueue(value);
|
|
492
|
-
},
|
|
493
|
-
});
|
|
494
|
-
}
|
|
495
|
-
else {
|
|
496
|
-
let url;
|
|
497
|
-
try {
|
|
498
|
-
url = new URL(source).toString();
|
|
499
|
-
}
|
|
500
|
-
catch {
|
|
501
|
-
let path_;
|
|
502
|
-
if (typeof source === "string") {
|
|
503
|
-
if ((0, _0_deps_js_1.isAbsolute)(source)) {
|
|
504
|
-
path_ = source;
|
|
505
|
-
}
|
|
506
|
-
else {
|
|
507
|
-
// @ts-ignore: lib
|
|
508
|
-
path_ = (0, _0_deps_js_1.join)(Deno.cwd(), source);
|
|
509
|
-
}
|
|
510
|
-
url = (0, _0_deps_js_1.toFileUrl)(path_).toString();
|
|
511
|
-
name = (0, _0_deps_js_1.basename)(path_);
|
|
512
|
-
}
|
|
513
|
-
else {
|
|
514
|
-
(0, _0_deps_js_1.unreachable)();
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
const response = await fetch(url);
|
|
518
|
-
if (response.body === null) {
|
|
519
|
-
throw new _0_errors_js_1.InputError("Invalid response");
|
|
520
|
-
}
|
|
521
|
-
if (name === "file") {
|
|
522
|
-
const contentType = response.headers.get("content-type")?.split(";")[0].trim();
|
|
523
|
-
if (contentType) {
|
|
524
|
-
name += (0, _0_deps_js_1.extension)(contentType);
|
|
525
|
-
}
|
|
526
|
-
else {
|
|
527
|
-
const maybeFileName = new URL(response.url).pathname.split("/")
|
|
528
|
-
.filter((v) => v)
|
|
529
|
-
.slice(-1)[0]
|
|
530
|
-
.trim();
|
|
531
|
-
if (maybeFileName) {
|
|
532
|
-
name += (0, _0_deps_js_1.extension)((0, _0_deps_js_1.extname)(maybeFileName));
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
const contentLength = Number(response.headers.get("content-length"));
|
|
537
|
-
if (contentLength && !isNaN(contentLength)) {
|
|
538
|
-
size = contentLength;
|
|
539
|
-
}
|
|
540
|
-
if (allowStream) {
|
|
541
|
-
contents = response.body;
|
|
542
|
-
}
|
|
543
|
-
else {
|
|
544
|
-
contents = new Uint8Array(await response.arrayBuffer());
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
return { size: params?.fileSize ? params.fileSize : size, name, contents };
|
|
548
|
-
};
|
|
549
|
-
_FileManager_UPLOAD_MAX_CHUNK_SIZE = { value: 512 * _1_utilities_js_1.kilobyte };
|
|
550
|
-
_FileManager_BIG_FILE_THRESHOLD = { value: 10 * _1_utilities_js_1.megabyte };
|
|
551
|
-
_FileManager_CUSTOM_EMOJI_TTL = { value: 30 * _0_deps_js_1.MINUTE };
|
|
544
|
+
_a = FileManager;
|