@mtcute/web 0.8.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.
Files changed (118) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +53 -0
  3. package/cjs/client.d.ts +30 -0
  4. package/cjs/client.js +40 -0
  5. package/cjs/client.js.map +1 -0
  6. package/cjs/crypto.d.ts +21 -0
  7. package/cjs/crypto.js +71 -0
  8. package/cjs/crypto.js.map +1 -0
  9. package/cjs/encodings/base64.d.ts +2 -0
  10. package/cjs/encodings/base64.js +112 -0
  11. package/cjs/encodings/base64.js.map +1 -0
  12. package/cjs/encodings/hex.d.ts +2 -0
  13. package/cjs/encodings/hex.js +69 -0
  14. package/cjs/encodings/hex.js.map +1 -0
  15. package/cjs/encodings/utf8.d.ts +3 -0
  16. package/cjs/encodings/utf8.js +29 -0
  17. package/cjs/encodings/utf8.js.map +1 -0
  18. package/cjs/exit-hook.d.ts +1 -0
  19. package/cjs/exit-hook.js +24 -0
  20. package/cjs/exit-hook.js.map +1 -0
  21. package/cjs/idb/driver.d.ts +18 -0
  22. package/cjs/idb/driver.js +137 -0
  23. package/cjs/idb/driver.js.map +1 -0
  24. package/cjs/idb/index.d.ts +22 -0
  25. package/cjs/idb/index.js +28 -0
  26. package/cjs/idb/index.js.map +1 -0
  27. package/cjs/idb/repository/auth-keys.d.ts +14 -0
  28. package/cjs/idb/repository/auth-keys.js +70 -0
  29. package/cjs/idb/repository/auth-keys.js.map +1 -0
  30. package/cjs/idb/repository/kv.d.ts +11 -0
  31. package/cjs/idb/repository/kv.js +34 -0
  32. package/cjs/idb/repository/kv.js.map +1 -0
  33. package/cjs/idb/repository/peers.d.ts +12 -0
  34. package/cjs/idb/repository/peers.js +38 -0
  35. package/cjs/idb/repository/peers.js.map +1 -0
  36. package/cjs/idb/repository/ref-messages.d.ts +12 -0
  37. package/cjs/idb/repository/ref-messages.js +57 -0
  38. package/cjs/idb/repository/ref-messages.js.map +1 -0
  39. package/cjs/idb/utils.d.ts +3 -0
  40. package/cjs/idb/utils.js +27 -0
  41. package/cjs/idb/utils.js.map +1 -0
  42. package/cjs/index.d.ts +7 -0
  43. package/cjs/index.js +24 -0
  44. package/cjs/index.js.map +1 -0
  45. package/cjs/logging.d.ts +1 -0
  46. package/cjs/logging.js +35 -0
  47. package/cjs/logging.js.map +1 -0
  48. package/cjs/package.json +3 -0
  49. package/cjs/platform.d.ts +21 -0
  50. package/cjs/platform.js +49 -0
  51. package/cjs/platform.js.map +1 -0
  52. package/cjs/wasm.d.ts +2 -0
  53. package/cjs/wasm.js +36 -0
  54. package/cjs/wasm.js.map +1 -0
  55. package/cjs/websocket.d.ts +45 -0
  56. package/cjs/websocket.js +121 -0
  57. package/cjs/websocket.js.map +1 -0
  58. package/cjs/worker.d.ts +10 -0
  59. package/cjs/worker.js +128 -0
  60. package/cjs/worker.js.map +1 -0
  61. package/esm/client.d.ts +30 -0
  62. package/esm/client.js +35 -0
  63. package/esm/client.js.map +1 -0
  64. package/esm/crypto.d.ts +21 -0
  65. package/esm/crypto.js +67 -0
  66. package/esm/crypto.js.map +1 -0
  67. package/esm/encodings/base64.d.ts +2 -0
  68. package/esm/encodings/base64.js +107 -0
  69. package/esm/encodings/base64.js.map +1 -0
  70. package/esm/encodings/hex.d.ts +2 -0
  71. package/esm/encodings/hex.js +64 -0
  72. package/esm/encodings/hex.js.map +1 -0
  73. package/esm/encodings/utf8.d.ts +3 -0
  74. package/esm/encodings/utf8.js +23 -0
  75. package/esm/encodings/utf8.js.map +1 -0
  76. package/esm/exit-hook.d.ts +1 -0
  77. package/esm/exit-hook.js +20 -0
  78. package/esm/exit-hook.js.map +1 -0
  79. package/esm/idb/driver.d.ts +18 -0
  80. package/esm/idb/driver.js +133 -0
  81. package/esm/idb/driver.js.map +1 -0
  82. package/esm/idb/index.d.ts +22 -0
  83. package/esm/idb/index.js +23 -0
  84. package/esm/idb/index.js.map +1 -0
  85. package/esm/idb/repository/auth-keys.d.ts +14 -0
  86. package/esm/idb/repository/auth-keys.js +66 -0
  87. package/esm/idb/repository/auth-keys.js.map +1 -0
  88. package/esm/idb/repository/kv.d.ts +11 -0
  89. package/esm/idb/repository/kv.js +30 -0
  90. package/esm/idb/repository/kv.js.map +1 -0
  91. package/esm/idb/repository/peers.d.ts +12 -0
  92. package/esm/idb/repository/peers.js +34 -0
  93. package/esm/idb/repository/peers.js.map +1 -0
  94. package/esm/idb/repository/ref-messages.d.ts +12 -0
  95. package/esm/idb/repository/ref-messages.js +53 -0
  96. package/esm/idb/repository/ref-messages.js.map +1 -0
  97. package/esm/idb/utils.d.ts +3 -0
  98. package/esm/idb/utils.js +21 -0
  99. package/esm/idb/utils.js.map +1 -0
  100. package/esm/index.d.ts +7 -0
  101. package/esm/index.js +8 -0
  102. package/esm/index.js.map +1 -0
  103. package/esm/logging.d.ts +1 -0
  104. package/esm/logging.js +31 -0
  105. package/esm/logging.js.map +1 -0
  106. package/esm/platform.d.ts +21 -0
  107. package/esm/platform.js +45 -0
  108. package/esm/platform.js.map +1 -0
  109. package/esm/wasm.d.ts +2 -0
  110. package/esm/wasm.js +32 -0
  111. package/esm/wasm.js.map +1 -0
  112. package/esm/websocket.d.ts +45 -0
  113. package/esm/websocket.js +113 -0
  114. package/esm/websocket.js.map +1 -0
  115. package/esm/worker.d.ts +10 -0
  116. package/esm/worker.js +123 -0
  117. package/esm/worker.js.map +1 -0
  118. package/package.json +26 -0
package/esm/crypto.js ADDED
@@ -0,0 +1,67 @@
1
+ import { BaseCryptoProvider } from '@mtcute/core/utils.js';
2
+ import { createCtr256, ctr256, deflateMaxSize, freeCtr256, gunzip, ige256Decrypt, ige256Encrypt, initSync, sha1, sha256, } 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
+ export class WebCryptoProvider extends BaseCryptoProvider {
10
+ sha1(data) {
11
+ return sha1(data);
12
+ }
13
+ sha256(data) {
14
+ return sha256(data);
15
+ }
16
+ createAesCtr(key, iv) {
17
+ const ctx = createCtr256(key, iv);
18
+ return {
19
+ process: (data) => ctr256(ctx, data),
20
+ close: () => freeCtr256(ctx),
21
+ };
22
+ }
23
+ createAesIge(key, iv) {
24
+ return {
25
+ encrypt: (data) => ige256Encrypt(data, key, iv),
26
+ decrypt: (data) => ige256Decrypt(data, key, iv),
27
+ };
28
+ }
29
+ gzip(data, maxSize) {
30
+ return deflateMaxSize(data, maxSize);
31
+ }
32
+ gunzip(data) {
33
+ return gunzip(data);
34
+ }
35
+ constructor(params) {
36
+ super();
37
+ const crypto = params?.crypto ?? globalThis.crypto;
38
+ if (!crypto || !crypto.subtle) {
39
+ throw new Error('WebCrypto is not available');
40
+ }
41
+ this.crypto = crypto;
42
+ this._wasmInput = params?.wasmInput;
43
+ }
44
+ async initialize() {
45
+ initSync(await loadWasmBinary(this._wasmInput));
46
+ }
47
+ async pbkdf2(password, salt, iterations, keylen, algo) {
48
+ const keyMaterial = await this.crypto.subtle.importKey('raw', password, 'PBKDF2', false, ['deriveBits']);
49
+ return this.crypto.subtle
50
+ .deriveBits({
51
+ name: 'PBKDF2',
52
+ salt,
53
+ iterations,
54
+ hash: algo ? ALGO_TO_SUBTLE[algo] : 'SHA-512',
55
+ }, keyMaterial, (keylen || 64) * 8)
56
+ .then((result) => new Uint8Array(result));
57
+ }
58
+ async hmacSha256(data, key) {
59
+ const keyMaterial = await this.crypto.subtle.importKey('raw', key, { name: 'HMAC', hash: { name: 'SHA-256' } }, false, ['sign']);
60
+ const res = await this.crypto.subtle.sign({ name: 'HMAC' }, keyMaterial, data);
61
+ return new Uint8Array(res);
62
+ }
63
+ randomFill(buf) {
64
+ this.crypto.getRandomValues(buf);
65
+ }
66
+ }
67
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/crypto.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseCryptoProvider, IAesCtr, ICryptoProvider, IEncryptionScheme } from '@mtcute/core/utils.js'\nimport {\n createCtr256,\n ctr256,\n deflateMaxSize,\n freeCtr256,\n gunzip,\n ige256Decrypt,\n ige256Encrypt,\n initSync,\n sha1,\n sha256,\n} from '@mtcute/wasm'\n\nimport { loadWasmBinary, WasmInitInput } from './wasm.js'\n\nconst ALGO_TO_SUBTLE: Record<string, string> = {\n sha256: 'SHA-256',\n sha1: 'SHA-1',\n sha512: 'SHA-512',\n}\n\nexport interface WebCryptoProviderOptions {\n crypto?: Crypto\n wasmInput?: WasmInitInput\n}\n\nexport class WebCryptoProvider extends BaseCryptoProvider implements ICryptoProvider {\n readonly crypto: Crypto\n private _wasmInput?: WasmInitInput\n\n sha1(data: Uint8Array): Uint8Array {\n return sha1(data)\n }\n\n sha256(data: Uint8Array): Uint8Array {\n return sha256(data)\n }\n\n createAesCtr(key: Uint8Array, iv: Uint8Array): IAesCtr {\n const ctx = createCtr256(key, iv)\n\n return {\n process: (data) => ctr256(ctx, data),\n close: () => freeCtr256(ctx),\n }\n }\n\n createAesIge(key: Uint8Array, iv: Uint8Array): IEncryptionScheme {\n return {\n encrypt: (data) => ige256Encrypt(data, key, iv),\n decrypt: (data) => ige256Decrypt(data, key, iv),\n }\n }\n\n gzip(data: Uint8Array, maxSize: number): Uint8Array | null {\n return deflateMaxSize(data, maxSize)\n }\n\n gunzip(data: Uint8Array): Uint8Array {\n return gunzip(data)\n }\n\n constructor(params?: WebCryptoProviderOptions) {\n super()\n const crypto = params?.crypto ?? globalThis.crypto\n\n if (!crypto || !crypto.subtle) {\n throw new Error('WebCrypto is not available')\n }\n this.crypto = crypto\n this._wasmInput = params?.wasmInput\n }\n\n async initialize(): Promise<void> {\n initSync(await loadWasmBinary(this._wasmInput))\n }\n\n async pbkdf2(\n password: Uint8Array,\n salt: Uint8Array,\n iterations: number,\n keylen?: number | undefined,\n algo?: string | undefined,\n ): Promise<Uint8Array> {\n const keyMaterial = await this.crypto.subtle.importKey('raw', password, 'PBKDF2', false, ['deriveBits'])\n\n return this.crypto.subtle\n .deriveBits(\n {\n name: 'PBKDF2',\n salt,\n iterations,\n hash: algo ? ALGO_TO_SUBTLE[algo] : 'SHA-512',\n },\n keyMaterial,\n (keylen || 64) * 8,\n )\n .then((result) => new Uint8Array(result))\n }\n\n async hmacSha256(data: Uint8Array, key: Uint8Array): Promise<Uint8Array> {\n const keyMaterial = await this.crypto.subtle.importKey(\n 'raw',\n key,\n { name: 'HMAC', hash: { name: 'SHA-256' } },\n false,\n ['sign'],\n )\n\n const res = await this.crypto.subtle.sign({ name: 'HMAC' }, keyMaterial, data)\n\n return new Uint8Array(res)\n }\n\n randomFill(buf: Uint8Array): void {\n this.crypto.getRandomValues(buf)\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function base64Encode(buf: Uint8Array, url?: boolean): string;
2
+ export declare function base64Decode(string: string, url?: boolean): Uint8Array;
@@ -0,0 +1,107 @@
1
+ /// Based on https://github.com/beatgammit/base64-js, MIT license
2
+ const lookup = [];
3
+ const revLookup = [];
4
+ const code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
5
+ for (let i = 0, len = code.length; i < len; ++i) {
6
+ lookup[i] = code[i];
7
+ revLookup[code.charCodeAt(i)] = i;
8
+ }
9
+ function getLens(b64) {
10
+ const len = b64.length;
11
+ if (len % 4 > 0) {
12
+ throw new Error('Invalid string. Length must be a multiple of 4');
13
+ }
14
+ // Trim off extra bytes after placeholder bytes are found
15
+ // See: https://github.com/beatgammit/base64-js/issues/42
16
+ let validLen = b64.indexOf('=');
17
+ if (validLen === -1)
18
+ validLen = len;
19
+ const placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4);
20
+ return [validLen, placeHoldersLen];
21
+ }
22
+ function _byteLength(b64, validLen, placeHoldersLen) {
23
+ return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;
24
+ }
25
+ function toByteArray(b64, arr) {
26
+ let tmp;
27
+ const lens = getLens(b64);
28
+ const validLen = lens[0];
29
+ const placeHoldersLen = lens[1];
30
+ let curByte = 0;
31
+ // if there are placeholders, only get up to the last complete 4 chars
32
+ const len = placeHoldersLen > 0 ? validLen - 4 : validLen;
33
+ let i;
34
+ for (i = 0; i < len; i += 4) {
35
+ tmp =
36
+ (revLookup[b64.charCodeAt(i)] << 18) |
37
+ (revLookup[b64.charCodeAt(i + 1)] << 12) |
38
+ (revLookup[b64.charCodeAt(i + 2)] << 6) |
39
+ revLookup[b64.charCodeAt(i + 3)];
40
+ arr[curByte++] = (tmp >> 16) & 0xff;
41
+ arr[curByte++] = (tmp >> 8) & 0xff;
42
+ arr[curByte++] = tmp & 0xff;
43
+ }
44
+ if (placeHoldersLen === 2) {
45
+ tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4);
46
+ arr[curByte++] = tmp & 0xff;
47
+ }
48
+ if (placeHoldersLen === 1) {
49
+ tmp =
50
+ (revLookup[b64.charCodeAt(i)] << 10) |
51
+ (revLookup[b64.charCodeAt(i + 1)] << 4) |
52
+ (revLookup[b64.charCodeAt(i + 2)] >> 2);
53
+ arr[curByte++] = (tmp >> 8) & 0xff;
54
+ arr[curByte++] = tmp & 0xff;
55
+ }
56
+ return arr;
57
+ }
58
+ function tripletToBase64(num) {
59
+ return lookup[(num >> 18) & 0x3f] + lookup[(num >> 12) & 0x3f] + lookup[(num >> 6) & 0x3f] + lookup[num & 0x3f];
60
+ }
61
+ function encodeChunk(uint8, start, end) {
62
+ let tmp;
63
+ const output = [];
64
+ for (let i = start; i < end; i += 3) {
65
+ tmp = ((uint8[i] << 16) & 0xff0000) + ((uint8[i + 1] << 8) & 0xff00) + (uint8[i + 2] & 0xff);
66
+ output.push(tripletToBase64(tmp));
67
+ }
68
+ return output.join('');
69
+ }
70
+ function fromByteArray(uint8) {
71
+ let tmp;
72
+ const len = uint8.length;
73
+ const extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
74
+ const parts = [];
75
+ const maxChunkLength = 16383; // must be multiple of 3
76
+ // go through the array every three bytes, we'll deal with trailing stuff later
77
+ for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
78
+ parts.push(encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength));
79
+ }
80
+ // pad the end with zeros, but make sure to not forget the extra bytes
81
+ if (extraBytes === 1) {
82
+ tmp = uint8[len - 1];
83
+ parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + '==');
84
+ }
85
+ else if (extraBytes === 2) {
86
+ tmp = (uint8[len - 2] << 8) + uint8[len - 1];
87
+ parts.push(lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3f] + lookup[(tmp << 2) & 0x3f] + '=');
88
+ }
89
+ return parts.join('');
90
+ }
91
+ export function base64Encode(buf, url = false) {
92
+ const str = fromByteArray(buf);
93
+ if (url)
94
+ return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
95
+ return str;
96
+ }
97
+ export function base64Decode(string, url = false) {
98
+ if (url) {
99
+ string = string.replace(/-/g, '+').replace(/_/g, '/');
100
+ while (string.length % 4)
101
+ string += '=';
102
+ }
103
+ const buf = new Uint8Array(_byteLength(string, ...getLens(string)));
104
+ toByteArray(string, buf);
105
+ return buf;
106
+ }
107
+ //# sourceMappingURL=base64.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base64.js","sourceRoot":"","sources":["../../../src/encodings/base64.ts"],"names":[],"mappings":"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","sourcesContent":["/// Based on https://github.com/beatgammit/base64-js, MIT license\nconst lookup: string[] = []\nconst revLookup: number[] = []\n\nconst code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n\nfor (let i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\nfunction getLens(b64: string): [number, number] {\n const len = b64.length\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n let validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n const placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\nfunction _byteLength(b64: string, validLen: number, placeHoldersLen: number) {\n return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen\n}\n\nfunction toByteArray(b64: string, arr: Uint8Array) {\n let tmp\n const lens = getLens(b64)\n const validLen = lens[0]\n const placeHoldersLen = lens[1]\n\n let curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n const len = placeHoldersLen > 0 ? validLen - 4 : validLen\n\n let i\n\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xff\n arr[curByte++] = (tmp >> 8) & 0xff\n arr[curByte++] = tmp & 0xff\n }\n\n if (placeHoldersLen === 2) {\n tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xff\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xff\n arr[curByte++] = tmp & 0xff\n }\n\n return arr\n}\n\nfunction tripletToBase64(num: number) {\n return lookup[(num >> 18) & 0x3f] + lookup[(num >> 12) & 0x3f] + lookup[(num >> 6) & 0x3f] + lookup[num & 0x3f]\n}\n\nfunction encodeChunk(uint8: Uint8Array, start: number, end: number) {\n let tmp\n const output = []\n\n for (let i = start; i < end; i += 3) {\n tmp = ((uint8[i] << 16) & 0xff0000) + ((uint8[i + 1] << 8) & 0xff00) + (uint8[i + 2] & 0xff)\n output.push(tripletToBase64(tmp))\n }\n\n return output.join('')\n}\n\nfunction fromByteArray(uint8: Uint8Array) {\n let tmp\n const len = uint8.length\n const extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n const parts = []\n const maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + '==')\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3f] + lookup[(tmp << 2) & 0x3f] + '=')\n }\n\n return parts.join('')\n}\n\nexport function base64Encode(buf: Uint8Array, url = false): string {\n const str = fromByteArray(buf)\n if (url) return str.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '')\n\n return str\n}\n\nexport function base64Decode(string: string, url = false): Uint8Array {\n if (url) {\n string = string.replace(/-/g, '+').replace(/_/g, '/')\n while (string.length % 4) string += '='\n }\n\n const buf = new Uint8Array(_byteLength(string, ...getLens(string)))\n\n toByteArray(string, buf)\n\n return buf\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function hexEncode(buf: Uint8Array): string;
2
+ export declare function hexDecode(string: string): Uint8Array;
@@ -0,0 +1,64 @@
1
+ /// Based on https://github.com/feross/buffer, MIT license
2
+ const hexSliceLookupTable = (function () {
3
+ const alphabet = '0123456789abcdef';
4
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
5
+ const table = new Array(256);
6
+ for (let i = 0; i < 16; ++i) {
7
+ const i16 = i * 16;
8
+ for (let j = 0; j < 16; ++j) {
9
+ table[i16 + j] = alphabet[i] + alphabet[j];
10
+ }
11
+ }
12
+ return table;
13
+ })();
14
+ const hexCharValueTable = {
15
+ '0': 0,
16
+ '1': 1,
17
+ '2': 2,
18
+ '3': 3,
19
+ '4': 4,
20
+ '5': 5,
21
+ '6': 6,
22
+ '7': 7,
23
+ '8': 8,
24
+ '9': 9,
25
+ a: 10,
26
+ b: 11,
27
+ c: 12,
28
+ d: 13,
29
+ e: 14,
30
+ f: 15,
31
+ A: 10,
32
+ B: 11,
33
+ C: 12,
34
+ D: 13,
35
+ E: 14,
36
+ F: 15,
37
+ };
38
+ export function hexEncode(buf) {
39
+ let out = '';
40
+ for (let i = 0; i < buf.byteLength; ++i) {
41
+ out += hexSliceLookupTable[buf[i]];
42
+ }
43
+ return out;
44
+ }
45
+ function hexDecodeInner(buf, string) {
46
+ const strLen = string.length;
47
+ const length = Math.min(buf.length, strLen / 2);
48
+ let i;
49
+ for (i = 0; i < length; ++i) {
50
+ const a = hexCharValueTable[string[i * 2]];
51
+ const b = hexCharValueTable[string[i * 2 + 1]];
52
+ if (a === undefined || b === undefined) {
53
+ return;
54
+ }
55
+ buf[i] = (a << 4) | b;
56
+ }
57
+ return;
58
+ }
59
+ export function hexDecode(string) {
60
+ const buf = new Uint8Array(Math.ceil(string.length / 2));
61
+ hexDecodeInner(buf, string);
62
+ return buf;
63
+ }
64
+ //# sourceMappingURL=hex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hex.js","sourceRoot":"","sources":["../../../src/encodings/hex.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAE1D,MAAM,mBAAmB,GAAG,CAAC;IACzB,MAAM,QAAQ,GAAG,kBAAkB,CAAA;IACnC,mEAAmE;IACnE,MAAM,KAAK,GAAa,IAAI,KAAK,CAAC,GAAG,CAAC,CAAA;IAEtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE;QACzB,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,CAAA;QAElB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE;YACzB,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;SAC7C;KACJ;IAED,OAAO,KAAK,CAAA;AAChB,CAAC,CAAC,EAAE,CAAA;AAEJ,MAAM,iBAAiB,GAA2B;IAC9C,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;IACL,CAAC,EAAE,EAAE;CACR,CAAA;AAED,MAAM,UAAU,SAAS,CAAC,GAAe;IACrC,IAAI,GAAG,GAAG,EAAE,CAAA;IAEZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE;QACrC,GAAG,IAAI,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;KACrC;IAED,OAAO,GAAG,CAAA;AACd,CAAC;AAED,SAAS,cAAc,CAAC,GAAe,EAAE,MAAc;IACnD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;IAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,CAAA;IAE/C,IAAI,CAAC,CAAA;IAEL,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,EAAE,CAAC,EAAE;QACzB,MAAM,CAAC,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAC1C,MAAM,CAAC,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAE9C,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,EAAE;YACpC,OAAM;SACT;QACD,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;KACxB;IAED,OAAM;AACV,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAc;IACpC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;IACxD,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAE3B,OAAO,GAAG,CAAA;AACd,CAAC","sourcesContent":["/// Based on https://github.com/feross/buffer, MIT license\n\nconst hexSliceLookupTable = (function () {\n const alphabet = '0123456789abcdef'\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const table: string[] = new Array(256)\n\n for (let i = 0; i < 16; ++i) {\n const i16 = i * 16\n\n for (let j = 0; j < 16; ++j) {\n table[i16 + j] = alphabet[i] + alphabet[j]\n }\n }\n\n return table\n})()\n\nconst hexCharValueTable: Record<string, number> = {\n '0': 0,\n '1': 1,\n '2': 2,\n '3': 3,\n '4': 4,\n '5': 5,\n '6': 6,\n '7': 7,\n '8': 8,\n '9': 9,\n a: 10,\n b: 11,\n c: 12,\n d: 13,\n e: 14,\n f: 15,\n A: 10,\n B: 11,\n C: 12,\n D: 13,\n E: 14,\n F: 15,\n}\n\nexport function hexEncode(buf: Uint8Array): string {\n let out = ''\n\n for (let i = 0; i < buf.byteLength; ++i) {\n out += hexSliceLookupTable[buf[i]]\n }\n\n return out\n}\n\nfunction hexDecodeInner(buf: Uint8Array, string: string): void {\n const strLen = string.length\n const length = Math.min(buf.length, strLen / 2)\n\n let i\n\n for (i = 0; i < length; ++i) {\n const a = hexCharValueTable[string[i * 2]]\n const b = hexCharValueTable[string[i * 2 + 1]]\n\n if (a === undefined || b === undefined) {\n return\n }\n buf[i] = (a << 4) | b\n }\n\n return\n}\n\nexport function hexDecode(string: string): Uint8Array {\n const buf = new Uint8Array(Math.ceil(string.length / 2))\n hexDecodeInner(buf, string)\n\n return buf\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export declare function utf8ByteLength(str: string): number;
2
+ export declare function utf8Decode(buf: Uint8Array): string;
3
+ export declare function utf8Encode(str: string): Uint8Array;
@@ -0,0 +1,23 @@
1
+ const sharedEncoder = new TextEncoder();
2
+ const sharedDecoder = new TextDecoder('utf8');
3
+ export function utf8ByteLength(str) {
4
+ // https://stackoverflow.com/a/23329386
5
+ let s = str.length;
6
+ for (let i = str.length - 1; i >= 0; i--) {
7
+ const code = str.charCodeAt(i);
8
+ if (code > 0x7f && code <= 0x7ff)
9
+ s++;
10
+ else if (code > 0x7ff && code <= 0xffff)
11
+ s += 2;
12
+ if (code >= 0xDC00 && code <= 0xDFFF)
13
+ i--; //trail surrogate
14
+ }
15
+ return s;
16
+ }
17
+ export function utf8Decode(buf) {
18
+ return sharedDecoder.decode(buf);
19
+ }
20
+ export function utf8Encode(str) {
21
+ return sharedEncoder.encode(str);
22
+ }
23
+ //# sourceMappingURL=utf8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utf8.js","sourceRoot":"","sources":["../../../src/encodings/utf8.ts"],"names":[],"mappings":"AAAA,MAAM,aAAa,GAAG,IAAI,WAAW,EAAE,CAAA;AACvC,MAAM,aAAa,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAA;AAE7C,MAAM,UAAU,cAAc,CAAC,GAAW;IACtC,uCAAuC;IACvC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAA;IAElB,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QAC9B,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,KAAK;YAAE,CAAC,EAAE,CAAA;aAChC,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,IAAI,MAAM;YAAE,CAAC,IAAI,CAAC,CAAA;QAC/C,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM;YAAE,CAAC,EAAE,CAAA,CAAC,iBAAiB;KAC9D;IAED,OAAO,CAAC,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAe;IACtC,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IAClC,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;AACpC,CAAC","sourcesContent":["const sharedEncoder = new TextEncoder()\nconst sharedDecoder = new TextDecoder('utf8')\n\nexport function utf8ByteLength(str: string) {\n // https://stackoverflow.com/a/23329386\n let s = str.length\n\n for (let i = str.length - 1; i >= 0; i--) {\n const code = str.charCodeAt(i)\n if (code > 0x7f && code <= 0x7ff) s++\n else if (code > 0x7ff && code <= 0xffff) s += 2\n if (code >= 0xDC00 && code <= 0xDFFF) i-- //trail surrogate\n }\n\n return s\n}\n\nexport function utf8Decode(buf: Uint8Array): string {\n return sharedDecoder.decode(buf)\n}\n\nexport function utf8Encode(str: string): Uint8Array {\n return sharedEncoder.encode(str)\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function beforeExit(fn: () => void): () => void;
@@ -0,0 +1,20 @@
1
+ const callbacks = new Set();
2
+ let registered = false;
3
+ export function beforeExit(fn) {
4
+ if (typeof window === 'undefined') {
5
+ return () => { };
6
+ }
7
+ if (!registered) {
8
+ registered = true;
9
+ window.addEventListener('beforeunload', () => {
10
+ for (const callback of callbacks) {
11
+ callback();
12
+ }
13
+ });
14
+ }
15
+ callbacks.add(fn);
16
+ return () => {
17
+ callbacks.delete(fn);
18
+ };
19
+ }
20
+ //# sourceMappingURL=exit-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-hook.js","sourceRoot":"","sources":["../../src/exit-hook.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAA;AAEvC,IAAI,UAAU,GAAG,KAAK,CAAA;AAEtB,MAAM,UAAU,UAAU,CAAC,EAAc;IACrC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QAC/B,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;KAClB;IACD,IAAI,CAAC,UAAU,EAAE;QACb,UAAU,GAAG,IAAI,CAAA;QAEjB,MAAM,CAAC,gBAAgB,CAAC,cAAc,EAAE,GAAG,EAAE;YACzC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;gBAC9B,QAAQ,EAAE,CAAA;aACb;QACL,CAAC,CAAC,CAAA;KACL;IAED,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAEjB,OAAO,GAAG,EAAE;QACR,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACxB,CAAC,CAAA;AACL,CAAC","sourcesContent":["const callbacks = new Set<() => void>()\n\nlet registered = false\n\nexport function beforeExit(fn: () => void): () => void {\n if (typeof window === 'undefined') {\n return () => {}\n }\n if (!registered) {\n registered = true\n\n window.addEventListener('beforeunload', () => {\n for (const callback of callbacks) {\n callback()\n }\n })\n }\n\n callbacks.add(fn)\n\n return () => {\n callbacks.delete(fn)\n }\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { BaseStorageDriver } from '@mtcute/core';
2
+ export type PostMigrationFunction = (db: IDBDatabase) => Promise<void>;
3
+ type MigrationFunction = (db: IDBDatabase) => void | PostMigrationFunction;
4
+ export declare class IdbStorageDriver extends BaseStorageDriver {
5
+ readonly _dbName: string;
6
+ db: IDBDatabase;
7
+ constructor(_dbName: string);
8
+ private _pendingWrites;
9
+ private _pendingWritesOses;
10
+ private _migrations;
11
+ private _maxVersion;
12
+ registerMigration(repo: string, version: number, migration: MigrationFunction): void;
13
+ writeLater(os: string, obj: unknown): void;
14
+ _load(): Promise<void>;
15
+ _save(): Promise<void>;
16
+ _destroy(): void;
17
+ }
18
+ export {};
@@ -0,0 +1,133 @@
1
+ import { BaseStorageDriver, MtUnsupportedError } from '@mtcute/core';
2
+ import { txToPromise } from './utils.js';
3
+ const REPO_VERSION_PREFIX = '__version:';
4
+ export class IdbStorageDriver extends BaseStorageDriver {
5
+ constructor(_dbName) {
6
+ super();
7
+ this._dbName = _dbName;
8
+ this._pendingWrites = [];
9
+ this._pendingWritesOses = new Set();
10
+ this._migrations = new Map();
11
+ this._maxVersion = new Map();
12
+ if (typeof indexedDB === 'undefined') {
13
+ throw new MtUnsupportedError('IndexedDB is not available');
14
+ }
15
+ }
16
+ registerMigration(repo, version, migration) {
17
+ if (this.loaded) {
18
+ throw new Error('Cannot register migrations after loading');
19
+ }
20
+ let map = this._migrations.get(repo);
21
+ if (!map) {
22
+ map = new Map();
23
+ this._migrations.set(repo, map);
24
+ }
25
+ if (map.has(version)) {
26
+ throw new Error(`Migration for ${repo} version ${version} is already registered`);
27
+ }
28
+ map.set(version, migration);
29
+ const prevMax = this._maxVersion.get(repo) ?? 0;
30
+ if (version > prevMax) {
31
+ this._maxVersion.set(repo, version);
32
+ }
33
+ }
34
+ writeLater(os, obj) {
35
+ this._pendingWrites.push([os, obj]);
36
+ this._pendingWritesOses.add(os);
37
+ }
38
+ async _load() {
39
+ this.db = await new Promise((resolve, reject) => {
40
+ // indexed db fucking sucks - we can't create tables once we have loaded
41
+ // and making an ever-incrementing version number is pretty hard
42
+ // since migrations are added dynamically.
43
+ //
44
+ // force the database to always emit `upgradeneeded` by passing current time
45
+ const req = indexedDB.open(this._dbName, Date.now());
46
+ req.onerror = () => reject(req.error);
47
+ const postUpgrade = [];
48
+ req.onsuccess = async () => {
49
+ try {
50
+ for (const cb of postUpgrade) {
51
+ await cb(req.result);
52
+ }
53
+ resolve(req.result);
54
+ }
55
+ catch (e) {
56
+ reject(e);
57
+ }
58
+ };
59
+ req.onupgradeneeded = () => {
60
+ // indexed db still fucking sucks. we can't fetch anything from here,
61
+ // since migrations must be sync, and any fetch is inherently async
62
+ // what we do have, however, is the list of object stores.
63
+ // we can abuse them to store the current migrations status as plain strings
64
+ const db = req.result;
65
+ const didUpgrade = new Set();
66
+ const doUpgrade = (repo, fromVersion) => {
67
+ const migrations = this._migrations.get(repo);
68
+ if (!migrations)
69
+ return;
70
+ const targetVer = this._maxVersion.get(repo);
71
+ while (fromVersion < targetVer) {
72
+ const nextVersion = fromVersion + 1;
73
+ const migration = migrations.get(nextVersion);
74
+ if (!migration) {
75
+ throw new Error(`No migration for ${repo} to version ${nextVersion}`);
76
+ }
77
+ const result = migration(db);
78
+ if (result) {
79
+ // guess what? IDB still. fucking. sucks!
80
+ // if we want to do something except creating/removing
81
+ // databases, we should do this outside of migration
82
+ postUpgrade.push(result);
83
+ }
84
+ fromVersion = nextVersion;
85
+ }
86
+ didUpgrade.add(repo);
87
+ db.createObjectStore(`${REPO_VERSION_PREFIX}${repo}:${targetVer}`);
88
+ };
89
+ for (const key of db.objectStoreNames) {
90
+ if (!key.startsWith(REPO_VERSION_PREFIX))
91
+ continue;
92
+ const [, repo, version] = key.split(':');
93
+ const currentVer = Number(version);
94
+ db.deleteObjectStore(key);
95
+ doUpgrade(repo, currentVer);
96
+ didUpgrade.add(repo);
97
+ }
98
+ for (const repo of this._migrations.keys()) {
99
+ if (didUpgrade.has(repo))
100
+ continue;
101
+ doUpgrade(repo, 0);
102
+ }
103
+ };
104
+ });
105
+ }
106
+ async _save() {
107
+ if (this._pendingWritesOses.size === 0)
108
+ return;
109
+ const writes = this._pendingWrites;
110
+ const oses = this._pendingWritesOses;
111
+ this._pendingWrites = [];
112
+ this._pendingWritesOses = new Set();
113
+ const tx = this.db.transaction(oses, 'readwrite');
114
+ const osMap = new Map();
115
+ for (const table of oses) {
116
+ osMap.set(table, tx.objectStore(table));
117
+ }
118
+ for (const [table, obj] of writes) {
119
+ const os = osMap.get(table);
120
+ if (obj === null) {
121
+ os.delete(table);
122
+ }
123
+ else {
124
+ os.put(obj);
125
+ }
126
+ }
127
+ await txToPromise(tx);
128
+ }
129
+ _destroy() {
130
+ this.db.close();
131
+ }
132
+ }
133
+ //# sourceMappingURL=driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/idb/driver.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseStorageDriver, MtUnsupportedError } from '@mtcute/core'\n\nimport { txToPromise } from './utils.js'\n\nexport type PostMigrationFunction = (db: IDBDatabase) => Promise<void>\ntype MigrationFunction = (db: IDBDatabase) => void | PostMigrationFunction\n\nconst REPO_VERSION_PREFIX = '__version:'\n\nexport class IdbStorageDriver extends BaseStorageDriver {\n db!: IDBDatabase\n\n constructor(readonly _dbName: string) {\n super()\n\n if (typeof indexedDB === 'undefined') {\n throw new MtUnsupportedError('IndexedDB is not available')\n }\n }\n\n private _pendingWrites: [string, unknown][] = []\n private _pendingWritesOses = new Set<string>()\n private _migrations: Map<string, Map<number, MigrationFunction>> = new Map()\n private _maxVersion: Map<string, number> = new Map()\n\n registerMigration(repo: string, version: number, migration: MigrationFunction): void {\n if (this.loaded) {\n throw new Error('Cannot register migrations after loading')\n }\n\n let map = this._migrations.get(repo)\n\n if (!map) {\n map = new Map()\n this._migrations.set(repo, map)\n }\n\n if (map.has(version)) {\n throw new Error(`Migration for ${repo} version ${version} is already registered`)\n }\n\n map.set(version, migration)\n\n const prevMax = this._maxVersion.get(repo) ?? 0\n\n if (version > prevMax) {\n this._maxVersion.set(repo, version)\n }\n }\n\n writeLater(os: string, obj: unknown): void {\n this._pendingWrites.push([os, obj])\n this._pendingWritesOses.add(os)\n }\n\n async _load(): Promise<void> {\n this.db = await new Promise((resolve, reject) => {\n // indexed db fucking sucks - we can't create tables once we have loaded\n // and making an ever-incrementing version number is pretty hard\n // since migrations are added dynamically.\n //\n // force the database to always emit `upgradeneeded` by passing current time\n const req = indexedDB.open(this._dbName, Date.now())\n\n req.onerror = () => reject(req.error)\n\n const postUpgrade: PostMigrationFunction[] = []\n\n req.onsuccess = async () => {\n try {\n for (const cb of postUpgrade) {\n await cb(req.result)\n }\n resolve(req.result)\n } catch (e) {\n reject(e)\n }\n }\n req.onupgradeneeded = () => {\n // indexed db still fucking sucks. we can't fetch anything from here,\n // since migrations must be sync, and any fetch is inherently async\n // what we do have, however, is the list of object stores.\n // we can abuse them to store the current migrations status as plain strings\n const db = req.result\n\n const didUpgrade = new Set<string>()\n\n const doUpgrade = (repo: string, fromVersion: number) => {\n const migrations = this._migrations.get(repo)\n if (!migrations) return\n\n const targetVer = this._maxVersion.get(repo)!\n\n while (fromVersion < targetVer) {\n const nextVersion = fromVersion + 1\n const migration = migrations.get(nextVersion)\n\n if (!migration) {\n throw new Error(`No migration for ${repo} to version ${nextVersion}`)\n }\n\n const result = migration(db)\n\n if (result) {\n // guess what? IDB still. fucking. sucks!\n // if we want to do something except creating/removing\n // databases, we should do this outside of migration\n postUpgrade.push(result)\n }\n\n fromVersion = nextVersion\n }\n\n didUpgrade.add(repo)\n db.createObjectStore(`${REPO_VERSION_PREFIX}${repo}:${targetVer}`)\n }\n\n for (const key of db.objectStoreNames) {\n if (!key.startsWith(REPO_VERSION_PREFIX)) continue\n const [, repo, version] = key.split(':')\n\n const currentVer = Number(version)\n db.deleteObjectStore(key)\n doUpgrade(repo, currentVer)\n didUpgrade.add(repo)\n }\n\n for (const repo of this._migrations.keys()) {\n if (didUpgrade.has(repo)) continue\n\n doUpgrade(repo, 0)\n }\n }\n })\n }\n\n async _save() {\n if (this._pendingWritesOses.size === 0) return\n\n const writes = this._pendingWrites\n const oses = this._pendingWritesOses\n this._pendingWrites = []\n this._pendingWritesOses = new Set()\n\n const tx = this.db.transaction(oses, 'readwrite')\n\n const osMap = new Map<string, IDBObjectStore>()\n\n for (const table of oses) {\n osMap.set(table, tx.objectStore(table))\n }\n\n for (const [table, obj] of writes) {\n const os = osMap.get(table)!\n\n if (obj === null) {\n os.delete(table)\n } else {\n os.put(obj)\n }\n }\n\n await txToPromise(tx)\n }\n\n _destroy(): void {\n this.db.close()\n }\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import { IMtStorageProvider } from '@mtcute/core';
2
+ import { IdbStorageDriver } from './driver.js';
3
+ import { IdbAuthKeysRepository } from './repository/auth-keys.js';
4
+ import { IdbKvRepository } from './repository/kv.js';
5
+ import { IdbPeersRepository } from './repository/peers.js';
6
+ import { IdbRefMsgRepository } from './repository/ref-messages.js';
7
+ export { IdbStorageDriver } from './driver.js';
8
+ /**
9
+ * mtcute storage that uses IndexedDB as a backend.
10
+ *
11
+ * This storage is the default one for browsers, and is generally
12
+ * recommended over local storage based one.
13
+ */
14
+ export declare class IdbStorage implements IMtStorageProvider {
15
+ readonly dbName: string;
16
+ constructor(dbName: string);
17
+ readonly driver: IdbStorageDriver;
18
+ readonly kv: IdbKvRepository;
19
+ readonly authKeys: IdbAuthKeysRepository;
20
+ readonly peers: IdbPeersRepository;
21
+ readonly refMessages: IdbRefMsgRepository;
22
+ }
@@ -0,0 +1,23 @@
1
+ import { IdbStorageDriver } from './driver.js';
2
+ import { IdbAuthKeysRepository } from './repository/auth-keys.js';
3
+ import { IdbKvRepository } from './repository/kv.js';
4
+ import { IdbPeersRepository } from './repository/peers.js';
5
+ import { IdbRefMsgRepository } from './repository/ref-messages.js';
6
+ export { IdbStorageDriver } from './driver.js';
7
+ /**
8
+ * mtcute storage that uses IndexedDB as a backend.
9
+ *
10
+ * This storage is the default one for browsers, and is generally
11
+ * recommended over local storage based one.
12
+ */
13
+ export class IdbStorage {
14
+ constructor(dbName) {
15
+ this.dbName = dbName;
16
+ this.driver = new IdbStorageDriver(this.dbName);
17
+ this.kv = new IdbKvRepository(this.driver);
18
+ this.authKeys = new IdbAuthKeysRepository(this.driver);
19
+ this.peers = new IdbPeersRepository(this.driver);
20
+ this.refMessages = new IdbRefMsgRepository(this.driver);
21
+ }
22
+ }
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/idb/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IACnB,YAAqB,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;QAE1B,WAAM,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC1C,OAAE,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACrC,aAAQ,GAAG,IAAI,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACjD,UAAK,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC3C,gBAAW,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IANrB,CAAC;CAO1C","sourcesContent":["import { IMtStorageProvider } from '@mtcute/core'\n\nimport { IdbStorageDriver } from './driver.js'\nimport { IdbAuthKeysRepository } from './repository/auth-keys.js'\nimport { IdbKvRepository } from './repository/kv.js'\nimport { IdbPeersRepository } from './repository/peers.js'\nimport { IdbRefMsgRepository } from './repository/ref-messages.js'\n\nexport { IdbStorageDriver } from './driver.js'\n\n/**\n * mtcute storage that uses IndexedDB as a backend.\n *\n * This storage is the default one for browsers, and is generally\n * recommended over local storage based one.\n */\nexport class IdbStorage implements IMtStorageProvider {\n constructor(readonly dbName: string) {}\n\n readonly driver = new IdbStorageDriver(this.dbName)\n readonly kv = new IdbKvRepository(this.driver)\n readonly authKeys = new IdbAuthKeysRepository(this.driver)\n readonly peers = new IdbPeersRepository(this.driver)\n readonly refMessages = new IdbRefMsgRepository(this.driver)\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import { IAuthKeysRepository } from '@mtcute/core';
2
+ import { IdbStorageDriver } from '../driver.js';
3
+ export declare class IdbAuthKeysRepository implements IAuthKeysRepository {
4
+ readonly _driver: IdbStorageDriver;
5
+ constructor(_driver: IdbStorageDriver);
6
+ private os;
7
+ set(dc: number, key: Uint8Array | null): Promise<void>;
8
+ get(dc: number): Promise<Uint8Array | null>;
9
+ private osTemp;
10
+ setTemp(dc: number, idx: number, key: Uint8Array | null, expires: number): Promise<void>;
11
+ getTemp(dc: number, idx: number, now: number): Promise<Uint8Array | null>;
12
+ deleteByDc(dc: number): Promise<void>;
13
+ deleteAll(): Promise<void>;
14
+ }