@mtcute/web 0.17.0 → 0.18.0-rc.5

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/client.cjs ADDED
@@ -0,0 +1,39 @@
1
+ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
2
+ globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
3
+ console.warn("[mtcute-workspace] CommonJS support is deprecated and will be removed in 0.20.0. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
4
+ console.warn("[mtcute-workspace] 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 crypto = require("./crypto.cjs");
10
+ const index = require("./idb/index.cjs");
11
+ const platform = require("./platform.cjs");
12
+ const websocket = require("./websocket.cjs");
13
+ class BaseTelegramClient extends client_js.BaseTelegramClient {
14
+ constructor(opts) {
15
+ super({
16
+ crypto: new crypto.WebCryptoProvider(),
17
+ transport: new websocket.WebSocketTransport(),
18
+ platform: new platform.WebPlatform(),
19
+ ...opts,
20
+ storage: typeof opts.storage === "string" ? new index.IdbStorage(opts.storage) : opts.storage ?? new index.IdbStorage("client.session")
21
+ });
22
+ }
23
+ }
24
+ class TelegramClient extends client_js.TelegramClient {
25
+ constructor(opts) {
26
+ if ("client" in opts) {
27
+ super(opts);
28
+ return;
29
+ }
30
+ super({
31
+ client: new BaseTelegramClient(opts),
32
+ disableUpdates: opts.disableUpdates,
33
+ skipConversationUpdates: opts.skipConversationUpdates,
34
+ updates: opts.updates
35
+ });
36
+ }
37
+ }
38
+ exports.BaseTelegramClient = BaseTelegramClient;
39
+ exports.TelegramClient = TelegramClient;
package/client.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ITelegramStorageProvider, PartialOnly } from '@mtcute/core';
2
2
  import { BaseTelegramClientOptions as BaseTelegramClientOptionsBase, TelegramClientOptions, BaseTelegramClient as BaseTelegramClientBase, TelegramClient as TelegramClientBase } from '@mtcute/core/client.js';
3
3
  export type { TelegramClientOptions };
4
- export interface BaseTelegramClientOptions extends PartialOnly<Omit<BaseTelegramClientOptionsBase, 'storage'>, 'transport' | 'crypto'> {
4
+ export interface BaseTelegramClientOptions extends PartialOnly<Omit<BaseTelegramClientOptionsBase, 'storage'>, 'transport' | 'crypto' | 'platform'> {
5
5
  /**
6
6
  * Storage to use for this client.
7
7
  *
@@ -11,13 +11,6 @@ export interface BaseTelegramClientOptions extends PartialOnly<Omit<BaseTelegram
11
11
  * @default `"client.session"`
12
12
  */
13
13
  storage?: string | ITelegramStorageProvider;
14
- /**
15
- * **ADVANCED USE ONLY**
16
- *
17
- * Whether to not set up the platform.
18
- * This is useful if you call `setPlatform` yourself.
19
- */
20
- platformless?: boolean;
21
14
  }
22
15
  export declare class BaseTelegramClient extends BaseTelegramClientBase {
23
16
  constructor(opts: BaseTelegramClientOptions);
package/client.js ADDED
@@ -0,0 +1,34 @@
1
+ import { BaseTelegramClient as BaseTelegramClient$1, TelegramClient as TelegramClient$1 } from "@mtcute/core/client.js";
2
+ import { WebCryptoProvider } from "./crypto.js";
3
+ import { IdbStorage } from "./idb/index.js";
4
+ import { WebPlatform } from "./platform.js";
5
+ import { WebSocketTransport } from "./websocket.js";
6
+ class BaseTelegramClient extends BaseTelegramClient$1 {
7
+ constructor(opts) {
8
+ super({
9
+ crypto: new WebCryptoProvider(),
10
+ transport: new WebSocketTransport(),
11
+ platform: new WebPlatform(),
12
+ ...opts,
13
+ storage: typeof opts.storage === "string" ? new IdbStorage(opts.storage) : opts.storage ?? new IdbStorage("client.session")
14
+ });
15
+ }
16
+ }
17
+ class TelegramClient extends TelegramClient$1 {
18
+ constructor(opts) {
19
+ if ("client" in opts) {
20
+ super(opts);
21
+ return;
22
+ }
23
+ super({
24
+ client: new BaseTelegramClient(opts),
25
+ disableUpdates: opts.disableUpdates,
26
+ skipConversationUpdates: opts.skipConversationUpdates,
27
+ updates: opts.updates
28
+ });
29
+ }
30
+ }
31
+ export {
32
+ BaseTelegramClient,
33
+ TelegramClient
34
+ };
@@ -0,0 +1,48 @@
1
+ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
2
+ globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
3
+ console.warn("[mtcute-workspace] CommonJS support is deprecated and will be removed in 0.20.0. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
4
+ console.warn("[mtcute-workspace] 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 BASE_FORMAT = "%s [%c%s%c] [%c%s%c] ";
9
+ const LEVEL_NAMES = [
10
+ "",
11
+ // OFF
12
+ "ERR",
13
+ "WRN",
14
+ "INF",
15
+ "DBG",
16
+ "VRB"
17
+ ];
18
+ const COLORS = [
19
+ "",
20
+ // OFF
21
+ "color: #7a5f9d",
22
+ "color: #8d7041",
23
+ "color: #396c9e",
24
+ "color: #437761",
25
+ "color: #7a5f9d"
26
+ ];
27
+ const TAG_COLORS = [
28
+ "color: #437761",
29
+ "color: #537a36",
30
+ "color: #8d7041",
31
+ "color: #396c9e",
32
+ "color: #7a5f9d",
33
+ "color: #7a5f9d"
34
+ ];
35
+ const defaultLoggingHandler = (color, level, tag, fmt, args) => {
36
+ console.log(
37
+ BASE_FORMAT + fmt,
38
+ (/* @__PURE__ */ new Date()).toISOString(),
39
+ COLORS[level],
40
+ LEVEL_NAMES[level],
41
+ "",
42
+ TAG_COLORS[color],
43
+ tag,
44
+ "",
45
+ ...args
46
+ );
47
+ };
48
+ exports.defaultLoggingHandler = defaultLoggingHandler;
@@ -0,0 +1,43 @@
1
+ const BASE_FORMAT = "%s [%c%s%c] [%c%s%c] ";
2
+ const LEVEL_NAMES = [
3
+ "",
4
+ // OFF
5
+ "ERR",
6
+ "WRN",
7
+ "INF",
8
+ "DBG",
9
+ "VRB"
10
+ ];
11
+ const COLORS = [
12
+ "",
13
+ // OFF
14
+ "color: #7a5f9d",
15
+ "color: #8d7041",
16
+ "color: #396c9e",
17
+ "color: #437761",
18
+ "color: #7a5f9d"
19
+ ];
20
+ const TAG_COLORS = [
21
+ "color: #437761",
22
+ "color: #537a36",
23
+ "color: #8d7041",
24
+ "color: #396c9e",
25
+ "color: #7a5f9d",
26
+ "color: #7a5f9d"
27
+ ];
28
+ const defaultLoggingHandler = (color, level, tag, fmt, args) => {
29
+ console.log(
30
+ BASE_FORMAT + fmt,
31
+ (/* @__PURE__ */ new Date()).toISOString(),
32
+ COLORS[level],
33
+ LEVEL_NAMES[level],
34
+ "",
35
+ TAG_COLORS[color],
36
+ tag,
37
+ "",
38
+ ...args
39
+ );
40
+ };
41
+ export {
42
+ defaultLoggingHandler
43
+ };
package/crypto.cjs ADDED
@@ -0,0 +1,84 @@
1
+ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
2
+ globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
3
+ console.warn("[mtcute-workspace] CommonJS support is deprecated and will be removed in 0.20.0. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
4
+ console.warn("[mtcute-workspace] 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 utils_js = require("@mtcute/core/utils.js");
9
+ const wasm = require("@mtcute/wasm");
10
+ const wasm$1 = require("./wasm.cjs");
11
+ const ALGO_TO_SUBTLE = {
12
+ sha256: "SHA-256",
13
+ sha1: "SHA-1",
14
+ sha512: "SHA-512"
15
+ };
16
+ class WebCryptoProvider extends utils_js.BaseCryptoProvider {
17
+ crypto;
18
+ _wasmInput;
19
+ sha1(data) {
20
+ return wasm.sha1(data);
21
+ }
22
+ sha256(data) {
23
+ return wasm.sha256(data);
24
+ }
25
+ createAesCtr(key, iv) {
26
+ const ctx = wasm.createCtr256(key, iv);
27
+ return {
28
+ process: (data) => wasm.ctr256(ctx, data),
29
+ close: () => wasm.freeCtr256(ctx)
30
+ };
31
+ }
32
+ createAesIge(key, iv) {
33
+ return {
34
+ encrypt: (data) => wasm.ige256Encrypt(data, key, iv),
35
+ decrypt: (data) => wasm.ige256Decrypt(data, key, iv)
36
+ };
37
+ }
38
+ gzip(data, maxSize) {
39
+ return wasm.deflateMaxSize(data, maxSize);
40
+ }
41
+ gunzip(data) {
42
+ return wasm.gunzip(data);
43
+ }
44
+ constructor(params) {
45
+ super();
46
+ const crypto = params?.crypto ?? globalThis.crypto;
47
+ if (!crypto || !crypto.subtle) {
48
+ throw new Error("WebCrypto is not available");
49
+ }
50
+ this.crypto = crypto;
51
+ this._wasmInput = params?.wasmInput;
52
+ }
53
+ async initialize() {
54
+ wasm.initSync(await wasm$1.loadWasmBinary(this._wasmInput));
55
+ }
56
+ async pbkdf2(password, salt, iterations, keylen, algo) {
57
+ const keyMaterial = await this.crypto.subtle.importKey("raw", password, "PBKDF2", false, ["deriveBits"]);
58
+ return this.crypto.subtle.deriveBits(
59
+ {
60
+ name: "PBKDF2",
61
+ salt,
62
+ iterations,
63
+ hash: algo ? ALGO_TO_SUBTLE[algo] : "SHA-512"
64
+ },
65
+ keyMaterial,
66
+ (keylen || 64) * 8
67
+ ).then((result) => new Uint8Array(result));
68
+ }
69
+ async hmacSha256(data, key) {
70
+ const keyMaterial = await this.crypto.subtle.importKey(
71
+ "raw",
72
+ key,
73
+ { name: "HMAC", hash: { name: "SHA-256" } },
74
+ false,
75
+ ["sign"]
76
+ );
77
+ const res = await this.crypto.subtle.sign({ name: "HMAC" }, keyMaterial, data);
78
+ return new Uint8Array(res);
79
+ }
80
+ randomFill(buf) {
81
+ this.crypto.getRandomValues(buf);
82
+ }
83
+ }
84
+ exports.WebCryptoProvider = WebCryptoProvider;
package/crypto.js ADDED
@@ -0,0 +1,79 @@
1
+ import { BaseCryptoProvider } from "@mtcute/core/utils.js";
2
+ import { sha1, sha256, createCtr256, freeCtr256, ctr256, ige256Decrypt, ige256Encrypt, deflateMaxSize, gunzip, initSync } from "@mtcute/wasm";
3
+ import { loadWasmBinary } from "./wasm.js";
4
+ const ALGO_TO_SUBTLE = {
5
+ sha256: "SHA-256",
6
+ sha1: "SHA-1",
7
+ sha512: "SHA-512"
8
+ };
9
+ class WebCryptoProvider extends BaseCryptoProvider {
10
+ crypto;
11
+ _wasmInput;
12
+ sha1(data) {
13
+ return sha1(data);
14
+ }
15
+ sha256(data) {
16
+ return sha256(data);
17
+ }
18
+ createAesCtr(key, iv) {
19
+ const ctx = createCtr256(key, iv);
20
+ return {
21
+ process: (data) => ctr256(ctx, data),
22
+ close: () => freeCtr256(ctx)
23
+ };
24
+ }
25
+ createAesIge(key, iv) {
26
+ return {
27
+ encrypt: (data) => ige256Encrypt(data, key, iv),
28
+ decrypt: (data) => ige256Decrypt(data, key, iv)
29
+ };
30
+ }
31
+ gzip(data, maxSize) {
32
+ return deflateMaxSize(data, maxSize);
33
+ }
34
+ gunzip(data) {
35
+ return gunzip(data);
36
+ }
37
+ constructor(params) {
38
+ super();
39
+ const crypto = params?.crypto ?? globalThis.crypto;
40
+ if (!crypto || !crypto.subtle) {
41
+ throw new Error("WebCrypto is not available");
42
+ }
43
+ this.crypto = crypto;
44
+ this._wasmInput = params?.wasmInput;
45
+ }
46
+ async initialize() {
47
+ initSync(await loadWasmBinary(this._wasmInput));
48
+ }
49
+ async pbkdf2(password, salt, iterations, keylen, algo) {
50
+ const keyMaterial = await this.crypto.subtle.importKey("raw", password, "PBKDF2", false, ["deriveBits"]);
51
+ return this.crypto.subtle.deriveBits(
52
+ {
53
+ name: "PBKDF2",
54
+ salt,
55
+ iterations,
56
+ hash: algo ? ALGO_TO_SUBTLE[algo] : "SHA-512"
57
+ },
58
+ keyMaterial,
59
+ (keylen || 64) * 8
60
+ ).then((result) => new Uint8Array(result));
61
+ }
62
+ async hmacSha256(data, key) {
63
+ const keyMaterial = await this.crypto.subtle.importKey(
64
+ "raw",
65
+ key,
66
+ { name: "HMAC", hash: { name: "SHA-256" } },
67
+ false,
68
+ ["sign"]
69
+ );
70
+ const res = await this.crypto.subtle.sign({ name: "HMAC" }, keyMaterial, data);
71
+ return new Uint8Array(res);
72
+ }
73
+ randomFill(buf) {
74
+ this.crypto.getRandomValues(buf);
75
+ }
76
+ }
77
+ export {
78
+ WebCryptoProvider
79
+ };
package/exit-hook.cjs ADDED
@@ -0,0 +1,28 @@
1
+ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
2
+ globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
3
+ console.warn("[mtcute-workspace] CommonJS support is deprecated and will be removed in 0.20.0. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
4
+ console.warn("[mtcute-workspace] 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 callbacks = /* @__PURE__ */ new Set();
9
+ let registered = false;
10
+ function beforeExit(fn) {
11
+ if (typeof window === "undefined") {
12
+ return () => {
13
+ };
14
+ }
15
+ if (!registered) {
16
+ registered = true;
17
+ window.addEventListener("beforeunload", () => {
18
+ for (const callback of callbacks) {
19
+ callback();
20
+ }
21
+ });
22
+ }
23
+ callbacks.add(fn);
24
+ return () => {
25
+ callbacks.delete(fn);
26
+ };
27
+ }
28
+ exports.beforeExit = beforeExit;
package/exit-hook.js ADDED
@@ -0,0 +1,23 @@
1
+ const callbacks = /* @__PURE__ */ new Set();
2
+ let registered = false;
3
+ function beforeExit(fn) {
4
+ if (typeof window === "undefined") {
5
+ return () => {
6
+ };
7
+ }
8
+ if (!registered) {
9
+ registered = true;
10
+ window.addEventListener("beforeunload", () => {
11
+ for (const callback of callbacks) {
12
+ callback();
13
+ }
14
+ });
15
+ }
16
+ callbacks.add(fn);
17
+ return () => {
18
+ callbacks.delete(fn);
19
+ };
20
+ }
21
+ export {
22
+ beforeExit
23
+ };
package/idb/driver.cjs ADDED
@@ -0,0 +1,123 @@
1
+ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
2
+ globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
3
+ console.warn("[mtcute-workspace] CommonJS support is deprecated and will be removed in 0.20.0. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
4
+ console.warn("[mtcute-workspace] 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 core = require("@mtcute/core");
9
+ const utils = require("./utils.cjs");
10
+ const REPO_VERSION_PREFIX = "__version:";
11
+ class IdbStorageDriver extends core.BaseStorageDriver {
12
+ constructor(_dbName) {
13
+ super();
14
+ this._dbName = _dbName;
15
+ if (typeof indexedDB === "undefined") {
16
+ throw new core.MtUnsupportedError("IndexedDB is not available");
17
+ }
18
+ }
19
+ db;
20
+ _pendingWrites = [];
21
+ _pendingWritesOses = /* @__PURE__ */ new Set();
22
+ _migrations = /* @__PURE__ */ new Map();
23
+ _maxVersion = /* @__PURE__ */ new Map();
24
+ registerMigration(repo, version, migration) {
25
+ if (this.loaded) {
26
+ throw new Error("Cannot register migrations after loading");
27
+ }
28
+ let map = this._migrations.get(repo);
29
+ if (!map) {
30
+ map = /* @__PURE__ */ new Map();
31
+ this._migrations.set(repo, map);
32
+ }
33
+ if (map.has(version)) {
34
+ throw new Error(`Migration for ${repo} version ${version} is already registered`);
35
+ }
36
+ map.set(version, migration);
37
+ const prevMax = this._maxVersion.get(repo) ?? 0;
38
+ if (version > prevMax) {
39
+ this._maxVersion.set(repo, version);
40
+ }
41
+ }
42
+ writeLater(os, obj) {
43
+ this._pendingWrites.push([os, obj]);
44
+ this._pendingWritesOses.add(os);
45
+ }
46
+ async _load() {
47
+ this.db = await new Promise((resolve, reject) => {
48
+ const req = indexedDB.open(this._dbName, Date.now());
49
+ req.onerror = () => reject(req.error);
50
+ const postUpgrade = [];
51
+ req.onsuccess = async () => {
52
+ try {
53
+ for (const cb of postUpgrade) {
54
+ await cb(req.result);
55
+ }
56
+ resolve(req.result);
57
+ } catch (e) {
58
+ reject(e);
59
+ }
60
+ };
61
+ req.onupgradeneeded = () => {
62
+ const db = req.result;
63
+ const didUpgrade = /* @__PURE__ */ new Set();
64
+ const doUpgrade = (repo, fromVersion) => {
65
+ const migrations = this._migrations.get(repo);
66
+ if (!migrations) return;
67
+ const targetVer = this._maxVersion.get(repo);
68
+ while (fromVersion < targetVer) {
69
+ const nextVersion = fromVersion + 1;
70
+ const migration = migrations.get(nextVersion);
71
+ if (!migration) {
72
+ throw new Error(`No migration for ${repo} to version ${nextVersion}`);
73
+ }
74
+ const result = migration(db);
75
+ if (result) {
76
+ postUpgrade.push(result);
77
+ }
78
+ fromVersion = nextVersion;
79
+ }
80
+ didUpgrade.add(repo);
81
+ db.createObjectStore(`${REPO_VERSION_PREFIX}${repo}:${targetVer}`);
82
+ };
83
+ for (const key of db.objectStoreNames) {
84
+ if (!key.startsWith(REPO_VERSION_PREFIX)) continue;
85
+ const [, repo, version] = key.split(":");
86
+ const currentVer = Number(version);
87
+ db.deleteObjectStore(key);
88
+ doUpgrade(repo, currentVer);
89
+ didUpgrade.add(repo);
90
+ }
91
+ for (const repo of this._migrations.keys()) {
92
+ if (didUpgrade.has(repo)) continue;
93
+ doUpgrade(repo, 0);
94
+ }
95
+ };
96
+ });
97
+ }
98
+ async _save() {
99
+ if (this._pendingWritesOses.size === 0) return;
100
+ const writes = this._pendingWrites;
101
+ const oses = this._pendingWritesOses;
102
+ this._pendingWrites = [];
103
+ this._pendingWritesOses = /* @__PURE__ */ new Set();
104
+ const tx = this.db.transaction(oses, "readwrite");
105
+ const osMap = /* @__PURE__ */ new Map();
106
+ for (const table of oses) {
107
+ osMap.set(table, tx.objectStore(table));
108
+ }
109
+ for (const [table, obj] of writes) {
110
+ const os = osMap.get(table);
111
+ if (obj === null) {
112
+ os.delete(table);
113
+ } else {
114
+ os.put(obj);
115
+ }
116
+ }
117
+ await utils.txToPromise(tx);
118
+ }
119
+ _destroy() {
120
+ this.db.close();
121
+ }
122
+ }
123
+ exports.IdbStorageDriver = IdbStorageDriver;
package/idb/driver.js ADDED
@@ -0,0 +1,118 @@
1
+ import { BaseStorageDriver, MtUnsupportedError } from "@mtcute/core";
2
+ import { txToPromise } from "./utils.js";
3
+ const REPO_VERSION_PREFIX = "__version:";
4
+ class IdbStorageDriver extends BaseStorageDriver {
5
+ constructor(_dbName) {
6
+ super();
7
+ this._dbName = _dbName;
8
+ if (typeof indexedDB === "undefined") {
9
+ throw new MtUnsupportedError("IndexedDB is not available");
10
+ }
11
+ }
12
+ db;
13
+ _pendingWrites = [];
14
+ _pendingWritesOses = /* @__PURE__ */ new Set();
15
+ _migrations = /* @__PURE__ */ new Map();
16
+ _maxVersion = /* @__PURE__ */ new Map();
17
+ registerMigration(repo, version, migration) {
18
+ if (this.loaded) {
19
+ throw new Error("Cannot register migrations after loading");
20
+ }
21
+ let map = this._migrations.get(repo);
22
+ if (!map) {
23
+ map = /* @__PURE__ */ new Map();
24
+ this._migrations.set(repo, map);
25
+ }
26
+ if (map.has(version)) {
27
+ throw new Error(`Migration for ${repo} version ${version} is already registered`);
28
+ }
29
+ map.set(version, migration);
30
+ const prevMax = this._maxVersion.get(repo) ?? 0;
31
+ if (version > prevMax) {
32
+ this._maxVersion.set(repo, version);
33
+ }
34
+ }
35
+ writeLater(os, obj) {
36
+ this._pendingWrites.push([os, obj]);
37
+ this._pendingWritesOses.add(os);
38
+ }
39
+ async _load() {
40
+ this.db = await new Promise((resolve, reject) => {
41
+ const req = indexedDB.open(this._dbName, Date.now());
42
+ req.onerror = () => reject(req.error);
43
+ const postUpgrade = [];
44
+ req.onsuccess = async () => {
45
+ try {
46
+ for (const cb of postUpgrade) {
47
+ await cb(req.result);
48
+ }
49
+ resolve(req.result);
50
+ } catch (e) {
51
+ reject(e);
52
+ }
53
+ };
54
+ req.onupgradeneeded = () => {
55
+ const db = req.result;
56
+ const didUpgrade = /* @__PURE__ */ new Set();
57
+ const doUpgrade = (repo, fromVersion) => {
58
+ const migrations = this._migrations.get(repo);
59
+ if (!migrations) return;
60
+ const targetVer = this._maxVersion.get(repo);
61
+ while (fromVersion < targetVer) {
62
+ const nextVersion = fromVersion + 1;
63
+ const migration = migrations.get(nextVersion);
64
+ if (!migration) {
65
+ throw new Error(`No migration for ${repo} to version ${nextVersion}`);
66
+ }
67
+ const result = migration(db);
68
+ if (result) {
69
+ postUpgrade.push(result);
70
+ }
71
+ fromVersion = nextVersion;
72
+ }
73
+ didUpgrade.add(repo);
74
+ db.createObjectStore(`${REPO_VERSION_PREFIX}${repo}:${targetVer}`);
75
+ };
76
+ for (const key of db.objectStoreNames) {
77
+ if (!key.startsWith(REPO_VERSION_PREFIX)) continue;
78
+ const [, repo, version] = key.split(":");
79
+ const currentVer = Number(version);
80
+ db.deleteObjectStore(key);
81
+ doUpgrade(repo, currentVer);
82
+ didUpgrade.add(repo);
83
+ }
84
+ for (const repo of this._migrations.keys()) {
85
+ if (didUpgrade.has(repo)) continue;
86
+ doUpgrade(repo, 0);
87
+ }
88
+ };
89
+ });
90
+ }
91
+ async _save() {
92
+ if (this._pendingWritesOses.size === 0) return;
93
+ const writes = this._pendingWrites;
94
+ const oses = this._pendingWritesOses;
95
+ this._pendingWrites = [];
96
+ this._pendingWritesOses = /* @__PURE__ */ new Set();
97
+ const tx = this.db.transaction(oses, "readwrite");
98
+ const osMap = /* @__PURE__ */ new Map();
99
+ for (const table of oses) {
100
+ osMap.set(table, tx.objectStore(table));
101
+ }
102
+ for (const [table, obj] of writes) {
103
+ const os = osMap.get(table);
104
+ if (obj === null) {
105
+ os.delete(table);
106
+ } else {
107
+ os.put(obj);
108
+ }
109
+ }
110
+ await txToPromise(tx);
111
+ }
112
+ _destroy() {
113
+ this.db.close();
114
+ }
115
+ }
116
+ export {
117
+ IdbStorageDriver
118
+ };
package/idb/index.cjs ADDED
@@ -0,0 +1,29 @@
1
+ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WARNED) {
2
+ globalThis._MTCUTE_CJS_DEPRECATION_WARNED = true;
3
+ console.warn("[mtcute-workspace] CommonJS support is deprecated and will be removed in 0.20.0. Please consider switching to ESM, it's " + (/* @__PURE__ */ new Date()).getFullYear() + " already.");
4
+ console.warn("[mtcute-workspace] 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 driver = require("./driver.cjs");
9
+ const authKeys = require("./repository/auth-keys.cjs");
10
+ const kv = require("./repository/kv.cjs");
11
+ const peers = require("./repository/peers.cjs");
12
+ const refMessages = require("./repository/ref-messages.cjs");
13
+ class IdbStorage {
14
+ constructor(dbName) {
15
+ this.dbName = dbName;
16
+ this.driver = new driver.IdbStorageDriver(this.dbName);
17
+ this.kv = new kv.IdbKvRepository(this.driver);
18
+ this.authKeys = new authKeys.IdbAuthKeysRepository(this.driver);
19
+ this.peers = new peers.IdbPeersRepository(this.driver);
20
+ this.refMessages = new refMessages.IdbRefMsgRepository(this.driver);
21
+ }
22
+ driver;
23
+ kv;
24
+ authKeys;
25
+ peers;
26
+ refMessages;
27
+ }
28
+ exports.IdbStorageDriver = driver.IdbStorageDriver;
29
+ exports.IdbStorage = IdbStorage;