@mtcute/web 0.16.7 → 0.16.13

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.
Files changed (139) hide show
  1. package/{cjs/client.d.ts → client.d.ts} +2 -3
  2. package/{cjs/crypto.d.ts → crypto.d.ts} +2 -3
  3. package/idb/idb.test.d.ts +1 -0
  4. package/{esm/idb → idb}/index.d.ts +1 -1
  5. package/{esm/idb → idb}/repository/auth-keys.d.ts +2 -2
  6. package/{cjs/idb → idb}/repository/kv.d.ts +2 -2
  7. package/{esm/idb → idb}/repository/peers.d.ts +3 -3
  8. package/{cjs/idb → idb}/repository/ref-messages.d.ts +2 -2
  9. package/index.cjs +965 -0
  10. package/index.d.ts +7 -1
  11. package/index.js +955 -1
  12. package/methods.cjs +14 -0
  13. package/methods.d.ts +1 -1
  14. package/methods.js +1 -1
  15. package/package.json +56 -40
  16. package/{cjs/platform.d.ts → platform.d.ts} +1 -1
  17. package/utils.cjs +14 -0
  18. package/utils.d.ts +1 -1
  19. package/utils.js +1 -1
  20. package/{esm/websocket.d.ts → websocket.d.ts} +3 -4
  21. package/websocket.test.d.ts +1 -0
  22. package/{cjs/worker.d.ts → worker.d.ts} +1 -2
  23. package/cjs/client.js +0 -43
  24. package/cjs/client.js.map +0 -1
  25. package/cjs/common-internals-web/base64.js +0 -111
  26. package/cjs/common-internals-web/base64.js.map +0 -1
  27. package/cjs/common-internals-web/hex.js +0 -66
  28. package/cjs/common-internals-web/hex.js.map +0 -1
  29. package/cjs/common-internals-web/logging.js +0 -35
  30. package/cjs/common-internals-web/logging.js.map +0 -1
  31. package/cjs/common-internals-web/utf8.js +0 -28
  32. package/cjs/common-internals-web/utf8.js.map +0 -1
  33. package/cjs/crypto.js +0 -73
  34. package/cjs/crypto.js.map +0 -1
  35. package/cjs/exit-hook.js +0 -23
  36. package/cjs/exit-hook.js.map +0 -1
  37. package/cjs/idb/driver.js +0 -139
  38. package/cjs/idb/driver.js.map +0 -1
  39. package/cjs/idb/index.d.ts +0 -22
  40. package/cjs/idb/index.js +0 -34
  41. package/cjs/idb/index.js.map +0 -1
  42. package/cjs/idb/repository/auth-keys.d.ts +0 -14
  43. package/cjs/idb/repository/auth-keys.js +0 -71
  44. package/cjs/idb/repository/auth-keys.js.map +0 -1
  45. package/cjs/idb/repository/kv.js +0 -35
  46. package/cjs/idb/repository/kv.js.map +0 -1
  47. package/cjs/idb/repository/peers.d.ts +0 -12
  48. package/cjs/idb/repository/peers.js +0 -39
  49. package/cjs/idb/repository/peers.js.map +0 -1
  50. package/cjs/idb/repository/ref-messages.js +0 -62
  51. package/cjs/idb/repository/ref-messages.js.map +0 -1
  52. package/cjs/idb/utils.js +0 -17
  53. package/cjs/idb/utils.js.map +0 -1
  54. package/cjs/index.js +0 -30
  55. package/cjs/index.js.map +0 -1
  56. package/cjs/methods.js +0 -24
  57. package/cjs/methods.js.map +0 -1
  58. package/cjs/package.json +0 -3
  59. package/cjs/platform.js +0 -49
  60. package/cjs/platform.js.map +0 -1
  61. package/cjs/utils.js +0 -24
  62. package/cjs/utils.js.map +0 -1
  63. package/cjs/wasm.js +0 -35
  64. package/cjs/wasm.js.map +0 -1
  65. package/cjs/websocket.d.ts +0 -47
  66. package/cjs/websocket.js +0 -132
  67. package/cjs/websocket.js.map +0 -1
  68. package/cjs/worker.js +0 -128
  69. package/cjs/worker.js.map +0 -1
  70. package/esm/client.d.ts +0 -31
  71. package/esm/client.js +0 -38
  72. package/esm/client.js.map +0 -1
  73. package/esm/common-internals-web/base64.d.ts +0 -2
  74. package/esm/common-internals-web/base64.js +0 -107
  75. package/esm/common-internals-web/base64.js.map +0 -1
  76. package/esm/common-internals-web/hex.d.ts +0 -2
  77. package/esm/common-internals-web/hex.js +0 -62
  78. package/esm/common-internals-web/hex.js.map +0 -1
  79. package/esm/common-internals-web/logging.d.ts +0 -2
  80. package/esm/common-internals-web/logging.js +0 -31
  81. package/esm/common-internals-web/logging.js.map +0 -1
  82. package/esm/common-internals-web/utf8.d.ts +0 -3
  83. package/esm/common-internals-web/utf8.js +0 -23
  84. package/esm/common-internals-web/utf8.js.map +0 -1
  85. package/esm/crypto.d.ts +0 -22
  86. package/esm/crypto.js +0 -69
  87. package/esm/crypto.js.map +0 -1
  88. package/esm/exit-hook.d.ts +0 -1
  89. package/esm/exit-hook.js +0 -20
  90. package/esm/exit-hook.js.map +0 -1
  91. package/esm/idb/driver.d.ts +0 -18
  92. package/esm/idb/driver.js +0 -135
  93. package/esm/idb/driver.js.map +0 -1
  94. package/esm/idb/index.js +0 -29
  95. package/esm/idb/index.js.map +0 -1
  96. package/esm/idb/repository/auth-keys.js +0 -67
  97. package/esm/idb/repository/auth-keys.js.map +0 -1
  98. package/esm/idb/repository/kv.d.ts +0 -11
  99. package/esm/idb/repository/kv.js +0 -31
  100. package/esm/idb/repository/kv.js.map +0 -1
  101. package/esm/idb/repository/peers.js +0 -35
  102. package/esm/idb/repository/peers.js.map +0 -1
  103. package/esm/idb/repository/ref-messages.d.ts +0 -12
  104. package/esm/idb/repository/ref-messages.js +0 -58
  105. package/esm/idb/repository/ref-messages.js.map +0 -1
  106. package/esm/idb/utils.d.ts +0 -2
  107. package/esm/idb/utils.js +0 -13
  108. package/esm/idb/utils.js.map +0 -1
  109. package/esm/index.d.ts +0 -7
  110. package/esm/index.js +0 -8
  111. package/esm/index.js.map +0 -1
  112. package/esm/methods.d.ts +0 -1
  113. package/esm/methods.js +0 -2
  114. package/esm/methods.js.map +0 -1
  115. package/esm/platform.d.ts +0 -21
  116. package/esm/platform.js +0 -45
  117. package/esm/platform.js.map +0 -1
  118. package/esm/utils.d.ts +0 -1
  119. package/esm/utils.js +0 -2
  120. package/esm/utils.js.map +0 -1
  121. package/esm/wasm.d.ts +0 -2
  122. package/esm/wasm.js +0 -32
  123. package/esm/wasm.js.map +0 -1
  124. package/esm/websocket.js +0 -124
  125. package/esm/websocket.js.map +0 -1
  126. package/esm/worker.d.ts +0 -11
  127. package/esm/worker.js +0 -123
  128. package/esm/worker.js.map +0 -1
  129. /package/{cjs/common-internals-web → common-internals-web}/base64.d.ts +0 -0
  130. /package/{cjs/common-internals-web → common-internals-web}/hex.d.ts +0 -0
  131. /package/{cjs/common-internals-web → common-internals-web}/logging.d.ts +0 -0
  132. /package/{cjs/common-internals-web → common-internals-web}/utf8.d.ts +0 -0
  133. /package/{cjs/exit-hook.d.ts → exit-hook.d.ts} +0 -0
  134. /package/{cjs/idb → idb}/driver.d.ts +0 -0
  135. /package/{cjs/idb → idb}/utils.d.ts +0 -0
  136. /package/{cjs/index.d.ts → index.d.cts} +0 -0
  137. /package/{cjs/methods.d.ts → methods.d.cts} +0 -0
  138. /package/{cjs/utils.d.ts → utils.d.cts} +0 -0
  139. /package/{cjs/wasm.d.ts → wasm.d.ts} +0 -0
package/index.cjs ADDED
@@ -0,0 +1,965 @@
1
+ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
2
+ globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
3
+ console.warn("[@mtcute/web] CommonJS support is deprecated and will be removed soon. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
4
+ console.warn("[@mtcute/web] Learn more about switching to ESM: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c");
5
+ }
6
+ "use strict";
7
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
8
+ const client_js = require("@mtcute/core/client.js");
9
+ const platform_js = require("@mtcute/core/platform.js");
10
+ const utils_js = require("@mtcute/core/utils.js");
11
+ const wasm = require("@mtcute/wasm");
12
+ const core = require("@mtcute/core");
13
+ const EventEmitter = require("node:events");
14
+ const worker_js = require("@mtcute/core/worker.js");
15
+ async function loadWasmBinary(input) {
16
+ if (typeof input === "undefined") {
17
+ input = wasm.getWasmUrl();
18
+ }
19
+ if (typeof input === "string" || typeof Request === "function" && input instanceof Request || typeof URL === "function" && input instanceof URL) {
20
+ input = await fetch(input);
21
+ }
22
+ if (typeof Response === "function" && input instanceof Response) {
23
+ if (typeof WebAssembly.instantiateStreaming === "function") {
24
+ try {
25
+ const { instance: instance2 } = await WebAssembly.instantiateStreaming(input);
26
+ return instance2;
27
+ } catch (e) {
28
+ if (input.headers.get("Content-Type") !== "application/wasm") {
29
+ console.warn(
30
+ "`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",
31
+ e
32
+ );
33
+ } else {
34
+ throw e;
35
+ }
36
+ }
37
+ }
38
+ const bytes = await input.arrayBuffer();
39
+ const { instance } = await WebAssembly.instantiate(bytes);
40
+ return instance;
41
+ }
42
+ return WebAssembly.instantiate(input);
43
+ }
44
+ const ALGO_TO_SUBTLE = {
45
+ sha256: "SHA-256",
46
+ sha1: "SHA-1",
47
+ sha512: "SHA-512"
48
+ };
49
+ class WebCryptoProvider extends utils_js.BaseCryptoProvider {
50
+ crypto;
51
+ _wasmInput;
52
+ sha1(data) {
53
+ return wasm.sha1(data);
54
+ }
55
+ sha256(data) {
56
+ return wasm.sha256(data);
57
+ }
58
+ createAesCtr(key, iv) {
59
+ const ctx = wasm.createCtr256(key, iv);
60
+ return {
61
+ process: (data) => wasm.ctr256(ctx, data),
62
+ close: () => wasm.freeCtr256(ctx)
63
+ };
64
+ }
65
+ createAesIge(key, iv) {
66
+ return {
67
+ encrypt: (data) => wasm.ige256Encrypt(data, key, iv),
68
+ decrypt: (data) => wasm.ige256Decrypt(data, key, iv)
69
+ };
70
+ }
71
+ gzip(data, maxSize) {
72
+ return wasm.deflateMaxSize(data, maxSize);
73
+ }
74
+ gunzip(data) {
75
+ return wasm.gunzip(data);
76
+ }
77
+ constructor(params) {
78
+ super();
79
+ const crypto = params?.crypto ?? globalThis.crypto;
80
+ if (!crypto || !crypto.subtle) {
81
+ throw new Error("WebCrypto is not available");
82
+ }
83
+ this.crypto = crypto;
84
+ this._wasmInput = params?.wasmInput;
85
+ }
86
+ async initialize() {
87
+ wasm.initSync(await loadWasmBinary(this._wasmInput));
88
+ }
89
+ async pbkdf2(password, salt, iterations, keylen, algo) {
90
+ const keyMaterial = await this.crypto.subtle.importKey("raw", password, "PBKDF2", false, ["deriveBits"]);
91
+ return this.crypto.subtle.deriveBits(
92
+ {
93
+ name: "PBKDF2",
94
+ salt,
95
+ iterations,
96
+ hash: algo ? ALGO_TO_SUBTLE[algo] : "SHA-512"
97
+ },
98
+ keyMaterial,
99
+ (keylen || 64) * 8
100
+ ).then((result) => new Uint8Array(result));
101
+ }
102
+ async hmacSha256(data, key) {
103
+ const keyMaterial = await this.crypto.subtle.importKey(
104
+ "raw",
105
+ key,
106
+ { name: "HMAC", hash: { name: "SHA-256" } },
107
+ false,
108
+ ["sign"]
109
+ );
110
+ const res = await this.crypto.subtle.sign({ name: "HMAC" }, keyMaterial, data);
111
+ return new Uint8Array(res);
112
+ }
113
+ randomFill(buf) {
114
+ this.crypto.getRandomValues(buf);
115
+ }
116
+ }
117
+ function txToPromise(tx) {
118
+ return new Promise((resolve, reject) => {
119
+ tx.oncomplete = () => resolve();
120
+ tx.onerror = () => reject(tx.error);
121
+ });
122
+ }
123
+ function reqToPromise(req) {
124
+ return new Promise((resolve, reject) => {
125
+ req.onsuccess = () => resolve(req.result);
126
+ req.onerror = () => reject(req.error);
127
+ });
128
+ }
129
+ const REPO_VERSION_PREFIX = "__version:";
130
+ class IdbStorageDriver extends core.BaseStorageDriver {
131
+ constructor(_dbName) {
132
+ super();
133
+ this._dbName = _dbName;
134
+ if (typeof indexedDB === "undefined") {
135
+ throw new core.MtUnsupportedError("IndexedDB is not available");
136
+ }
137
+ }
138
+ db;
139
+ _pendingWrites = [];
140
+ _pendingWritesOses = /* @__PURE__ */ new Set();
141
+ _migrations = /* @__PURE__ */ new Map();
142
+ _maxVersion = /* @__PURE__ */ new Map();
143
+ registerMigration(repo, version, migration) {
144
+ if (this.loaded) {
145
+ throw new Error("Cannot register migrations after loading");
146
+ }
147
+ let map = this._migrations.get(repo);
148
+ if (!map) {
149
+ map = /* @__PURE__ */ new Map();
150
+ this._migrations.set(repo, map);
151
+ }
152
+ if (map.has(version)) {
153
+ throw new Error(`Migration for ${repo} version ${version} is already registered`);
154
+ }
155
+ map.set(version, migration);
156
+ const prevMax = this._maxVersion.get(repo) ?? 0;
157
+ if (version > prevMax) {
158
+ this._maxVersion.set(repo, version);
159
+ }
160
+ }
161
+ writeLater(os, obj) {
162
+ this._pendingWrites.push([os, obj]);
163
+ this._pendingWritesOses.add(os);
164
+ }
165
+ async _load() {
166
+ this.db = await new Promise((resolve, reject) => {
167
+ const req = indexedDB.open(this._dbName, Date.now());
168
+ req.onerror = () => reject(req.error);
169
+ const postUpgrade = [];
170
+ req.onsuccess = async () => {
171
+ try {
172
+ for (const cb of postUpgrade) {
173
+ await cb(req.result);
174
+ }
175
+ resolve(req.result);
176
+ } catch (e) {
177
+ reject(e);
178
+ }
179
+ };
180
+ req.onupgradeneeded = () => {
181
+ const db = req.result;
182
+ const didUpgrade = /* @__PURE__ */ new Set();
183
+ const doUpgrade = (repo, fromVersion) => {
184
+ const migrations = this._migrations.get(repo);
185
+ if (!migrations) return;
186
+ const targetVer = this._maxVersion.get(repo);
187
+ while (fromVersion < targetVer) {
188
+ const nextVersion = fromVersion + 1;
189
+ const migration = migrations.get(nextVersion);
190
+ if (!migration) {
191
+ throw new Error(`No migration for ${repo} to version ${nextVersion}`);
192
+ }
193
+ const result = migration(db);
194
+ if (result) {
195
+ postUpgrade.push(result);
196
+ }
197
+ fromVersion = nextVersion;
198
+ }
199
+ didUpgrade.add(repo);
200
+ db.createObjectStore(`${REPO_VERSION_PREFIX}${repo}:${targetVer}`);
201
+ };
202
+ for (const key of db.objectStoreNames) {
203
+ if (!key.startsWith(REPO_VERSION_PREFIX)) continue;
204
+ const [, repo, version] = key.split(":");
205
+ const currentVer = Number(version);
206
+ db.deleteObjectStore(key);
207
+ doUpgrade(repo, currentVer);
208
+ didUpgrade.add(repo);
209
+ }
210
+ for (const repo of this._migrations.keys()) {
211
+ if (didUpgrade.has(repo)) continue;
212
+ doUpgrade(repo, 0);
213
+ }
214
+ };
215
+ });
216
+ }
217
+ async _save() {
218
+ if (this._pendingWritesOses.size === 0) return;
219
+ const writes = this._pendingWrites;
220
+ const oses = this._pendingWritesOses;
221
+ this._pendingWrites = [];
222
+ this._pendingWritesOses = /* @__PURE__ */ new Set();
223
+ const tx = this.db.transaction(oses, "readwrite");
224
+ const osMap = /* @__PURE__ */ new Map();
225
+ for (const table of oses) {
226
+ osMap.set(table, tx.objectStore(table));
227
+ }
228
+ for (const [table, obj] of writes) {
229
+ const os = osMap.get(table);
230
+ if (obj === null) {
231
+ os.delete(table);
232
+ } else {
233
+ os.put(obj);
234
+ }
235
+ }
236
+ await txToPromise(tx);
237
+ }
238
+ _destroy() {
239
+ this.db.close();
240
+ }
241
+ }
242
+ const TABLE_AUTH_KEYS = "authKeys";
243
+ const TABLE_TEMP_AUTH_KEYS = "tempAuthKeys";
244
+ class IdbAuthKeysRepository {
245
+ constructor(_driver) {
246
+ this._driver = _driver;
247
+ _driver.registerMigration(TABLE_AUTH_KEYS, 1, (db) => {
248
+ db.createObjectStore(TABLE_AUTH_KEYS, { keyPath: "dc" });
249
+ db.createObjectStore(TABLE_TEMP_AUTH_KEYS, { keyPath: ["dc", "idx"] });
250
+ });
251
+ }
252
+ os(mode) {
253
+ return this._driver.db.transaction(TABLE_AUTH_KEYS, mode).objectStore(TABLE_AUTH_KEYS);
254
+ }
255
+ async set(dc, key) {
256
+ const os = this.os("readwrite");
257
+ if (key === null) {
258
+ return reqToPromise(os.delete(dc));
259
+ }
260
+ await reqToPromise(os.put({ dc, key }));
261
+ }
262
+ async get(dc) {
263
+ const os = this.os();
264
+ const it = await reqToPromise(os.get(dc));
265
+ if (it === void 0) return null;
266
+ return it.key;
267
+ }
268
+ osTemp(mode) {
269
+ return this._driver.db.transaction(TABLE_TEMP_AUTH_KEYS, mode).objectStore(TABLE_TEMP_AUTH_KEYS);
270
+ }
271
+ async setTemp(dc, idx, key, expires) {
272
+ const os = this.osTemp("readwrite");
273
+ if (!key) {
274
+ return reqToPromise(os.delete([dc, idx]));
275
+ }
276
+ await reqToPromise(os.put({ dc, idx, key, expiresAt: expires }));
277
+ }
278
+ async getTemp(dc, idx, now) {
279
+ const os = this.osTemp();
280
+ const row = await reqToPromise(os.get([dc, idx]));
281
+ if (row === void 0 || row.expiresAt < now) return null;
282
+ return row.key;
283
+ }
284
+ async deleteByDc(dc) {
285
+ const tx = this._driver.db.transaction([TABLE_AUTH_KEYS, TABLE_TEMP_AUTH_KEYS], "readwrite");
286
+ tx.objectStore(TABLE_AUTH_KEYS).delete(dc);
287
+ const tempOs = tx.objectStore(TABLE_TEMP_AUTH_KEYS);
288
+ const keys = await reqToPromise(tempOs.getAllKeys());
289
+ for (const key of keys) {
290
+ if (key[0] === dc) {
291
+ tempOs.delete(key);
292
+ }
293
+ }
294
+ await txToPromise(tx);
295
+ }
296
+ deleteAll() {
297
+ const tx = this._driver.db.transaction([TABLE_AUTH_KEYS, TABLE_TEMP_AUTH_KEYS], "readwrite");
298
+ tx.objectStore(TABLE_AUTH_KEYS).clear();
299
+ tx.objectStore(TABLE_TEMP_AUTH_KEYS).clear();
300
+ return txToPromise(tx);
301
+ }
302
+ }
303
+ const KV_TABLE = "kv";
304
+ class IdbKvRepository {
305
+ constructor(_driver) {
306
+ this._driver = _driver;
307
+ _driver.registerMigration(KV_TABLE, 1, (db) => {
308
+ db.createObjectStore(KV_TABLE, { keyPath: "key" });
309
+ });
310
+ }
311
+ set(key, value) {
312
+ this._driver.writeLater(KV_TABLE, { key, value });
313
+ }
314
+ os(mode) {
315
+ return this._driver.db.transaction(KV_TABLE, mode).objectStore(KV_TABLE);
316
+ }
317
+ async get(key) {
318
+ const os = this.os();
319
+ const res = await reqToPromise(os.get(key));
320
+ if (res === void 0) return null;
321
+ return res.value;
322
+ }
323
+ async delete(key) {
324
+ await reqToPromise(this.os("readwrite").delete(key));
325
+ }
326
+ async deleteAll() {
327
+ await reqToPromise(this.os("readwrite").clear());
328
+ }
329
+ }
330
+ const TABLE$1 = "peers";
331
+ class IdbPeersRepository {
332
+ constructor(_driver) {
333
+ this._driver = _driver;
334
+ _driver.registerMigration(TABLE$1, 1, (db) => {
335
+ const os = db.createObjectStore(TABLE$1, { keyPath: "id" });
336
+ os.createIndex("by_username", "usernames", { unique: true, multiEntry: true });
337
+ os.createIndex("by_phone", "phone", { unique: true });
338
+ });
339
+ }
340
+ store(peer) {
341
+ this._driver.writeLater(TABLE$1, peer);
342
+ }
343
+ os(mode) {
344
+ return this._driver.db.transaction(TABLE$1, mode).objectStore(TABLE$1);
345
+ }
346
+ async getById(id, allowMin) {
347
+ const it = await reqToPromise(this.os().get(id));
348
+ if (!it) return null;
349
+ if (it.isMin && !allowMin) return null;
350
+ return it;
351
+ }
352
+ async getByUsername(username) {
353
+ const it = await reqToPromise(
354
+ this.os().index("by_username").get(username)
355
+ );
356
+ if (!it || it.isMin) return null;
357
+ return it;
358
+ }
359
+ async getByPhone(phone) {
360
+ const it = await reqToPromise(this.os().index("by_phone").get(phone));
361
+ if (!it || it.isMin) return null;
362
+ return it;
363
+ }
364
+ deleteAll() {
365
+ return reqToPromise(this.os("readwrite").clear());
366
+ }
367
+ }
368
+ const TABLE = "messageRefs";
369
+ class IdbRefMsgRepository {
370
+ constructor(_driver) {
371
+ this._driver = _driver;
372
+ _driver.registerMigration(TABLE, 1, (db) => {
373
+ const os = db.createObjectStore(TABLE, { keyPath: ["peerId", "chatId", "msgId"] });
374
+ os.createIndex("by_peer", "peerId");
375
+ os.createIndex("by_msg", ["chatId", "msgId"]);
376
+ });
377
+ }
378
+ os(mode) {
379
+ return this._driver.db.transaction(TABLE, mode).objectStore(TABLE);
380
+ }
381
+ async store(peerId, chatId, msgId) {
382
+ const os = this.os("readwrite");
383
+ await reqToPromise(os.put({ peerId, chatId, msgId }));
384
+ }
385
+ async getByPeer(peerId) {
386
+ const os = this.os();
387
+ const index = os.index("by_peer");
388
+ const it = await reqToPromise(index.get(peerId));
389
+ if (!it) return null;
390
+ return [it.chatId, it.msgId];
391
+ }
392
+ async delete(chatId, msgIds) {
393
+ const tx = this._driver.db.transaction(TABLE, "readwrite");
394
+ const os = tx.objectStore(TABLE);
395
+ const index = os.index("by_msg");
396
+ for (const msgId of msgIds) {
397
+ const keys = await reqToPromise(index.getAllKeys([chatId, msgId]));
398
+ for (const key of keys) {
399
+ os.delete(key);
400
+ }
401
+ }
402
+ return txToPromise(tx);
403
+ }
404
+ async deleteByPeer(peerId) {
405
+ const tx = this._driver.db.transaction(TABLE, "readwrite");
406
+ const os = tx.objectStore(TABLE);
407
+ const index = os.index("by_peer");
408
+ const req = index.openCursor(peerId);
409
+ let cursor = await reqToPromise(req);
410
+ while (cursor) {
411
+ cursor.delete();
412
+ cursor.continue();
413
+ cursor = await reqToPromise(req);
414
+ }
415
+ return txToPromise(tx);
416
+ }
417
+ async deleteAll() {
418
+ await reqToPromise(this.os("readwrite").clear());
419
+ }
420
+ }
421
+ class IdbStorage {
422
+ constructor(dbName) {
423
+ this.dbName = dbName;
424
+ this.driver = new IdbStorageDriver(this.dbName);
425
+ this.kv = new IdbKvRepository(this.driver);
426
+ this.authKeys = new IdbAuthKeysRepository(this.driver);
427
+ this.peers = new IdbPeersRepository(this.driver);
428
+ this.refMessages = new IdbRefMsgRepository(this.driver);
429
+ }
430
+ driver;
431
+ kv;
432
+ authKeys;
433
+ peers;
434
+ refMessages;
435
+ }
436
+ const lookup = [];
437
+ const revLookup = [];
438
+ const code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
439
+ for (let i = 0, len = code.length; i < len; ++i) {
440
+ lookup[i] = code[i];
441
+ revLookup[code.charCodeAt(i)] = i;
442
+ }
443
+ function getLens(b64) {
444
+ const len = b64.length;
445
+ if (len % 4 > 0) {
446
+ throw new Error("Invalid string. Length must be a multiple of 4");
447
+ }
448
+ let validLen = b64.indexOf("=");
449
+ if (validLen === -1) validLen = len;
450
+ const placeHoldersLen = validLen === len ? 0 : 4 - validLen % 4;
451
+ return [validLen, placeHoldersLen];
452
+ }
453
+ function _byteLength(b64, validLen, placeHoldersLen) {
454
+ return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
455
+ }
456
+ function toByteArray(b64, arr) {
457
+ let tmp;
458
+ const lens = getLens(b64);
459
+ const validLen = lens[0];
460
+ const placeHoldersLen = lens[1];
461
+ let curByte = 0;
462
+ const len = placeHoldersLen > 0 ? validLen - 4 : validLen;
463
+ let i;
464
+ for (i = 0; i < len; i += 4) {
465
+ tmp = revLookup[b64.charCodeAt(i)] << 18 | revLookup[b64.charCodeAt(i + 1)] << 12 | revLookup[b64.charCodeAt(i + 2)] << 6 | revLookup[b64.charCodeAt(i + 3)];
466
+ arr[curByte++] = tmp >> 16 & 255;
467
+ arr[curByte++] = tmp >> 8 & 255;
468
+ arr[curByte++] = tmp & 255;
469
+ }
470
+ if (placeHoldersLen === 2) {
471
+ tmp = revLookup[b64.charCodeAt(i)] << 2 | revLookup[b64.charCodeAt(i + 1)] >> 4;
472
+ arr[curByte++] = tmp & 255;
473
+ }
474
+ if (placeHoldersLen === 1) {
475
+ tmp = revLookup[b64.charCodeAt(i)] << 10 | revLookup[b64.charCodeAt(i + 1)] << 4 | revLookup[b64.charCodeAt(i + 2)] >> 2;
476
+ arr[curByte++] = tmp >> 8 & 255;
477
+ arr[curByte++] = tmp & 255;
478
+ }
479
+ return arr;
480
+ }
481
+ function tripletToBase64(num) {
482
+ return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63];
483
+ }
484
+ function encodeChunk(uint8, start, end) {
485
+ let tmp;
486
+ const output = [];
487
+ for (let i = start; i < end; i += 3) {
488
+ tmp = (uint8[i] << 16 & 16711680) + (uint8[i + 1] << 8 & 65280) + (uint8[i + 2] & 255);
489
+ output.push(tripletToBase64(tmp));
490
+ }
491
+ return output.join("");
492
+ }
493
+ function fromByteArray(uint8) {
494
+ let tmp;
495
+ const len = uint8.length;
496
+ const extraBytes = len % 3;
497
+ const parts = [];
498
+ const maxChunkLength = 16383;
499
+ for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
500
+ parts.push(encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength));
501
+ }
502
+ if (extraBytes === 1) {
503
+ tmp = uint8[len - 1];
504
+ parts.push(`${lookup[tmp >> 2] + lookup[tmp << 4 & 63]}==`);
505
+ } else if (extraBytes === 2) {
506
+ tmp = (uint8[len - 2] << 8) + uint8[len - 1];
507
+ parts.push(`${lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63]}=`);
508
+ }
509
+ return parts.join("");
510
+ }
511
+ function base64Encode(buf, url = false) {
512
+ const str = fromByteArray(buf);
513
+ if (url) return str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
514
+ return str;
515
+ }
516
+ function base64Decode(string, url = false) {
517
+ if (url) {
518
+ string = string.replace(/-/g, "+").replace(/_/g, "/");
519
+ while (string.length % 4) string += "=";
520
+ }
521
+ const buf = new Uint8Array(_byteLength(string, ...getLens(string)));
522
+ toByteArray(string, buf);
523
+ return buf;
524
+ }
525
+ const hexSliceLookupTable = function() {
526
+ const alphabet = "0123456789abcdef";
527
+ const table = Array.from({ length: 256 });
528
+ for (let i = 0; i < 16; ++i) {
529
+ const i16 = i * 16;
530
+ for (let j = 0; j < 16; ++j) {
531
+ table[i16 + j] = alphabet[i] + alphabet[j];
532
+ }
533
+ }
534
+ return table;
535
+ }();
536
+ const hexCharValueTable = {
537
+ 0: 0,
538
+ 1: 1,
539
+ 2: 2,
540
+ 3: 3,
541
+ 4: 4,
542
+ 5: 5,
543
+ 6: 6,
544
+ 7: 7,
545
+ 8: 8,
546
+ 9: 9,
547
+ a: 10,
548
+ b: 11,
549
+ c: 12,
550
+ d: 13,
551
+ e: 14,
552
+ f: 15,
553
+ A: 10,
554
+ B: 11,
555
+ C: 12,
556
+ D: 13,
557
+ E: 14,
558
+ F: 15
559
+ };
560
+ function hexEncode(buf) {
561
+ let out = "";
562
+ for (let i = 0; i < buf.byteLength; ++i) {
563
+ out += hexSliceLookupTable[buf[i]];
564
+ }
565
+ return out;
566
+ }
567
+ function hexDecodeInner(buf, string) {
568
+ const strLen = string.length;
569
+ const length = Math.min(buf.length, strLen / 2);
570
+ let i;
571
+ for (i = 0; i < length; ++i) {
572
+ const a = hexCharValueTable[string[i * 2]];
573
+ const b = hexCharValueTable[string[i * 2 + 1]];
574
+ if (a === void 0 || b === void 0) {
575
+ return;
576
+ }
577
+ buf[i] = a << 4 | b;
578
+ }
579
+ }
580
+ function hexDecode(string) {
581
+ const buf = new Uint8Array(Math.ceil(string.length / 2));
582
+ hexDecodeInner(buf, string);
583
+ return buf;
584
+ }
585
+ const BASE_FORMAT = "%s [%c%s%c] [%c%s%c] ";
586
+ const LEVEL_NAMES = [
587
+ "",
588
+ // OFF
589
+ "ERR",
590
+ "WRN",
591
+ "INF",
592
+ "DBG",
593
+ "VRB"
594
+ ];
595
+ const COLORS = [
596
+ "",
597
+ // OFF
598
+ "color: #7a5f9d",
599
+ "color: #8d7041",
600
+ "color: #396c9e",
601
+ "color: #437761",
602
+ "color: #7a5f9d"
603
+ ];
604
+ const TAG_COLORS = [
605
+ "color: #437761",
606
+ "color: #537a36",
607
+ "color: #8d7041",
608
+ "color: #396c9e",
609
+ "color: #7a5f9d",
610
+ "color: #7a5f9d"
611
+ ];
612
+ const defaultLoggingHandler = (color, level, tag, fmt, args) => {
613
+ console.log(
614
+ BASE_FORMAT + fmt,
615
+ (/* @__PURE__ */ new Date()).toISOString(),
616
+ COLORS[level],
617
+ LEVEL_NAMES[level],
618
+ "",
619
+ TAG_COLORS[color],
620
+ tag,
621
+ "",
622
+ ...args
623
+ );
624
+ };
625
+ const sharedEncoder = new TextEncoder();
626
+ const sharedDecoder = new TextDecoder("utf8");
627
+ function utf8ByteLength(str) {
628
+ let s = str.length;
629
+ for (let i = str.length - 1; i >= 0; i--) {
630
+ const code2 = str.charCodeAt(i);
631
+ if (code2 > 127 && code2 <= 2047) s++;
632
+ else if (code2 > 2047 && code2 <= 65535) s += 2;
633
+ if (code2 >= 56320 && code2 <= 57343) i--;
634
+ }
635
+ return s;
636
+ }
637
+ function utf8Decode(buf) {
638
+ return sharedDecoder.decode(buf);
639
+ }
640
+ function utf8Encode(str) {
641
+ return sharedEncoder.encode(str);
642
+ }
643
+ const callbacks = /* @__PURE__ */ new Set();
644
+ let registered = false;
645
+ function beforeExit(fn) {
646
+ if (typeof window === "undefined") {
647
+ return () => {
648
+ };
649
+ }
650
+ if (!registered) {
651
+ registered = true;
652
+ window.addEventListener("beforeunload", () => {
653
+ for (const callback of callbacks) {
654
+ callback();
655
+ }
656
+ });
657
+ }
658
+ callbacks.add(fn);
659
+ return () => {
660
+ callbacks.delete(fn);
661
+ };
662
+ }
663
+ class WebPlatform {
664
+ getDeviceModel() {
665
+ if (typeof navigator === "undefined") return "Browser";
666
+ return navigator.userAgent;
667
+ }
668
+ getDefaultLogLevel() {
669
+ if (typeof localStorage !== "undefined") {
670
+ const localLogLevel = Number.parseInt(localStorage.MTCUTE_LOG_LEVEL);
671
+ if (!Number.isNaN(localLogLevel)) {
672
+ return localLogLevel;
673
+ }
674
+ }
675
+ return null;
676
+ }
677
+ onNetworkChanged(fn) {
678
+ if (!("onLine" in navigator)) return () => {
679
+ };
680
+ const onlineHandler = () => fn(navigator.onLine);
681
+ window.addEventListener("online", onlineHandler);
682
+ window.addEventListener("offline", onlineHandler);
683
+ return () => {
684
+ window.removeEventListener("online", onlineHandler);
685
+ window.removeEventListener("offline", onlineHandler);
686
+ };
687
+ }
688
+ isOnline() {
689
+ return navigator.onLine;
690
+ }
691
+ }
692
+ WebPlatform.prototype.log = defaultLoggingHandler;
693
+ WebPlatform.prototype.beforeExit = beforeExit;
694
+ WebPlatform.prototype.utf8ByteLength = utf8ByteLength;
695
+ WebPlatform.prototype.utf8Encode = utf8Encode;
696
+ WebPlatform.prototype.utf8Decode = utf8Decode;
697
+ WebPlatform.prototype.hexEncode = hexEncode;
698
+ WebPlatform.prototype.hexDecode = hexDecode;
699
+ WebPlatform.prototype.base64Encode = base64Encode;
700
+ WebPlatform.prototype.base64Decode = base64Decode;
701
+ const subdomainsMap = {
702
+ 1: "pluto",
703
+ 2: "venus",
704
+ 3: "aurora",
705
+ 4: "vesta",
706
+ 5: "flora"
707
+ };
708
+ class BaseWebSocketTransport extends EventEmitter {
709
+ _currentDc = null;
710
+ _state = core.TransportState.Idle;
711
+ _socket = null;
712
+ _crypto;
713
+ log;
714
+ packetCodecInitialized = false;
715
+ _baseDomain;
716
+ _subdomains;
717
+ _WebSocket;
718
+ constructor({
719
+ ws = WebSocket,
720
+ baseDomain = "web.telegram.org",
721
+ subdomains = subdomainsMap
722
+ } = {}) {
723
+ super();
724
+ if (!ws) {
725
+ throw new core.MtUnsupportedError(
726
+ "To use WebSocket transport with NodeJS, install `ws` package and pass it to constructor"
727
+ );
728
+ }
729
+ if ("default" in ws) {
730
+ ws = ws.default;
731
+ }
732
+ this._baseDomain = baseDomain;
733
+ this._subdomains = subdomains;
734
+ this._WebSocket = ws;
735
+ }
736
+ _updateLogPrefix() {
737
+ if (this._currentDc) {
738
+ this.log.prefix = `[WS:${this._subdomains[this._currentDc.id]}.${this._baseDomain}] `;
739
+ } else {
740
+ this.log.prefix = "[WS:disconnected] ";
741
+ }
742
+ }
743
+ setup(crypto, log) {
744
+ this._crypto = crypto;
745
+ this.log = log.create("ws");
746
+ }
747
+ state() {
748
+ return this._state;
749
+ }
750
+ currentDc() {
751
+ return this._currentDc;
752
+ }
753
+ connect(dc, testMode) {
754
+ if (this._state !== core.TransportState.Idle) {
755
+ throw new core.MtcuteError("Transport is not IDLE");
756
+ }
757
+ if (!this.packetCodecInitialized) {
758
+ this._packetCodec.setup?.(this._crypto, this.log);
759
+ this._packetCodec.on("error", (err) => this.emit("error", err));
760
+ this._packetCodec.on("packet", (buf) => this.emit("message", buf));
761
+ this.packetCodecInitialized = true;
762
+ }
763
+ this._state = core.TransportState.Connecting;
764
+ this._currentDc = dc;
765
+ this._socket = new this._WebSocket(
766
+ `wss://${this._subdomains[dc.id]}.${this._baseDomain}/apiws${testMode ? "_test" : ""}`,
767
+ "binary"
768
+ );
769
+ this._updateLogPrefix();
770
+ this.log.debug("connecting to %s (%j)", this._socket.url, dc);
771
+ this._socket.binaryType = "arraybuffer";
772
+ this._socket.addEventListener("message", (evt) => this._packetCodec.feed(new Uint8Array(evt.data)));
773
+ this._socket.addEventListener("open", this.handleConnect.bind(this));
774
+ this._socket.addEventListener("error", this.handleError.bind(this));
775
+ this._socket.addEventListener("close", this.handleClosed.bind(this));
776
+ }
777
+ _closeWaiters = [];
778
+ async close() {
779
+ if (this._state === core.TransportState.Idle) return;
780
+ const promise = utils_js.createControllablePromise();
781
+ this._closeWaiters.push(promise);
782
+ this._socket.close();
783
+ return promise;
784
+ }
785
+ handleClosed() {
786
+ this.log.info("connection closed");
787
+ this._state = core.TransportState.Idle;
788
+ this._socket = null;
789
+ this._currentDc = null;
790
+ this._packetCodec.reset();
791
+ this.emit("close");
792
+ for (const waiter of this._closeWaiters) {
793
+ waiter.resolve();
794
+ }
795
+ this._closeWaiters = [];
796
+ }
797
+ handleError(event) {
798
+ const error = "error" in event ? event.error : new Error("unknown WebSocket error");
799
+ this.log.error("error: %s", error.stack);
800
+ this.emit("error", error);
801
+ }
802
+ handleConnect() {
803
+ this.log.info("connected");
804
+ Promise.resolve(this._packetCodec.tag()).then((initialMessage) => {
805
+ this._socket.send(initialMessage);
806
+ this._state = core.TransportState.Ready;
807
+ this.emit("ready");
808
+ }).catch((err) => this.emit("error", err));
809
+ }
810
+ async send(bytes) {
811
+ if (this._state !== core.TransportState.Ready) {
812
+ throw new core.MtcuteError("Transport is not READY");
813
+ }
814
+ const framed = await this._packetCodec.encode(bytes);
815
+ this._socket.send(framed);
816
+ }
817
+ }
818
+ class WebSocketTransport extends BaseWebSocketTransport {
819
+ _packetCodec = new core.ObfuscatedPacketCodec(new core.IntermediatePacketCodec());
820
+ }
821
+ class BaseTelegramClient extends client_js.BaseTelegramClient {
822
+ constructor(opts) {
823
+ if (!opts.platformless) platform_js.setPlatform(new WebPlatform());
824
+ super({
825
+ crypto: new WebCryptoProvider(),
826
+ transport: () => new WebSocketTransport(),
827
+ ...opts,
828
+ storage: typeof opts.storage === "string" ? new IdbStorage(opts.storage) : opts.storage ?? new IdbStorage("client.session")
829
+ });
830
+ }
831
+ }
832
+ class TelegramClient extends client_js.TelegramClient {
833
+ constructor(opts) {
834
+ if ("client" in opts) {
835
+ super(opts);
836
+ return;
837
+ }
838
+ super({
839
+ client: new BaseTelegramClient(opts),
840
+ disableUpdates: opts.disableUpdates,
841
+ skipConversationUpdates: opts.skipConversationUpdates,
842
+ updates: opts.updates
843
+ });
844
+ }
845
+ }
846
+ let _registered = false;
847
+ class TelegramWorker extends worker_js.TelegramWorker {
848
+ registerWorker(handler) {
849
+ if (_registered) {
850
+ throw new Error("TelegramWorker must be created only once");
851
+ }
852
+ _registered = true;
853
+ if (typeof SharedWorkerGlobalScope !== "undefined" && self instanceof SharedWorkerGlobalScope) {
854
+ const connections = [];
855
+ const broadcast = (message) => {
856
+ for (const port of connections) {
857
+ port.postMessage(message);
858
+ }
859
+ };
860
+ self.onconnect = (event) => {
861
+ const port = event.ports[0];
862
+ connections.push(port);
863
+ const respond = port.postMessage.bind(port);
864
+ const onClose = () => {
865
+ port.close();
866
+ const idx = connections.indexOf(port);
867
+ if (idx >= 0) {
868
+ connections.splice(connections.indexOf(port), 1);
869
+ }
870
+ };
871
+ const onTimeout = () => {
872
+ console.warn("some connection timed out!");
873
+ respond({ __type__: "timeout" });
874
+ onClose();
875
+ };
876
+ let timeout = setTimeout(onTimeout, 6e4);
877
+ port.addEventListener("message", (message) => {
878
+ if (message.data.__type__ === "close") {
879
+ onClose();
880
+ return;
881
+ }
882
+ if (message.data.__type__ === "ping") {
883
+ clearTimeout(timeout);
884
+ timeout = setTimeout(onTimeout, 6e4);
885
+ return;
886
+ }
887
+ handler(message.data, respond);
888
+ });
889
+ port.start();
890
+ };
891
+ return broadcast;
892
+ }
893
+ if (typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope) {
894
+ const respond = self.postMessage.bind(self);
895
+ self.addEventListener("message", (message) => handler(message.data, respond));
896
+ return respond;
897
+ }
898
+ throw new Error("TelegramWorker must be created from a worker");
899
+ }
900
+ }
901
+ const platform = new WebPlatform();
902
+ class TelegramWorkerPort extends worker_js.TelegramWorkerPort {
903
+ constructor(options) {
904
+ platform_js.setPlatform(platform);
905
+ super(options);
906
+ this.options = options;
907
+ }
908
+ connectToWorker(worker, handler) {
909
+ if (worker instanceof Worker) {
910
+ const send = worker.postMessage.bind(worker);
911
+ const messageHandler = (ev) => {
912
+ handler(ev.data);
913
+ };
914
+ worker.addEventListener("message", messageHandler);
915
+ return [
916
+ send,
917
+ () => {
918
+ worker.removeEventListener("message", messageHandler);
919
+ }
920
+ ];
921
+ }
922
+ if (worker instanceof SharedWorker) {
923
+ const send = worker.port.postMessage.bind(worker.port);
924
+ const pingInterval = setInterval(() => {
925
+ worker.port.postMessage({ __type__: "ping" });
926
+ }, 1e4);
927
+ const messageHandler = (ev) => {
928
+ if (ev.data.__type__ === "timeout") {
929
+ location.reload();
930
+ return;
931
+ }
932
+ handler(ev.data);
933
+ };
934
+ worker.port.addEventListener("message", messageHandler);
935
+ worker.port.start();
936
+ let cancelBeforeExit;
937
+ const close = () => {
938
+ clearInterval(pingInterval);
939
+ worker.port.postMessage({ __type__: "close" });
940
+ worker.port.removeEventListener("message", messageHandler);
941
+ worker.port.close();
942
+ cancelBeforeExit();
943
+ };
944
+ cancelBeforeExit = platform.beforeExit(close);
945
+ return [send, close];
946
+ }
947
+ throw new Error("Only workers and shared workers are supported");
948
+ }
949
+ }
950
+ exports.BaseTelegramClient = BaseTelegramClient;
951
+ exports.BaseWebSocketTransport = BaseWebSocketTransport;
952
+ exports.IdbStorage = IdbStorage;
953
+ exports.IdbStorageDriver = IdbStorageDriver;
954
+ exports.TelegramClient = TelegramClient;
955
+ exports.TelegramWorker = TelegramWorker;
956
+ exports.TelegramWorkerPort = TelegramWorkerPort;
957
+ exports.WebCryptoProvider = WebCryptoProvider;
958
+ exports.WebPlatform = WebPlatform;
959
+ exports.WebSocketTransport = WebSocketTransport;
960
+ Object.keys(core).forEach((k) => {
961
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
962
+ enumerable: true,
963
+ get: () => core[k]
964
+ });
965
+ });