@mtcute/core 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/base-client.d.ts +3 -6
- package/cjs/base-client.js +12 -20
- package/cjs/base-client.js.map +1 -1
- package/cjs/network/auth-key.test.d.ts +1 -0
- package/cjs/network/auth-key.test.js +111 -0
- package/cjs/network/auth-key.test.js.map +1 -0
- package/cjs/network/config-manager.js +2 -1
- package/cjs/network/config-manager.js.map +1 -1
- package/cjs/network/config-manager.test.d.ts +1 -0
- package/cjs/network/config-manager.test.js +170 -0
- package/cjs/network/config-manager.test.js.map +1 -0
- package/cjs/network/index.d.ts +1 -1
- package/cjs/network/index.js.map +1 -1
- package/cjs/network/multi-session-connection.js +17 -4
- package/cjs/network/multi-session-connection.js.map +1 -1
- package/cjs/network/network-manager.d.ts +1 -1
- package/cjs/network/network-manager.js +12 -5
- package/cjs/network/network-manager.js.map +1 -1
- package/cjs/network/persistent-connection.test.d.ts +1 -0
- package/cjs/network/persistent-connection.test.js +157 -0
- package/cjs/network/persistent-connection.test.js.map +1 -0
- package/cjs/network/session-connection.js +3 -2
- package/cjs/network/session-connection.js.map +1 -1
- package/cjs/network/transports/intermediate.test.d.ts +1 -0
- package/cjs/network/transports/intermediate.test.js +84 -0
- package/cjs/network/transports/intermediate.test.js.map +1 -0
- package/cjs/network/transports/obfuscated.js +1 -1
- package/cjs/network/transports/obfuscated.js.map +1 -1
- package/cjs/network/transports/obfuscated.test.d.ts +1 -0
- package/cjs/network/transports/obfuscated.test.js +131 -0
- package/cjs/network/transports/obfuscated.test.js.map +1 -0
- package/cjs/network/transports/tcp.js +1 -1
- package/cjs/network/transports/tcp.js.map +1 -1
- package/cjs/network/transports/tcp.test.d.ts +1 -0
- package/cjs/network/transports/tcp.test.js +103 -0
- package/cjs/network/transports/tcp.test.js.map +1 -0
- package/cjs/network/transports/websocket.test.d.ts +1 -0
- package/cjs/network/transports/websocket.test.js +91 -0
- package/cjs/network/transports/websocket.test.js.map +1 -0
- package/cjs/storage/abstract.d.ts +18 -0
- package/cjs/storage/abstract.js.map +1 -1
- package/cjs/storage/idb.d.ts +101 -0
- package/cjs/storage/idb.js +458 -0
- package/cjs/storage/idb.js.map +1 -0
- package/cjs/storage/idb.test.d.ts +1 -0
- package/cjs/storage/idb.test.js +21 -0
- package/cjs/storage/idb.test.js.map +1 -0
- package/cjs/storage/index.d.ts +0 -4
- package/cjs/storage/index.js +0 -4
- package/cjs/storage/index.js.map +1 -1
- package/cjs/storage/json-file.d.ts +12 -0
- package/cjs/storage/json-file.js +12 -0
- package/cjs/storage/json-file.js.map +1 -1
- package/cjs/storage/json.js +3 -2
- package/cjs/storage/json.js.map +1 -1
- package/cjs/storage/json.test.d.ts +1 -0
- package/cjs/storage/json.test.js +36 -0
- package/cjs/storage/json.test.js.map +1 -0
- package/cjs/storage/localstorage.d.ts +12 -0
- package/cjs/storage/localstorage.js +12 -0
- package/cjs/storage/localstorage.js.map +1 -1
- package/cjs/storage/localstorage.test.d.ts +1 -0
- package/cjs/storage/localstorage.test.js +23 -0
- package/cjs/storage/localstorage.test.js.map +1 -0
- package/cjs/storage/memory.d.ts +12 -1
- package/cjs/storage/memory.js +65 -3
- package/cjs/storage/memory.js.map +1 -1
- package/cjs/storage/memory.test.d.ts +1 -0
- package/cjs/storage/memory.test.js +48 -0
- package/cjs/storage/memory.test.js.map +1 -0
- package/cjs/utils/async-lock.test.d.ts +1 -0
- package/cjs/utils/async-lock.test.js +25 -0
- package/cjs/utils/async-lock.test.js.map +1 -0
- package/cjs/utils/bigint-utils.test.d.ts +1 -0
- package/cjs/utils/bigint-utils.test.js +150 -0
- package/cjs/utils/bigint-utils.test.js.map +1 -0
- package/cjs/utils/buffer-utils.test.d.ts +1 -0
- package/cjs/utils/buffer-utils.test.js +69 -0
- package/cjs/utils/buffer-utils.test.js.map +1 -0
- package/cjs/utils/condition-variable.test.d.ts +1 -0
- package/cjs/utils/condition-variable.test.js +27 -0
- package/cjs/utils/condition-variable.test.js.map +1 -0
- package/cjs/utils/controllable-promise.d.ts +0 -5
- package/cjs/utils/controllable-promise.js +1 -7
- package/cjs/utils/controllable-promise.js.map +1 -1
- package/cjs/utils/controllable-promise.test.d.ts +1 -0
- package/cjs/utils/controllable-promise.test.js +17 -0
- package/cjs/utils/controllable-promise.test.js.map +1 -0
- package/cjs/utils/crypto/keys.test.d.ts +1 -0
- package/cjs/utils/crypto/keys.test.js +40 -0
- package/cjs/utils/crypto/keys.test.js.map +1 -0
- package/cjs/utils/crypto/miller-rabin.test.d.ts +1 -0
- package/cjs/utils/crypto/miller-rabin.test.js +60 -0
- package/cjs/utils/crypto/miller-rabin.test.js.map +1 -0
- package/cjs/utils/crypto/mtproto.test.d.ts +1 -0
- package/cjs/utils/crypto/mtproto.test.js +50 -0
- package/cjs/utils/crypto/mtproto.test.js.map +1 -0
- package/cjs/utils/crypto/node.test.d.ts +1 -0
- package/cjs/utils/crypto/node.test.js +14 -0
- package/cjs/utils/crypto/node.test.js.map +1 -0
- package/cjs/utils/crypto/password.test.d.ts +1 -0
- package/cjs/utils/crypto/password.test.js +95 -0
- package/cjs/utils/crypto/password.test.js.map +1 -0
- package/cjs/utils/crypto/utils.test.d.ts +1 -0
- package/cjs/utils/crypto/utils.test.js +49 -0
- package/cjs/utils/crypto/utils.test.js.map +1 -0
- package/cjs/utils/crypto/web.test.d.ts +1 -0
- package/cjs/utils/crypto/web.test.js +17 -0
- package/cjs/utils/crypto/web.test.js.map +1 -0
- package/cjs/utils/deque.test.d.ts +1 -0
- package/cjs/utils/deque.test.js +128 -0
- package/cjs/utils/deque.test.js.map +1 -0
- package/cjs/utils/function-utils.test.d.ts +1 -0
- package/cjs/utils/function-utils.test.js +23 -0
- package/cjs/utils/function-utils.test.js.map +1 -0
- package/cjs/utils/linked-list.test.d.ts +1 -0
- package/cjs/utils/linked-list.test.js +36 -0
- package/cjs/utils/linked-list.test.js.map +1 -0
- package/cjs/utils/links/bots.test.d.ts +1 -0
- package/cjs/utils/links/bots.test.js +152 -0
- package/cjs/utils/links/bots.test.js.map +1 -0
- package/cjs/utils/links/chat.test.d.ts +1 -0
- package/cjs/utils/links/chat.test.js +84 -0
- package/cjs/utils/links/chat.test.js.map +1 -0
- package/cjs/utils/links/misc.test.d.ts +1 -0
- package/cjs/utils/links/misc.test.js +153 -0
- package/cjs/utils/links/misc.test.js.map +1 -0
- package/cjs/utils/links/proxy.test.d.ts +1 -0
- package/cjs/utils/links/proxy.test.js +74 -0
- package/cjs/utils/links/proxy.test.js.map +1 -0
- package/cjs/utils/links/user.test.d.ts +1 -0
- package/cjs/utils/links/user.test.js +63 -0
- package/cjs/utils/links/user.test.js.map +1 -0
- package/cjs/utils/logger.test.d.ts +1 -0
- package/cjs/utils/logger.test.js +127 -0
- package/cjs/utils/logger.test.js.map +1 -0
- package/cjs/utils/long-utils.test.d.ts +1 -0
- package/cjs/utils/long-utils.test.js +158 -0
- package/cjs/utils/long-utils.test.js.map +1 -0
- package/cjs/utils/lru-map.test.d.ts +1 -0
- package/cjs/utils/lru-map.test.js +96 -0
- package/cjs/utils/lru-map.test.js.map +1 -0
- package/cjs/utils/lru-set.test.d.ts +1 -0
- package/cjs/utils/lru-set.test.js +77 -0
- package/cjs/utils/lru-set.test.js.map +1 -0
- package/cjs/utils/peer-utils.js +3 -1
- package/cjs/utils/peer-utils.js.map +1 -1
- package/cjs/utils/peer-utils.test.d.ts +1 -0
- package/cjs/utils/peer-utils.test.js +122 -0
- package/cjs/utils/peer-utils.test.js.map +1 -0
- package/cjs/utils/sorted-array.test.d.ts +1 -0
- package/cjs/utils/sorted-array.test.js +66 -0
- package/cjs/utils/sorted-array.test.js.map +1 -0
- package/cjs/utils/string-session.test.d.ts +1 -0
- package/cjs/utils/string-session.test.js +106 -0
- package/cjs/utils/string-session.test.js.map +1 -0
- package/cjs/utils/tl-json.test.d.ts +1 -0
- package/cjs/utils/tl-json.test.js +83 -0
- package/cjs/utils/tl-json.test.js.map +1 -0
- package/cjs/utils/type-assertions.test.d.ts +1 -0
- package/cjs/utils/type-assertions.test.js +67 -0
- package/cjs/utils/type-assertions.test.js.map +1 -0
- package/esm/base-client.d.ts +3 -6
- package/esm/base-client.js +2 -10
- package/esm/base-client.js.map +1 -1
- package/esm/network/auth-key.test.d.ts +1 -0
- package/esm/network/auth-key.test.js +106 -0
- package/esm/network/auth-key.test.js.map +1 -0
- package/esm/network/config-manager.js +2 -1
- package/esm/network/config-manager.js.map +1 -1
- package/esm/network/config-manager.test.d.ts +1 -0
- package/esm/network/config-manager.test.js +168 -0
- package/esm/network/config-manager.test.js.map +1 -0
- package/esm/network/index.d.ts +1 -1
- package/esm/network/index.js.map +1 -1
- package/esm/network/multi-session-connection.js +17 -4
- package/esm/network/multi-session-connection.js.map +1 -1
- package/esm/network/network-manager.d.ts +1 -1
- package/esm/network/network-manager.js +12 -5
- package/esm/network/network-manager.js.map +1 -1
- package/esm/network/persistent-connection.test.d.ts +1 -0
- package/esm/network/persistent-connection.test.js +155 -0
- package/esm/network/persistent-connection.test.js.map +1 -0
- package/esm/network/session-connection.js +3 -2
- package/esm/network/session-connection.js.map +1 -1
- package/esm/network/transports/intermediate.test.d.ts +1 -0
- package/esm/network/transports/intermediate.test.js +82 -0
- package/esm/network/transports/intermediate.test.js.map +1 -0
- package/esm/network/transports/obfuscated.js +1 -1
- package/esm/network/transports/obfuscated.js.map +1 -1
- package/esm/network/transports/obfuscated.test.d.ts +1 -0
- package/esm/network/transports/obfuscated.test.js +129 -0
- package/esm/network/transports/obfuscated.test.js.map +1 -0
- package/esm/network/transports/tcp.js +1 -1
- package/esm/network/transports/tcp.js.map +1 -1
- package/esm/network/transports/tcp.test.d.ts +1 -0
- package/esm/network/transports/tcp.test.js +101 -0
- package/esm/network/transports/tcp.test.js.map +1 -0
- package/esm/network/transports/websocket.test.d.ts +1 -0
- package/esm/network/transports/websocket.test.js +89 -0
- package/esm/network/transports/websocket.test.js.map +1 -0
- package/esm/storage/abstract.d.ts +18 -0
- package/esm/storage/abstract.js.map +1 -1
- package/esm/storage/idb.d.ts +101 -0
- package/esm/storage/idb.js +454 -0
- package/esm/storage/idb.js.map +1 -0
- package/esm/storage/idb.test.d.ts +1 -0
- package/esm/storage/idb.test.js +19 -0
- package/esm/storage/idb.test.js.map +1 -0
- package/esm/storage/index.d.ts +0 -4
- package/esm/storage/index.js +0 -4
- package/esm/storage/index.js.map +1 -1
- package/esm/storage/json-file.d.ts +12 -0
- package/esm/storage/json-file.js +12 -0
- package/esm/storage/json-file.js.map +1 -1
- package/esm/storage/json.js +3 -2
- package/esm/storage/json.js.map +1 -1
- package/esm/storage/json.test.d.ts +1 -0
- package/esm/storage/json.test.js +34 -0
- package/esm/storage/json.test.js.map +1 -0
- package/esm/storage/localstorage.d.ts +12 -0
- package/esm/storage/localstorage.js +12 -0
- package/esm/storage/localstorage.js.map +1 -1
- package/esm/storage/localstorage.test.d.ts +1 -0
- package/esm/storage/localstorage.test.js +21 -0
- package/esm/storage/localstorage.test.js.map +1 -0
- package/esm/storage/memory.d.ts +12 -1
- package/esm/storage/memory.js +65 -3
- package/esm/storage/memory.js.map +1 -1
- package/esm/storage/memory.test.d.ts +1 -0
- package/esm/storage/memory.test.js +46 -0
- package/esm/storage/memory.test.js.map +1 -0
- package/esm/utils/async-lock.test.d.ts +1 -0
- package/esm/utils/async-lock.test.js +23 -0
- package/esm/utils/async-lock.test.js.map +1 -0
- package/esm/utils/bigint-utils.test.d.ts +1 -0
- package/esm/utils/bigint-utils.test.js +148 -0
- package/esm/utils/bigint-utils.test.js.map +1 -0
- package/esm/utils/buffer-utils.test.d.ts +1 -0
- package/esm/utils/buffer-utils.test.js +67 -0
- package/esm/utils/buffer-utils.test.js.map +1 -0
- package/esm/utils/condition-variable.test.d.ts +1 -0
- package/esm/utils/condition-variable.test.js +25 -0
- package/esm/utils/condition-variable.test.js.map +1 -0
- package/esm/utils/controllable-promise.d.ts +0 -5
- package/esm/utils/controllable-promise.js +0 -5
- package/esm/utils/controllable-promise.js.map +1 -1
- package/esm/utils/controllable-promise.test.d.ts +1 -0
- package/esm/utils/controllable-promise.test.js +15 -0
- package/esm/utils/controllable-promise.test.js.map +1 -0
- package/esm/utils/crypto/keys.test.d.ts +1 -0
- package/esm/utils/crypto/keys.test.js +38 -0
- package/esm/utils/crypto/keys.test.js.map +1 -0
- package/esm/utils/crypto/miller-rabin.test.d.ts +1 -0
- package/esm/utils/crypto/miller-rabin.test.js +58 -0
- package/esm/utils/crypto/miller-rabin.test.js.map +1 -0
- package/esm/utils/crypto/mtproto.test.d.ts +1 -0
- package/esm/utils/crypto/mtproto.test.js +48 -0
- package/esm/utils/crypto/mtproto.test.js.map +1 -0
- package/esm/utils/crypto/node.test.d.ts +1 -0
- package/esm/utils/crypto/node.test.js +12 -0
- package/esm/utils/crypto/node.test.js.map +1 -0
- package/esm/utils/crypto/password.test.d.ts +1 -0
- package/esm/utils/crypto/password.test.js +90 -0
- package/esm/utils/crypto/password.test.js.map +1 -0
- package/esm/utils/crypto/utils.test.d.ts +1 -0
- package/esm/utils/crypto/utils.test.js +47 -0
- package/esm/utils/crypto/utils.test.js.map +1 -0
- package/esm/utils/crypto/web.test.d.ts +1 -0
- package/esm/utils/crypto/web.test.js +15 -0
- package/esm/utils/crypto/web.test.js.map +1 -0
- package/esm/utils/deque.test.d.ts +1 -0
- package/esm/utils/deque.test.js +126 -0
- package/esm/utils/deque.test.js.map +1 -0
- package/esm/utils/function-utils.test.d.ts +1 -0
- package/esm/utils/function-utils.test.js +21 -0
- package/esm/utils/function-utils.test.js.map +1 -0
- package/esm/utils/linked-list.test.d.ts +1 -0
- package/esm/utils/linked-list.test.js +34 -0
- package/esm/utils/linked-list.test.js.map +1 -0
- package/esm/utils/links/bots.test.d.ts +1 -0
- package/esm/utils/links/bots.test.js +150 -0
- package/esm/utils/links/bots.test.js.map +1 -0
- package/esm/utils/links/chat.test.d.ts +1 -0
- package/esm/utils/links/chat.test.js +82 -0
- package/esm/utils/links/chat.test.js.map +1 -0
- package/esm/utils/links/misc.test.d.ts +1 -0
- package/esm/utils/links/misc.test.js +151 -0
- package/esm/utils/links/misc.test.js.map +1 -0
- package/esm/utils/links/proxy.test.d.ts +1 -0
- package/esm/utils/links/proxy.test.js +72 -0
- package/esm/utils/links/proxy.test.js.map +1 -0
- package/esm/utils/links/user.test.d.ts +1 -0
- package/esm/utils/links/user.test.js +61 -0
- package/esm/utils/links/user.test.js.map +1 -0
- package/esm/utils/logger.test.d.ts +1 -0
- package/esm/utils/logger.test.js +122 -0
- package/esm/utils/logger.test.js.map +1 -0
- package/esm/utils/long-utils.test.d.ts +1 -0
- package/esm/utils/long-utils.test.js +153 -0
- package/esm/utils/long-utils.test.js.map +1 -0
- package/esm/utils/lru-map.test.d.ts +1 -0
- package/esm/utils/lru-map.test.js +94 -0
- package/esm/utils/lru-map.test.js.map +1 -0
- package/esm/utils/lru-set.test.d.ts +1 -0
- package/esm/utils/lru-set.test.js +72 -0
- package/esm/utils/lru-set.test.js.map +1 -0
- package/esm/utils/peer-utils.js +3 -1
- package/esm/utils/peer-utils.js.map +1 -1
- package/esm/utils/peer-utils.test.d.ts +1 -0
- package/esm/utils/peer-utils.test.js +117 -0
- package/esm/utils/peer-utils.test.js.map +1 -0
- package/esm/utils/sorted-array.test.d.ts +1 -0
- package/esm/utils/sorted-array.test.js +64 -0
- package/esm/utils/sorted-array.test.js.map +1 -0
- package/esm/utils/string-session.test.d.ts +1 -0
- package/esm/utils/string-session.test.js +104 -0
- package/esm/utils/string-session.test.js.map +1 -0
- package/esm/utils/tl-json.test.d.ts +1 -0
- package/esm/utils/tl-json.test.js +81 -0
- package/esm/utils/tl-json.test.js.map +1 -0
- package/esm/utils/type-assertions.test.d.ts +1 -0
- package/esm/utils/type-assertions.test.js +65 -0
- package/esm/utils/type-assertions.test.js.map +1 -0
- package/package.json +20 -16
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idb.js","sourceRoot":"","sources":["../../../src/storage/idb.ts"],"names":[],"mappings":";;;AAEA,mDAA6F;AAG7F,0DAA6E;AAC7E,oDAA4C;AAC5C,0DAA4D;AAG5D,MAAM,eAAe,GAAG,CAAC,CAAA;AAEzB,MAAM,MAAM,GAAG;IACX,EAAE,EAAE,IAAI;IACR,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,WAAW;IACrB,YAAY,EAAE,gBAAgB;IAC9B,GAAG,EAAE,KAAK;IACV,QAAQ,EAAE,UAAU;IACpB,WAAW,EAAE,cAAc;CACrB,CAAA;AACV,MAAM,YAAY,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;AA8BtC,SAAS,WAAW,CAAC,EAAkB;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,EAAE,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;QAC/B,EAAE,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;AACN,CAAC;AAED,SAAS,YAAY,CAAI,GAAkB;IACvC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACzC,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;AACN,CAAC;AAED,SAAS,YAAY,CAAC,GAA0C;IAC5D,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,CAAA;IAEjB,QAAQ,GAAG,CAAC,IAAI,EAAE;QACd,KAAK,MAAM;YACP,OAAO;gBACH,CAAC,EAAE,eAAe;gBAClB,MAAM,EAAE,EAAE;gBACV,UAAU,EAAE,YAAY,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAA,kCAAkB,EAAC,GAAG,CAAC,IAAI,CAAC;aAClF,CAAA;QACL,KAAK,MAAM;YACP,OAAO;gBACH,CAAC,EAAE,eAAe;gBAClB,MAAM,EAAE,CAAC,EAAE;aACd,CAAA;QACL,KAAK,SAAS;YACV,OAAO;gBACH,CAAC,EAAE,kBAAkB;gBACrB,SAAS,EAAE,IAAA,mCAAmB,EAAC,EAAE,CAAC;gBAClC,UAAU,EAAE,YAAY,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAA,kCAAkB,EAAC,GAAG,CAAC,IAAI,CAAC;aAClF,CAAA;KACR;IAED,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;AACrD,CAAC;AAOD;;;;;GAKG;AACH,MAAa,UAAU;IAMnB,YACa,OAAe,EACxB,MAoCC;QArCQ,YAAO,GAAP,OAAO,CAAQ;QAuFpB,mBAAc,GAAwB,EAAE,CAAA;QACxC,uBAAkB,GAAG,IAAI,GAAG,EAAU,CAAA;QAjD1C,IAAI,MAAM,EAAE,SAAS,KAAK,CAAC,EAAE;YACzB,IAAI,CAAC,MAAM,GAAG,IAAI,mBAAM,CAAC,MAAM,EAAE,SAAS,IAAI,GAAG,CAAC,CAAA;SACrD;QAED,IAAI,CAAC,eAAe,GAAG,MAAM,EAAE,cAAc,IAAI,MAAO,CAAA;IAC5D,CAAC;IAIO,UAAU,CAAC,EAAe,EAAE,MAAc,EAAE,MAAc;QAC9D,OAAO,MAAM,GAAG,MAAM,EAAE;YACpB,QAAQ,MAAM,EAAE;gBACZ,KAAK,CAAC,CAAC,CAAC;oBACJ,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;oBACnD,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;oBACxD,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAA;oBACrE,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAA;oBAE1D,MAAM,OAAO,GAAG,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;oBACtE,OAAO,CAAC,WAAW,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;oBAE5C,MAAM,UAAU,GAAG,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;oBAC3E,UAAU,CAAC,WAAW,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA;oBACjD,UAAU,CAAC,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;oBAE3C,MAAM,SAAS,GAAG,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAA;oBACjF,SAAS,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;oBAEpD,MAAM,EAAE,CAAA;iBACX;aACJ;SACJ;QAED,IAAI,MAAM,KAAK,eAAe;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,EAAE,CAAC,CAAA;IACpF,CAAC;IAOD,KAAK,CAAC,GAAW,EAAE,SAAsB,EAAE,SAAsB;QAC7D,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC5B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,2BAAc,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IAC9D,CAAC;IAKO,WAAW,CAAC,KAAa,EAAE,GAAY;QAC3C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;QACtC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IACtC,CAAC;IAEO,aAAa,CAAC,IAAgB;QAClC,IAAI,CAAC,OAAO,GAAG,IAAI,2BAAc,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QACvD,IAAI,GAAG,CAAA;QAEP,IAAI;YACA,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAA;SAC9B;QAAC,OAAO,CAAC,EAAE;YACR,2EAA2E;YAC3E,GAAG,GAAG,IAAI,CAAA;SACb;QAED,OAAO,GAAuC,CAAA;IAClD,CAAC;IAED,KAAK,CAAC,IAAI;QACN,IAAI,CAAC,EAAE,GAAG,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC5C,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAA;YAEzD,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACrC,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACzC,GAAG,CAAC,eAAe,GAAG,CAAC,KAAK,EAAE,EAAE,CAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,eAAe,CAAC,CAAA;QAC1F,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;YACnC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;gBACvB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAA;YACrD,CAAC,CAAC,CAAA;QACN,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI;QACN,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,KAAK,CAAC;YAAE,OAAM;QAE9C,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAA;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAA;QACpC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAA;QACxB,IAAI,CAAC,kBAAkB,GAAG,IAAI,GAAG,EAAE,CAAA;QAEnC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;QAEjD,MAAM,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAA;QAE/C,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE;YACtB,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAA;SAC1C;QAED,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,MAAM,EAAE;YAC/B,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAE,CAAA;YAE5B,IAAI,GAAG,KAAK,IAAI,EAAE;gBACd,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;aACnB;iBAAM;gBACH,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;aACd;SACJ;QAED,MAAM,WAAW,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC;IAEO,KAAK,CAAC,OAAO;QACjB,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;QACzD,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAEvC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;QAEtG,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;YACpB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;SACjB;QAED,OAAO,WAAW,CAAC,EAAE,CAAC,CAAA;IAC1B,CAAC;IAED,OAAO;QACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAA;QACf,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;IACtC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,YAAkC;QAC1C,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAA;QACpB,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAA;QAElE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YACvC,IAAI,KAAK,KAAK,MAAM,CAAC,QAAQ,IAAI,CAAC,YAAY;gBAAE,SAAQ;YACxD,IAAI,KAAK,KAAK,MAAM,CAAC,YAAY,IAAI,CAAC,YAAY;gBAAE,SAAQ;YAE5D,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAA;SAChC;QAED,OAAO,WAAW,CAAC,EAAE,CAAC,CAAA;IAC1B,CAAC;IAEO,KAAK,CAAC,UAAU,CAAI,GAAW;QACnC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QACzC,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAEvC,MAAM,GAAG,GAAG,MAAM,YAAY,CAAoB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAEjE,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAElC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAM,CAAA;IACrC,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAI,GAAW,EAAE,KAAQ,EAAE,GAAG,GAAG,KAAK;QACxD,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAA;QAEjD,IAAI,CAAC,GAAG,EAAE;YACN,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;YAEhC,OAAM;SACT;QAED,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,CAAC,CAAA;QACtD,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAEvC,MAAM,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IACtC,CAAC;IAED,aAAa,CAAC,GAAsC;QAChD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC1C,CAAC;IAED,aAAa;QACT,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IACjC,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,SAA8B;QAC5D,IAAI,GAAe,CAAA;QAEnB,IAAI,SAAS,KAAK,SAAS,EAAE;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;YACpF,GAAG,GAAG,MAAM,YAAY,CAAa,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;YAC/D,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,SAAU,GAAG,IAAI,CAAC,GAAG,EAAE;gBAAE,OAAO,IAAI,CAAA;SACpE;aAAM;YACH,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YAC5E,GAAG,GAAG,MAAM,YAAY,CAAa,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;YAClD,IAAI,GAAG,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAA;SACrC;QAED,OAAO,GAAG,CAAC,GAAG,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,GAAsB;QACpD,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAEzF,IAAI,GAAG,KAAK,IAAI,EAAE;YACd,OAAO,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;SACvC;QAED,MAAM,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;IACjD,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,IAAY,EAAE,KAAa,EAAE,GAAsB,EAAE,SAAiB;QAC1F,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;QAEjG,IAAI,GAAG,KAAK,IAAI,EAAE;YACd,OAAO,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;SAChD;QAED,MAAM,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;IACxE,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,IAAY;QAC9B,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,CAAA;QAEnF,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAE5C,kBAAkB;QAClB,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;QAClD,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;QAEpD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;YACpB,IAAK,GAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;gBACvC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;aACrB;SACJ;IACL,CAAC;IAGD,KAAK,CAAC,OAAO;QACT,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,WAAW,CAAA;QAE3D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAA4B,MAAM,CAAC,CAAA;QACrE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QAEvB,OAAO,IAAI,CAAA;IACf,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAsC;QAChD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QAEvB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IAC5C,CAAC;IAED,KAAK,CAAC,eAAe;QACjB,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAEhE,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC5C,YAAY,CAAoB,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC9C,YAAY,CAAoB,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC9C,YAAY,CAAoB,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC/C,YAAY,CAAoB,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SACjD,CAAC,CAAA;QAEF,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAElG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;IACxF,CAAC;IAED,aAAa,CAAC,GAAW;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACpC,CAAC;IAED,aAAa,CAAC,GAAW;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACpC,CAAC;IAED,cAAc,CAAC,GAAW;QACtB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACrC,CAAC;IAED,aAAa,CAAC,GAAW;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,QAAgB;QAChC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAClE,MAAM,GAAG,GAAG,MAAM,YAAY,CAAkB,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;QAEjE,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAElC,OAAO,GAAG,CAAC,GAAG,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,MAA2B;QAC/C,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;QACvD,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAErC,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,MAAM,EAAE;YAC5B,EAAE,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;SACjC;QAED,OAAO,WAAW,CAAC,EAAE,CAAC,CAAA;IAC1B,CAAC;IAED,WAAW,CAAC,KAAkC;QAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACtB,MAAM,GAAG,GAAc;gBACnB,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAA,gCAAgB,EAAC,IAAI,CAAC,UAAU,CAAC;gBACvC,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;gBACnB,IAAI,EAAE,2BAAc,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC;aAClE,CAAA;YAED,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;YAEtC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,EAAE;gBAC1B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;aAC7C;YAED,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE;gBACtB,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC;gBACxB,IAAI,EAAE,IAAI,CAAC,IAAI;aAClB,CAAC,CAAA;SACL;IACL,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,EAAkB,EAAE,MAAc;QACjE,MAAM,GAAG,GAAG,MAAM,YAAY,CAAgB,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;QAC7D,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAElC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QACtD,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QAE9B,IAAI,MAAM,GAAG,CAAC,EAAE;YACZ,OAAO;gBACH,CAAC,EAAE,0BAA0B;gBAC7B,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI;gBACV,KAAK,EAAE,GAAG,CAAC,KAAK;aACnB,CAAA;SACJ;QAED,OAAO;YACH,CAAC,EAAE,6BAA6B;YAChC,SAAS,EAAE,IAAA,mCAAmB,EAAC,MAAM,CAAC;YACtC,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,GAAG,CAAC,KAAK;SACnB,CAAA;IACL,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,SAAS,GAAG,IAAI;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QACvC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC,IAAI,CAAA;QAE9B,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAA;QACrE,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAE7C,MAAM,GAAG,GAAG,MAAM,YAAY,CAAY,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;QAE5D,IAAI,GAAG,EAAE;YACL,OAAO,YAAY,CAAC,GAAG,CAAC,CAAA;SAC3B;QAED,IAAI,SAAS,EAAE;YACX,OAAO,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,CAAA;SAC/E;QAED,OAAO,IAAI,CAAA;IACf,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,QAAgB;QACpC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC/C,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAE1C,MAAM,GAAG,GAAG,MAAM,YAAY,CAAY,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;QAEhF,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAElC,OAAO,YAAY,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,KAAa;QAC9B,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC/C,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAE1C,MAAM,GAAG,GAAG,MAAM,YAAY,CAAY,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;QAE1E,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAElC,OAAO,YAAY,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,MAAc;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QACvC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC,IAAI,CAAA;QAE9B,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC/C,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAE1C,MAAM,GAAG,GAAG,MAAM,YAAY,CAAY,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;QAEzD,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAElC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACvC,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,MAAc,EAAE,MAAc,EAAE,SAAiB;QACxE,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;QAE/F,MAAM,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAA0B,CAAC,CAAC,CAAA;IAC5F,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,MAAc,EAAE,UAAoB;QAC9D,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;QAC/D,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;QAC7C,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAEhC,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE;YAC5B,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;YAC7D,IAAI,GAAG,KAAK,SAAS;gBAAE,SAAQ;YAE/B,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;SACjB;QAED,OAAO,WAAW,CAAC,EAAE,CAAC,CAAA;IAC1B,CAAC;IAED,+BAA+B;IAE/B,KAAK,CAAC,QAAQ,CAAC,GAAW;QACtB,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;QACzD,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAEvC,MAAM,GAAG,GAAG,MAAM,YAAY,CAAa,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QACvD,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAErB,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE;YACzC,MAAM,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;YAElC,OAAO,IAAI,CAAA;SACd;QAED,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAY,CAAA;IAC3C,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAW,EAAE,KAAc,EAAE,GAAY;QACpD,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;QACzD,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAEvC,MAAM,GAAG,GAAe;YACpB,GAAG;YACH,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;YAC5B,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS;SACrD,CAAA;QAED,MAAM,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IACnC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,GAAW;QACzB,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;QACzD,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAEvC,MAAM,YAAY,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IACtC,CAAC;IAED,eAAe,CAAC,GAAW;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,kBAAkB,GAAG,EAAE,CAA2B,CAAA;IAC3E,CAAC;IAED,eAAe,CAAC,GAAW,EAAE,KAAa,EAAE,GAAY;QACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,kBAAkB,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;IAC7D,CAAC;IAED,kBAAkB,CAAC,GAAW;QAC1B,OAAO,IAAI,CAAC,WAAW,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAA;IACpD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW,EAAE,KAAa,EAAE,MAAc;QACzD,eAAe;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAEtB,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;QACzD,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAEvC,MAAM,GAAG,GAAG,MAAM,YAAY,CAAa,EAAE,CAAC,GAAG,CAAC,eAAe,GAAG,EAAE,CAAC,CAAC,CAAA;QAExE,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,OAAQ,GAAG,GAAG,EAAE;YAC5B,4BAA4B;YAC5B,MAAM,GAAG,GAAe;gBACpB,GAAG,EAAE,eAAe,GAAG,EAAE;gBACzB,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE;gBACvB,OAAO,EAAE,GAAG,GAAG,MAAM,GAAG,IAAI;aAC/B,CAAA;YACD,MAAM,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;YAE/B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,OAAQ,CAAC,CAAA;SAC/B;QAED,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAE7B,IAAI,KAAK,GAAG,CAAC,EAAE;YACX,KAAK,IAAI,CAAC,CAAA;YACV,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAA;YAC5B,MAAM,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;SAClC;QAED,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,OAAQ,CAAC,CAAA;IAChC,CAAC;IAED,cAAc,CAAC,GAAW;QACtB,OAAO,IAAI,CAAC,WAAW,CAAC,eAAe,GAAG,EAAE,CAAC,CAAA;IACjD,CAAC;CACJ;AA9iBD,gCA8iBC","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-argument */\nimport { tl } from '@mtcute/tl'\nimport { TlBinaryReader, TlBinaryWriter, TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime'\n\nimport { Logger } from '../utils/logger.js'\nimport { longFromFastString, longToFastString } from '../utils/long-utils.js'\nimport { LruMap } from '../utils/lru-map.js'\nimport { toggleChannelIdMark } from '../utils/peer-utils.js'\nimport { ITelegramStorage } from './abstract.js'\n\nconst CURRENT_VERSION = 1\n\nconst TABLES = {\n kv: 'kv',\n state: 'state',\n authKeys: 'auth_keys',\n tempAuthKeys: 'temp_auth_keys',\n pts: 'pts',\n entities: 'entities',\n messageRefs: 'message_refs',\n} as const\nconst EMPTY_BUFFER = new Uint8Array(0)\n\ninterface AuthKeyDto {\n dc: number\n key: Uint8Array\n expiresAt?: number\n}\n\ninterface EntityDto {\n id: number\n hash: string\n type: string\n username?: string\n phone?: string\n updated: number\n full: Uint8Array\n}\n\ninterface MessageRefDto {\n peerId: number\n chatId: number\n msgId: number\n}\n\ninterface FsmItemDto {\n key: string\n value: string\n expires?: number\n}\n\nfunction txToPromise(tx: IDBTransaction): Promise<void> {\n return new Promise((resolve, reject) => {\n tx.oncomplete = () => resolve()\n tx.onerror = () => reject(tx.error)\n })\n}\n\nfunction reqToPromise<T>(req: IDBRequest<T>): Promise<T> {\n return new Promise((resolve, reject) => {\n req.onsuccess = () => resolve(req.result)\n req.onerror = () => reject(req.error)\n })\n}\n\nfunction getInputPeer(row: EntityDto | ITelegramStorage.PeerInfo): tl.TypeInputPeer {\n const id = row.id\n\n switch (row.type) {\n case 'user':\n return {\n _: 'inputPeerUser',\n userId: id,\n accessHash: 'accessHash' in row ? row.accessHash : longFromFastString(row.hash),\n }\n case 'chat':\n return {\n _: 'inputPeerChat',\n chatId: -id,\n }\n case 'channel':\n return {\n _: 'inputPeerChannel',\n channelId: toggleChannelIdMark(id),\n accessHash: 'accessHash' in row ? row.accessHash : longFromFastString(row.hash),\n }\n }\n\n throw new Error(`Invalid peer type: ${row.type}`)\n}\n\ninterface CachedEntity {\n peer: tl.TypeInputPeer\n full: tl.TypeUser | tl.TypeChat | null\n}\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 ITelegramStorage {\n private _cache?: LruMap<number, CachedEntity>\n\n private _vacuumTimeout?: NodeJS.Timeout\n private _vacuumInterval: number\n\n constructor(\n readonly _dbName: string,\n params?: {\n /**\n * Entities cache size, in number of entities.\n *\n * Recently encountered entities are cached in memory,\n * to avoid redundant database calls. Set to 0 to\n * disable caching (not recommended)\n *\n * Note that by design in-memory cached is only\n * used when finding peer by ID, since other\n * kinds of lookups (phone, username) may get stale quickly\n *\n * @default `100`\n */\n cacheSize?: number\n\n /**\n * Updates to already cached in-memory entities are only\n * applied in DB once in a while, to avoid redundant\n * DB calls.\n *\n * If you are having issues with this, you can set this to `0`\n *\n * @default `30000` (30 sec)\n */\n unimportantSavesDelay?: number\n\n /**\n * Interval in milliseconds for vacuuming the storage.\n *\n * When vacuuming, the storage will remove expired FSM\n * states to reduce disk and memory usage.\n *\n * @default `300_000` (5 minutes)\n */\n vacuumInterval?: number\n },\n ) {\n if (params?.cacheSize !== 0) {\n this._cache = new LruMap(params?.cacheSize ?? 100)\n }\n\n this._vacuumInterval = params?.vacuumInterval ?? 300_000\n }\n\n db!: IDBDatabase\n\n private _upgradeDb(db: IDBDatabase, oldVer: number, newVer: number): void {\n while (oldVer < newVer) {\n switch (oldVer) {\n case 0: {\n db.createObjectStore(TABLES.kv, { keyPath: 'key' })\n db.createObjectStore(TABLES.authKeys, { keyPath: 'dc' })\n db.createObjectStore(TABLES.tempAuthKeys, { keyPath: ['dc', 'idx'] })\n db.createObjectStore(TABLES.pts, { keyPath: 'channelId' })\n\n const stateOs = db.createObjectStore(TABLES.state, { keyPath: 'key' })\n stateOs.createIndex('by_expires', 'expires')\n\n const entitiesOs = db.createObjectStore(TABLES.entities, { keyPath: 'id' })\n entitiesOs.createIndex('by_username', 'username')\n entitiesOs.createIndex('by_phone', 'phone')\n\n const msgRefsOs = db.createObjectStore(TABLES.messageRefs, { keyPath: 'peerId' })\n msgRefsOs.createIndex('by_msg', ['chatId', 'msgId'])\n\n oldVer++\n }\n }\n }\n\n if (newVer !== CURRENT_VERSION) throw new Error(`Invalid db version: ${newVer}`)\n }\n\n private log!: Logger\n private readerMap!: TlReaderMap\n private writerMap!: TlWriterMap\n private _reader!: TlBinaryReader\n\n setup(log: Logger, readerMap: TlReaderMap, writerMap: TlWriterMap): void {\n this.log = log.create('idb')\n this.readerMap = readerMap\n this.writerMap = writerMap\n this._reader = new TlBinaryReader(readerMap, EMPTY_BUFFER)\n }\n\n private _pendingWrites: [string, unknown][] = []\n private _pendingWritesOses = new Set<string>()\n\n private _writeLater(table: string, obj: unknown): void {\n this._pendingWrites.push([table, obj])\n this._pendingWritesOses.add(table)\n }\n\n private _readFullPeer(data: Uint8Array): tl.TypeUser | tl.TypeChat | null {\n this._reader = new TlBinaryReader(this.readerMap, data)\n let obj\n\n try {\n obj = this._reader.object()\n } catch (e) {\n // object might be from an older tl layer, in which case it will be ignored\n obj = null\n }\n\n return obj as tl.TypeUser | tl.TypeChat | null\n }\n\n async load(): Promise<void> {\n this.db = await new Promise((resolve, reject) => {\n const req = indexedDB.open(this._dbName, CURRENT_VERSION)\n\n req.onerror = () => reject(req.error)\n req.onsuccess = () => resolve(req.result)\n req.onupgradeneeded = (event) =>\n this._upgradeDb(req.result, event.oldVersion, event.newVersion || CURRENT_VERSION)\n })\n\n this._vacuumTimeout = setInterval(() => {\n this._vacuum().catch((e) => {\n this.log.warn('Failed to vacuum database: %s', e)\n })\n }, this._vacuumInterval)\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 private async _vacuum(): Promise<void> {\n const tx = this.db.transaction(TABLES.state, 'readwrite')\n const os = tx.objectStore(TABLES.state)\n\n const keys = await reqToPromise(os.index('by_expires').getAllKeys(IDBKeyRange.upperBound(Date.now())))\n\n for (const key of keys) {\n os.delete(key)\n }\n\n return txToPromise(tx)\n }\n\n destroy(): void {\n this.db.close()\n clearInterval(this._vacuumTimeout)\n }\n\n async reset(withAuthKeys?: boolean | undefined): Promise<void> {\n this._cache?.clear()\n const tx = this.db.transaction(Object.values(TABLES), 'readwrite')\n\n for (const table of Object.values(TABLES)) {\n if (table === TABLES.authKeys && !withAuthKeys) continue\n if (table === TABLES.tempAuthKeys && !withAuthKeys) continue\n\n tx.objectStore(table).clear()\n }\n\n return txToPromise(tx)\n }\n\n private async _getFromKv<T>(key: string): Promise<T | null> {\n const tx = this.db.transaction(TABLES.kv)\n const store = tx.objectStore(TABLES.kv)\n\n const res = await reqToPromise<{ value: string }>(store.get(key))\n\n if (res === undefined) return null\n\n return JSON.parse(res.value) as T\n }\n\n private async _setToKv<T>(key: string, value: T, now = false): Promise<void> {\n const dto = { key, value: JSON.stringify(value) }\n\n if (!now) {\n this._writeLater(TABLES.kv, dto)\n\n return\n }\n\n const tx = this.db.transaction(TABLES.kv, 'readwrite')\n const store = tx.objectStore(TABLES.kv)\n\n await reqToPromise(store.put(dto))\n }\n\n setDefaultDcs(dcs: ITelegramStorage.DcOptions | null): Promise<void> {\n return this._setToKv('dcs', dcs, true)\n }\n\n getDefaultDcs(): Promise<ITelegramStorage.DcOptions | null> {\n return this._getFromKv('dcs')\n }\n\n async getAuthKeyFor(dcId: number, tempIndex?: number | undefined): Promise<Uint8Array | null> {\n let row: AuthKeyDto\n\n if (tempIndex !== undefined) {\n const os = this.db.transaction(TABLES.tempAuthKeys).objectStore(TABLES.tempAuthKeys)\n row = await reqToPromise<AuthKeyDto>(os.get([dcId, tempIndex]))\n if (row === undefined || row.expiresAt! < Date.now()) return null\n } else {\n const os = this.db.transaction(TABLES.authKeys).objectStore(TABLES.authKeys)\n row = await reqToPromise<AuthKeyDto>(os.get(dcId))\n if (row === undefined) return null\n }\n\n return row.key\n }\n\n async setAuthKeyFor(dcId: number, key: Uint8Array | null): Promise<void> {\n const os = this.db.transaction(TABLES.authKeys, 'readwrite').objectStore(TABLES.authKeys)\n\n if (key === null) {\n return reqToPromise(os.delete(dcId))\n }\n\n await reqToPromise(os.put({ dc: dcId, key }))\n }\n\n async setTempAuthKeyFor(dcId: number, index: number, key: Uint8Array | null, expiresAt: number): Promise<void> {\n const os = this.db.transaction(TABLES.tempAuthKeys, 'readwrite').objectStore(TABLES.tempAuthKeys)\n\n if (key === null) {\n return reqToPromise(os.delete([dcId, index]))\n }\n\n await reqToPromise(os.put({ dc: dcId, idx: index, key, expiresAt }))\n }\n\n async dropAuthKeysFor(dcId: number): Promise<void> {\n const tx = this.db.transaction([TABLES.authKeys, TABLES.tempAuthKeys], 'readwrite')\n\n tx.objectStore(TABLES.authKeys).delete(dcId)\n\n // IndexedDB sucks\n const tempOs = tx.objectStore(TABLES.tempAuthKeys)\n const keys = await reqToPromise(tempOs.getAllKeys())\n\n for (const key of keys) {\n if ((key as [number, number])[0] === dcId) {\n tempOs.delete(key)\n }\n }\n }\n\n private _cachedSelf?: ITelegramStorage.SelfInfo | null\n async getSelf(): Promise<ITelegramStorage.SelfInfo | null> {\n if (this._cachedSelf !== undefined) return this._cachedSelf\n\n const self = await this._getFromKv<ITelegramStorage.SelfInfo>('self')\n this._cachedSelf = self\n\n return self\n }\n\n async setSelf(self: ITelegramStorage.SelfInfo | null): Promise<void> {\n this._cachedSelf = self\n\n return this._setToKv('self', self, true)\n }\n\n async getUpdatesState(): Promise<[number, number, number, number] | null> {\n const os = this.db.transaction(TABLES.kv).objectStore(TABLES.kv)\n\n const [pts, qts, date, seq] = await Promise.all([\n reqToPromise<{ value: number }>(os.get('pts')),\n reqToPromise<{ value: number }>(os.get('qts')),\n reqToPromise<{ value: number }>(os.get('date')),\n reqToPromise<{ value: number }>(os.get('seq')),\n ])\n\n if (pts === undefined || qts === undefined || date === undefined || seq === undefined) return null\n\n return [Number(pts.value), Number(qts.value), Number(date.value), Number(seq.value)]\n }\n\n setUpdatesPts(val: number): Promise<void> {\n return this._setToKv('pts', val)\n }\n\n setUpdatesQts(val: number): Promise<void> {\n return this._setToKv('qts', val)\n }\n\n setUpdatesDate(val: number): Promise<void> {\n return this._setToKv('date', val)\n }\n\n setUpdatesSeq(val: number): Promise<void> {\n return this._setToKv('seq', val)\n }\n\n async getChannelPts(entityId: number): Promise<number | null> {\n const os = this.db.transaction(TABLES.pts).objectStore(TABLES.pts)\n const row = await reqToPromise<{ pts: number }>(os.get(entityId))\n\n if (row === undefined) return null\n\n return row.pts\n }\n\n async setManyChannelPts(values: Map<number, number>): Promise<void> {\n const tx = this.db.transaction(TABLES.pts, 'readwrite')\n const os = tx.objectStore(TABLES.pts)\n\n for (const [id, pts] of values) {\n os.put({ channelId: id, pts })\n }\n\n return txToPromise(tx)\n }\n\n updatePeers(peers: ITelegramStorage.PeerInfo[]): void {\n for (const peer of peers) {\n const dto: EntityDto = {\n id: peer.id,\n hash: longToFastString(peer.accessHash),\n type: peer.type,\n username: peer.username,\n phone: peer.phone,\n updated: Date.now(),\n full: TlBinaryWriter.serializeObject(this.writerMap, peer.full),\n }\n\n this._writeLater(TABLES.entities, dto)\n\n if (!this._cachedSelf?.isBot) {\n this._writeLater(TABLES.messageRefs, null)\n }\n\n this._cache?.set(peer.id, {\n peer: getInputPeer(peer),\n full: peer.full,\n })\n }\n }\n\n private async _findPeerByReference(os: IDBObjectStore, peerId: number): Promise<tl.TypeInputPeer | null> {\n const row = await reqToPromise<MessageRefDto>(os.get(peerId))\n if (row === undefined) return null\n\n const chat = await this.getPeerById(row.chatId, false)\n if (chat === null) return null\n\n if (peerId > 0) {\n return {\n _: 'inputPeerUserFromMessage',\n userId: peerId,\n peer: chat,\n msgId: row.msgId,\n }\n }\n\n return {\n _: 'inputPeerChannelFromMessage',\n channelId: toggleChannelIdMark(peerId),\n peer: chat,\n msgId: row.msgId,\n }\n }\n\n async getPeerById(peerId: number, allowRefs = true): Promise<tl.TypeInputPeer | null> {\n const cached = this._cache?.get(peerId)\n if (cached) return cached.peer\n\n const tx = this.db.transaction([TABLES.entities, TABLES.messageRefs])\n const entOs = tx.objectStore(TABLES.entities)\n\n const row = await reqToPromise<EntityDto>(entOs.get(peerId))\n\n if (row) {\n return getInputPeer(row)\n }\n\n if (allowRefs) {\n return this._findPeerByReference(tx.objectStore(TABLES.messageRefs), peerId)\n }\n\n return null\n }\n\n async getPeerByUsername(username: string): Promise<tl.TypeInputPeer | null> {\n const tx = this.db.transaction(TABLES.entities)\n const os = tx.objectStore(TABLES.entities)\n\n const row = await reqToPromise<EntityDto>(os.index('by_username').get(username))\n\n if (row === undefined) return null\n\n return getInputPeer(row)\n }\n\n async getPeerByPhone(phone: string): Promise<tl.TypeInputPeer | null> {\n const tx = this.db.transaction(TABLES.entities)\n const os = tx.objectStore(TABLES.entities)\n\n const row = await reqToPromise<EntityDto>(os.index('by_phone').get(phone))\n\n if (row === undefined) return null\n\n return getInputPeer(row)\n }\n\n async getFullPeerById(peerId: number): Promise<tl.TypeUser | tl.TypeChat | null> {\n const cached = this._cache?.get(peerId)\n if (cached) return cached.full\n\n const tx = this.db.transaction(TABLES.entities)\n const os = tx.objectStore(TABLES.entities)\n\n const row = await reqToPromise<EntityDto>(os.get(peerId))\n\n if (row === undefined) return null\n\n return this._readFullPeer(row.full)\n }\n\n async saveReferenceMessage(peerId: number, chatId: number, messageId: number): Promise<void> {\n const os = this.db.transaction(TABLES.messageRefs, 'readwrite').objectStore(TABLES.messageRefs)\n\n await reqToPromise(os.put({ peerId, chatId, msgId: messageId } satisfies MessageRefDto))\n }\n\n async deleteReferenceMessages(chatId: number, messageIds: number[]): Promise<void> {\n const tx = this.db.transaction(TABLES.messageRefs, 'readwrite')\n const os = tx.objectStore(TABLES.messageRefs)\n const index = os.index('by_msg')\n\n for (const msgId of messageIds) {\n const key = await reqToPromise(index.getKey([chatId, msgId]))\n if (key === undefined) continue\n\n os.delete(key)\n }\n\n return txToPromise(tx)\n }\n\n // IStateStorage implementation\n\n async getState(key: string): Promise<unknown> {\n const tx = this.db.transaction(TABLES.state, 'readwrite')\n const os = tx.objectStore(TABLES.state)\n\n const row = await reqToPromise<FsmItemDto>(os.get(key))\n if (!row) return null\n\n if (row.expires && row.expires < Date.now()) {\n await reqToPromise(os.delete(key))\n\n return null\n }\n\n return JSON.parse(row.value) as unknown\n }\n\n async setState(key: string, state: unknown, ttl?: number): Promise<void> {\n const tx = this.db.transaction(TABLES.state, 'readwrite')\n const os = tx.objectStore(TABLES.state)\n\n const dto: FsmItemDto = {\n key,\n value: JSON.stringify(state),\n expires: ttl ? Date.now() + ttl * 1000 : undefined,\n }\n\n await reqToPromise(os.put(dto))\n }\n\n async deleteState(key: string): Promise<void> {\n const tx = this.db.transaction(TABLES.state, 'readwrite')\n const os = tx.objectStore(TABLES.state)\n\n await reqToPromise(os.delete(key))\n }\n\n getCurrentScene(key: string): Promise<string | null> {\n return this.getState(`$current_scene_${key}`) as Promise<string | null>\n }\n\n setCurrentScene(key: string, scene: string, ttl?: number): Promise<void> {\n return this.setState(`$current_scene_${key}`, scene, ttl)\n }\n\n deleteCurrentScene(key: string): Promise<void> {\n return this.deleteState(`$current_scene_${key}`)\n }\n\n async getRateLimit(key: string, limit: number, window: number): Promise<[number, number]> {\n // leaky bucket\n const now = Date.now()\n\n const tx = this.db.transaction(TABLES.state, 'readwrite')\n const os = tx.objectStore(TABLES.state)\n\n const row = await reqToPromise<FsmItemDto>(os.get(`$rate_limit_${key}`))\n\n if (!row || row.expires! < now) {\n // expired or does not exist\n const dto: FsmItemDto = {\n key: `$rate_limit_${key}`,\n value: limit.toString(),\n expires: now + window * 1000,\n }\n await reqToPromise(os.put(dto))\n\n return [limit, dto.expires!]\n }\n\n let value = Number(row.value)\n\n if (value > 0) {\n value -= 1\n row.value = value.toString()\n await reqToPromise(os.put(row))\n }\n\n return [value, row.expires!]\n }\n\n resetRateLimit(key: string): Promise<void> {\n return this.deleteState(`$rate_limit_${key}`)\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const test_1 = require("@mtcute/test");
|
|
5
|
+
const idb_js_1 = require("./idb.js");
|
|
6
|
+
vitest_1.describe.skipIf(import.meta.env.TEST_ENV !== 'browser')('IdbStorage', () => {
|
|
7
|
+
const idbName = 'mtcute_test_' + Math.random().toString(36).slice(2);
|
|
8
|
+
const storage = new idb_js_1.IdbStorage(idbName);
|
|
9
|
+
(0, test_1.testStorage)(storage);
|
|
10
|
+
(0, test_1.testStateStorage)(storage);
|
|
11
|
+
(0, vitest_1.afterAll)(async () => {
|
|
12
|
+
storage.destroy();
|
|
13
|
+
const req = indexedDB.deleteDatabase(idbName);
|
|
14
|
+
await new Promise((resolve, reject) => {
|
|
15
|
+
req.onerror = () => reject(req.error);
|
|
16
|
+
req.onsuccess = () => resolve();
|
|
17
|
+
req.onblocked = () => resolve();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=idb.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idb.test.js","sourceRoot":"","sources":["../../../src/storage/idb.test.ts"],"names":[],"mappings":";;AAAA,mCAA2C;AAE3C,uCAA4D;AAE5D,qCAAqC;AAErC,iBAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,YAAY,EAAE,GAAG,EAAE;IACvE,MAAM,OAAO,GAAG,cAAc,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAEpE,MAAM,OAAO,GAAG,IAAI,mBAAU,CAAC,OAAO,CAAC,CAAA;IACvC,IAAA,kBAAW,EAAC,OAAO,CAAC,CAAA;IACpB,IAAA,uBAAgB,EAAC,OAAO,CAAC,CAAA;IAEzB,IAAA,iBAAQ,EAAC,KAAK,IAAI,EAAE;QAChB,OAAO,CAAC,OAAO,EAAE,CAAA;QAEjB,MAAM,GAAG,GAAG,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;QAC7C,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACrC,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;YAC/B,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;QACnC,CAAC,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA","sourcesContent":["import { afterAll, describe } from 'vitest'\n\nimport { testStateStorage, testStorage } from '@mtcute/test'\n\nimport { IdbStorage } from './idb.js'\n\ndescribe.skipIf(import.meta.env.TEST_ENV !== 'browser')('IdbStorage', () => {\n const idbName = 'mtcute_test_' + Math.random().toString(36).slice(2)\n\n const storage = new IdbStorage(idbName)\n testStorage(storage)\n testStateStorage(storage)\n\n afterAll(async () => {\n storage.destroy()\n\n const req = indexedDB.deleteDatabase(idbName)\n await new Promise<void>((resolve, reject) => {\n req.onerror = () => reject(req.error)\n req.onsuccess = () => resolve()\n req.onblocked = () => resolve()\n })\n })\n})\n"]}
|
package/cjs/storage/index.d.ts
CHANGED
package/cjs/storage/index.js
CHANGED
|
@@ -15,8 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./abstract.js"), exports);
|
|
18
|
-
__exportStar(require("./json.js"), exports);
|
|
19
|
-
__exportStar(require("./json-file.js"), exports);
|
|
20
|
-
__exportStar(require("./localstorage.js"), exports);
|
|
21
|
-
__exportStar(require("./memory.js"), exports);
|
|
22
18
|
//# sourceMappingURL=index.js.map
|
package/cjs/storage/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA6B
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA6B","sourcesContent":["export * from './abstract.js'\n"]}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { JsonMemoryStorage } from './json.js';
|
|
2
|
+
/**
|
|
3
|
+
* mtcute storage that stores data in a JSON file.
|
|
4
|
+
*
|
|
5
|
+
* > **Note**: This storage is **not fully persistent**, meaning that
|
|
6
|
+
* > some data *will* be lost on restart, including entities cache,
|
|
7
|
+
* > FSM and rate limiter states, because JSON file would be too large otherwise.
|
|
8
|
+
* >
|
|
9
|
+
* > This storage should only be used for testing purposes,
|
|
10
|
+
* > and should not be used in production. Use e.g. `@mtcute/sqlite` instead.
|
|
11
|
+
*
|
|
12
|
+
* @deprecated
|
|
13
|
+
*/
|
|
2
14
|
export declare class JsonFileStorage extends JsonMemoryStorage {
|
|
3
15
|
private readonly _filename;
|
|
4
16
|
private readonly _safe;
|
package/cjs/storage/json-file.js
CHANGED
|
@@ -28,6 +28,18 @@ exports.JsonFileStorage = void 0;
|
|
|
28
28
|
const fs = __importStar(require("fs"));
|
|
29
29
|
const json_js_1 = require("./json.js");
|
|
30
30
|
const EVENTS = ['exit', 'SIGINT', 'SIGUSR1', 'SIGUSR2', 'uncaughtException', 'SIGTERM'];
|
|
31
|
+
/**
|
|
32
|
+
* mtcute storage that stores data in a JSON file.
|
|
33
|
+
*
|
|
34
|
+
* > **Note**: This storage is **not fully persistent**, meaning that
|
|
35
|
+
* > some data *will* be lost on restart, including entities cache,
|
|
36
|
+
* > FSM and rate limiter states, because JSON file would be too large otherwise.
|
|
37
|
+
* >
|
|
38
|
+
* > This storage should only be used for testing purposes,
|
|
39
|
+
* > and should not be used in production. Use e.g. `@mtcute/sqlite` instead.
|
|
40
|
+
*
|
|
41
|
+
* @deprecated
|
|
42
|
+
*/
|
|
31
43
|
class JsonFileStorage extends json_js_1.JsonMemoryStorage {
|
|
32
44
|
constructor(filename, params) {
|
|
33
45
|
super();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-file.js","sourceRoot":"","sources":["../../../src/storage/json-file.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport * as fs from 'fs'\n\nimport { JsonMemoryStorage } from './json.js'\n\nconst EVENTS = ['exit', 'SIGINT', 'SIGUSR1', 'SIGUSR2', 'uncaughtException', 'SIGTERM']\n\nexport class JsonFileStorage extends JsonMemoryStorage {\n private readonly _filename: string\n private readonly _safe: boolean\n private readonly _cleanup: boolean\n\n constructor(\n filename: string,\n params?: {\n /**\n * Whether to save file \"safely\", meaning that the file will first be saved\n * to `${filename}.tmp`, and then renamed to `filename`,\n * instead of writing directly to `filename`.\n *\n * This solves the issue with the storage being saved as\n * a blank file because of the app being stopped while\n * the storage is being written.\n *\n * @default `true`\n */\n safe?: boolean\n\n /**\n * Whether to save file on process exit.\n *\n * @default `true`\n */\n cleanup?: boolean\n },\n ) {\n super()\n\n this._filename = filename\n this._safe = params?.safe ?? true\n this._cleanup = params?.cleanup ?? true\n\n if (this._cleanup) {\n this._onProcessExit = this._onProcessExit.bind(this)\n EVENTS.forEach((event) => process.on(event, this._onProcessExit))\n }\n }\n\n async load(): Promise<void> {\n try {\n this._loadJson(\n await new Promise((res, rej) =>\n fs.readFile(this._filename, 'utf-8', (err, data) => (err ? rej(err) : res(data))),\n ),\n )\n } catch (e) {}\n }\n\n save(): Promise<void> {\n return new Promise((resolve, reject) => {\n fs.writeFile(this._safe ? this._filename + '.tmp' : this._filename, this._saveJson(), (err) => {\n if (err) reject(err)\n else if (this._safe) {\n fs.rename(this._filename + '.tmp', this._filename, (err) => {\n if (err && err.code !== 'ENOENT') reject(err)\n else resolve()\n })\n } else resolve()\n })\n })\n }\n\n private _processExitHandled = false\n private _onProcessExit(): void {\n // on exit handler must be synchronous, thus we use sync methods here\n if (this._processExitHandled) return\n this._processExitHandled = true\n\n try {\n fs.writeFileSync(this._filename, this._saveJson())\n } catch (e) {}\n\n if (this._safe) {\n try {\n fs.unlinkSync(this._filename + '.tmp')\n } catch (e) {}\n }\n }\n\n destroy(): void {\n if (this._cleanup) {\n EVENTS.forEach((event) => process.off(event, this._onProcessExit))\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"json-file.js","sourceRoot":"","sources":["../../../src/storage/json-file.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line no-restricted-imports\nimport * as fs from 'fs'\n\nimport { JsonMemoryStorage } from './json.js'\n\nconst EVENTS = ['exit', 'SIGINT', 'SIGUSR1', 'SIGUSR2', 'uncaughtException', 'SIGTERM']\n\n/**\n * mtcute storage that stores data in a JSON file.\n *\n * > **Note**: This storage is **not fully persistent**, meaning that\n * > some data *will* be lost on restart, including entities cache,\n * > FSM and rate limiter states, because JSON file would be too large otherwise.\n * >\n * > This storage should only be used for testing purposes,\n * > and should not be used in production. Use e.g. `@mtcute/sqlite` instead.\n *\n * @deprecated\n */\nexport class JsonFileStorage extends JsonMemoryStorage {\n private readonly _filename: string\n private readonly _safe: boolean\n private readonly _cleanup: boolean\n\n constructor(\n filename: string,\n params?: {\n /**\n * Whether to save file \"safely\", meaning that the file will first be saved\n * to `${filename}.tmp`, and then renamed to `filename`,\n * instead of writing directly to `filename`.\n *\n * This solves the issue with the storage being saved as\n * a blank file because of the app being stopped while\n * the storage is being written.\n *\n * @default `true`\n */\n safe?: boolean\n\n /**\n * Whether to save file on process exit.\n *\n * @default `true`\n */\n cleanup?: boolean\n },\n ) {\n super()\n\n this._filename = filename\n this._safe = params?.safe ?? true\n this._cleanup = params?.cleanup ?? true\n\n if (this._cleanup) {\n this._onProcessExit = this._onProcessExit.bind(this)\n EVENTS.forEach((event) => process.on(event, this._onProcessExit))\n }\n }\n\n async load(): Promise<void> {\n try {\n this._loadJson(\n await new Promise((res, rej) =>\n fs.readFile(this._filename, 'utf-8', (err, data) => (err ? rej(err) : res(data))),\n ),\n )\n } catch (e) {}\n }\n\n save(): Promise<void> {\n return new Promise((resolve, reject) => {\n fs.writeFile(this._safe ? this._filename + '.tmp' : this._filename, this._saveJson(), (err) => {\n if (err) reject(err)\n else if (this._safe) {\n fs.rename(this._filename + '.tmp', this._filename, (err) => {\n if (err && err.code !== 'ENOENT') reject(err)\n else resolve()\n })\n } else resolve()\n })\n })\n }\n\n private _processExitHandled = false\n private _onProcessExit(): void {\n // on exit handler must be synchronous, thus we use sync methods here\n if (this._processExitHandled) return\n this._processExitHandled = true\n\n try {\n fs.writeFileSync(this._filename, this._saveJson())\n } catch (e) {}\n\n if (this._safe) {\n try {\n fs.unlinkSync(this._filename + '.tmp')\n } catch (e) {}\n }\n }\n\n destroy(): void {\n if (this._cleanup) {\n EVENTS.forEach((event) => process.off(event, this._onProcessExit))\n }\n }\n}\n"]}
|
package/cjs/storage/json.js
CHANGED
|
@@ -23,12 +23,13 @@ class JsonMemoryStorage extends memory_js_1.MemoryStorage {
|
|
|
23
23
|
return ret;
|
|
24
24
|
}
|
|
25
25
|
case 'authKeysTempExpiry':
|
|
26
|
+
case 'pts':
|
|
27
|
+
return new Map(Object.entries(value));
|
|
26
28
|
case 'phoneIndex':
|
|
27
29
|
case 'usernameIndex':
|
|
28
|
-
case 'pts':
|
|
29
30
|
case 'fsm':
|
|
30
31
|
case 'rl':
|
|
31
|
-
|
|
32
|
+
case 'refs':
|
|
32
33
|
case 'entities':
|
|
33
34
|
return new Map();
|
|
34
35
|
}
|
package/cjs/storage/json.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/storage/json.ts"],"names":[],"mappings":";;;AAAA,wDAAwD;AACxD,mDAAuE;AAEvE,2CAA+D;AAE/D;;;GAGG;AACH,MAAa,iBAAkB,SAAQ,yBAAa;IACtC,SAAS,CAAC,IAAY;QAC5B,IAAI,CAAC,aAAa,CACd,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YAC5B,QAAQ,GAAG,EAAE;gBACT,KAAK,UAAU,CAAC;gBAChB,KAAK,cAAc,CAAC,CAAC;oBACjB,MAAM,GAAG,GAAG,IAAI,GAAG,EAA+B,CAEjD;oBAAC,KAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAY,EAAE,EAAE;wBACnD,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;wBACnC,MAAM,MAAM,GAAG,GAAG,KAAK,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;wBAE7D,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,IAAA,iCAAoB,EAAC,GAAG,CAAC,CAAC,CAAA;oBAC9C,CAAC,CAAC,CAAA;oBAEF,OAAO,GAAG,CAAA;iBACb;gBACD,KAAK,oBAAoB,CAAC;gBAC1B,KAAK,YAAY,CAAC;gBAClB,KAAK,eAAe,CAAC;gBACrB,KAAK,KAAK,CAAC;gBACX,KAAK,
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/storage/json.ts"],"names":[],"mappings":";;;AAAA,wDAAwD;AACxD,mDAAuE;AAEvE,2CAA+D;AAE/D;;;GAGG;AACH,MAAa,iBAAkB,SAAQ,yBAAa;IACtC,SAAS,CAAC,IAAY;QAC5B,IAAI,CAAC,aAAa,CACd,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YAC5B,QAAQ,GAAG,EAAE;gBACT,KAAK,UAAU,CAAC;gBAChB,KAAK,cAAc,CAAC,CAAC;oBACjB,MAAM,GAAG,GAAG,IAAI,GAAG,EAA+B,CAEjD;oBAAC,KAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAY,EAAE,EAAE;wBACnD,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;wBACnC,MAAM,MAAM,GAAG,GAAG,KAAK,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;wBAE7D,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,IAAA,iCAAoB,EAAC,GAAG,CAAC,CAAC,CAAA;oBAC9C,CAAC,CAAC,CAAA;oBAEF,OAAO,GAAG,CAAA;iBACb;gBACD,KAAK,oBAAoB,CAAC;gBAC1B,KAAK,KAAK;oBACN,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,KAA+B,CAAC,CAAC,CAAA;gBACnE,KAAK,YAAY,CAAC;gBAClB,KAAK,eAAe,CAAC;gBACrB,KAAK,KAAK,CAAC;gBACX,KAAK,IAAI,CAAC;gBACV,KAAK,MAAM,CAAC;gBACZ,KAAK,UAAU;oBACX,OAAO,IAAI,GAAG,EAAE,CAAA;aACvB;YAED,OAAO,KAAK,CAAA;QAChB,CAAC,CAAuB,CAC3B,CAAA;IACL,CAAC;IAES,SAAS;QACf,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YAC9C,QAAQ,GAAG,EAAE;gBACT,KAAK,UAAU,CAAC;gBAChB,KAAK,cAAc,CAAC,CAAC;oBACjB,MAAM,MAAM,GAAG,KAAuC,CAAA;oBAEtD,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;yBACvB,MAAM,CAAC,CAAC,EAAE,EAA8B,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;yBAC1D,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,GAAG,GAAG,IAAA,yBAAY,EAAC,GAAG,CAAC,CAAC;yBACpD,IAAI,CAAC,GAAG,CAAC,CAAA;iBACjB;gBACD,KAAK,oBAAoB,CAAC;gBAC1B,KAAK,YAAY,CAAC;gBAClB,KAAK,eAAe,CAAC;gBACrB,KAAK,KAAK,CAAC;gBACX,KAAK,KAAK,CAAC;gBACX,KAAK,IAAI;oBACL,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC,GAAI,KAA6B,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;gBAC5E,KAAK,UAAU;oBACX,OAAO,EAAE,CAAA;aAChB;YAED,OAAO,KAAK,CAAA;QAChB,CAAC,CAAC,CAAA;IACN,CAAC;CACJ;AA7DD,8CA6DC","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-return */\nimport { base64DecodeToBuffer, base64Encode } from '@mtcute/tl-runtime'\n\nimport { MemorySessionState, MemoryStorage } from './memory.js'\n\n/**\n * Helper class that provides json serialization functions\n * to the session.\n */\nexport class JsonMemoryStorage extends MemoryStorage {\n protected _loadJson(json: string): void {\n this._setStateFrom(\n JSON.parse(json, (key, value) => {\n switch (key) {\n case 'authKeys':\n case 'authKeysTemp': {\n const ret = new Map<string | number, Uint8Array>()\n\n ;(value as string).split('|').forEach((pair: string) => {\n const [dcId, b64] = pair.split(',')\n const mapKey = key === 'authKeysTemp' ? dcId : parseInt(dcId)\n\n ret.set(mapKey, base64DecodeToBuffer(b64))\n })\n\n return ret\n }\n case 'authKeysTempExpiry':\n case 'pts':\n return new Map(Object.entries(value as Record<string, string>))\n case 'phoneIndex':\n case 'usernameIndex':\n case 'fsm':\n case 'rl':\n case 'refs':\n case 'entities':\n return new Map()\n }\n\n return value\n }) as MemorySessionState,\n )\n }\n\n protected _saveJson(): string {\n return JSON.stringify(this._state, (key, value) => {\n switch (key) {\n case 'authKeys':\n case 'authKeysTemp': {\n const value_ = value as Map<string, Uint8Array | null>\n\n return [...value_.entries()]\n .filter((it): it is [string, Uint8Array] => it[1] !== null)\n .map(([dcId, key]) => dcId + ',' + base64Encode(key))\n .join('|')\n }\n case 'authKeysTempExpiry':\n case 'phoneIndex':\n case 'usernameIndex':\n case 'pts':\n case 'fsm':\n case 'rl':\n return Object.fromEntries([...(value as Map<string, string>).entries()])\n case 'entities':\n return {}\n }\n\n return value\n })\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const json_js_1 = require("./json.js");
|
|
5
|
+
// eslint-disable-next-line no-restricted-globals
|
|
6
|
+
const createBuffer = import.meta.env.TEST_ENV === 'node' ? Buffer.from : (d) => new Uint8Array(d);
|
|
7
|
+
(0, vitest_1.describe)('JsonMemoryStorage', () => {
|
|
8
|
+
class ExtJsonMemoryStorage extends json_js_1.JsonMemoryStorage {
|
|
9
|
+
loadJson(json) {
|
|
10
|
+
this._loadJson(json);
|
|
11
|
+
}
|
|
12
|
+
saveJson() {
|
|
13
|
+
return this._saveJson();
|
|
14
|
+
}
|
|
15
|
+
getInternalState() {
|
|
16
|
+
return this._state;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
(0, vitest_1.it)('should allow importing and exporting to json', () => {
|
|
20
|
+
const s = new ExtJsonMemoryStorage();
|
|
21
|
+
s.setUpdatesPts(123);
|
|
22
|
+
s.setUpdatesQts(456);
|
|
23
|
+
// eslint-disable-next-line no-restricted-globals
|
|
24
|
+
s.setAuthKeyFor(1, createBuffer([1, 2, 3]));
|
|
25
|
+
// eslint-disable-next-line no-restricted-globals
|
|
26
|
+
s.setTempAuthKeyFor(2, 0, createBuffer([4, 5, 6]), 1234567890);
|
|
27
|
+
const json = s.saveJson();
|
|
28
|
+
const s2 = new ExtJsonMemoryStorage();
|
|
29
|
+
s2.loadJson(json);
|
|
30
|
+
(0, vitest_1.expect)(s2.getInternalState()).toEqual({
|
|
31
|
+
...s.getInternalState(),
|
|
32
|
+
entities: new Map(), // entities are not saved
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=json.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.test.js","sourceRoot":"","sources":["../../../src/storage/json.test.ts"],"names":[],"mappings":";;AAAA,mCAA6C;AAE7C,uCAA6C;AAE7C,iDAAiD;AACjD,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAW,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;AAE3G,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;IAC/B,MAAM,oBAAqB,SAAQ,2BAAiB;QAChD,QAAQ,CAAC,IAAY;YACjB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACxB,CAAC;QAED,QAAQ;YACJ,OAAO,IAAI,CAAC,SAAS,EAAE,CAAA;QAC3B,CAAC;QAED,gBAAgB;YACZ,OAAO,IAAI,CAAC,MAAM,CAAA;QACtB,CAAC;KACJ;IAED,IAAA,WAAE,EAAC,8CAA8C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,GAAG,IAAI,oBAAoB,EAAE,CAAA;QAEpC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;QACpB,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;QACpB,iDAAiD;QACjD,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3C,iDAAiD;QACjD,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;QAE9D,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;QACzB,MAAM,EAAE,GAAG,IAAI,oBAAoB,EAAE,CAAA;QACrC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAEjB,IAAA,eAAM,EAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC;YAClC,GAAG,CAAC,CAAC,gBAAgB,EAAE;YACvB,QAAQ,EAAE,IAAI,GAAG,EAAE,EAAE,yBAAyB;SACjD,CAAC,CAAA;IACN,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA","sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { JsonMemoryStorage } from './json.js'\n\n// eslint-disable-next-line no-restricted-globals\nconst createBuffer = import.meta.env.TEST_ENV === 'node' ? Buffer.from : (d: number[]) => new Uint8Array(d)\n\ndescribe('JsonMemoryStorage', () => {\n class ExtJsonMemoryStorage extends JsonMemoryStorage {\n loadJson(json: string): void {\n this._loadJson(json)\n }\n\n saveJson(): string {\n return this._saveJson()\n }\n\n getInternalState() {\n return this._state\n }\n }\n\n it('should allow importing and exporting to json', () => {\n const s = new ExtJsonMemoryStorage()\n\n s.setUpdatesPts(123)\n s.setUpdatesQts(456)\n // eslint-disable-next-line no-restricted-globals\n s.setAuthKeyFor(1, createBuffer([1, 2, 3]))\n // eslint-disable-next-line no-restricted-globals\n s.setTempAuthKeyFor(2, 0, createBuffer([4, 5, 6]), 1234567890)\n\n const json = s.saveJson()\n const s2 = new ExtJsonMemoryStorage()\n s2.loadJson(json)\n\n expect(s2.getInternalState()).toEqual({\n ...s.getInternalState(),\n entities: new Map(), // entities are not saved\n })\n })\n})\n"]}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { JsonMemoryStorage } from './json.js';
|
|
2
|
+
/**
|
|
3
|
+
* mtcute storage that stores data in a `localStorage` key.
|
|
4
|
+
*
|
|
5
|
+
* > **Note**: This storage is **not fully persistent**, meaning that
|
|
6
|
+
* > some data *will* be lost on restart, including entities cache,
|
|
7
|
+
* > FSM and rate limiter states, because the JSON would be too large otherwise.
|
|
8
|
+
* >
|
|
9
|
+
* > This storage should only be used for testing purposes,
|
|
10
|
+
* > and should not be used in production. Use e.g. {@link IdbStorage} instead.
|
|
11
|
+
*
|
|
12
|
+
* @deprecated
|
|
13
|
+
*/
|
|
2
14
|
export declare class LocalstorageStorage extends JsonMemoryStorage {
|
|
3
15
|
private readonly _key;
|
|
4
16
|
constructor(key: string);
|
|
@@ -3,6 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.LocalstorageStorage = void 0;
|
|
4
4
|
const index_js_1 = require("../types/index.js");
|
|
5
5
|
const json_js_1 = require("./json.js");
|
|
6
|
+
/**
|
|
7
|
+
* mtcute storage that stores data in a `localStorage` key.
|
|
8
|
+
*
|
|
9
|
+
* > **Note**: This storage is **not fully persistent**, meaning that
|
|
10
|
+
* > some data *will* be lost on restart, including entities cache,
|
|
11
|
+
* > FSM and rate limiter states, because the JSON would be too large otherwise.
|
|
12
|
+
* >
|
|
13
|
+
* > This storage should only be used for testing purposes,
|
|
14
|
+
* > and should not be used in production. Use e.g. {@link IdbStorage} instead.
|
|
15
|
+
*
|
|
16
|
+
* @deprecated
|
|
17
|
+
*/
|
|
6
18
|
class LocalstorageStorage extends json_js_1.JsonMemoryStorage {
|
|
7
19
|
constructor(key) {
|
|
8
20
|
super();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localstorage.js","sourceRoot":"","sources":["../../../src/storage/localstorage.ts"],"names":[],"mappings":";;;AAAA,gDAAsD;AACtD,uCAA6C;AAE7C,MAAa,mBAAoB,SAAQ,2BAAiB;IAGtD,YAAY,GAAW;QACnB,KAAK,EAAE,CAAA;QAEP,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;YACrC,MAAM,IAAI,6BAAkB,CAAC,gCAAgC,CAAC,CAAA;SACjE;QAED,IAAI,CAAC,IAAI,GAAG,GAAG,CAAA;IACnB,CAAC;IAED,IAAI;QACA,IAAI;YACA,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC3C,IAAI,GAAG,KAAK,IAAI;gBAAE,OAAM;YAExB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;SACtB;QAAC,OAAO,CAAC,EAAE,GAAE;IAClB,CAAC;IAED,IAAI;QACA,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;IACrD,CAAC;CACJ;AAzBD,kDAyBC","sourcesContent":["import { MtUnsupportedError } from '../types/index.js'\nimport { JsonMemoryStorage } from './json.js'\n\nexport class LocalstorageStorage extends JsonMemoryStorage {\n private readonly _key: string\n\n constructor(key: string) {\n super()\n\n if (typeof localStorage === 'undefined') {\n throw new MtUnsupportedError('localStorage is not available!')\n }\n\n this._key = key\n }\n\n load(): void {\n try {\n const val = localStorage.getItem(this._key)\n if (val === null) return\n\n this._loadJson(val)\n } catch (e) {}\n }\n\n save(): void {\n localStorage.setItem(this._key, this._saveJson())\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"localstorage.js","sourceRoot":"","sources":["../../../src/storage/localstorage.ts"],"names":[],"mappings":";;;AAAA,gDAAsD;AACtD,uCAA6C;AAE7C;;;;;;;;;;;GAWG;AACH,MAAa,mBAAoB,SAAQ,2BAAiB;IAGtD,YAAY,GAAW;QACnB,KAAK,EAAE,CAAA;QAEP,IAAI,OAAO,YAAY,KAAK,WAAW,EAAE;YACrC,MAAM,IAAI,6BAAkB,CAAC,gCAAgC,CAAC,CAAA;SACjE;QAED,IAAI,CAAC,IAAI,GAAG,GAAG,CAAA;IACnB,CAAC;IAED,IAAI;QACA,IAAI;YACA,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC3C,IAAI,GAAG,KAAK,IAAI;gBAAE,OAAM;YAExB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;SACtB;QAAC,OAAO,CAAC,EAAE,GAAE;IAClB,CAAC;IAED,IAAI;QACA,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;IACrD,CAAC;CACJ;AAzBD,kDAyBC","sourcesContent":["import { MtUnsupportedError } from '../types/index.js'\nimport { JsonMemoryStorage } from './json.js'\n\n/**\n * mtcute storage that stores data in a `localStorage` key.\n *\n * > **Note**: This storage is **not fully persistent**, meaning that\n * > some data *will* be lost on restart, including entities cache,\n * > FSM and rate limiter states, because the JSON would be too large otherwise.\n * >\n * > This storage should only be used for testing purposes,\n * > and should not be used in production. Use e.g. {@link IdbStorage} instead.\n *\n * @deprecated\n */\nexport class LocalstorageStorage extends JsonMemoryStorage {\n private readonly _key: string\n\n constructor(key: string) {\n super()\n\n if (typeof localStorage === 'undefined') {\n throw new MtUnsupportedError('localStorage is not available!')\n }\n\n this._key = key\n }\n\n load(): void {\n try {\n const val = localStorage.getItem(this._key)\n if (val === null) return\n\n this._loadJson(val)\n } catch (e) {}\n }\n\n save(): void {\n localStorage.setItem(this._key, this._saveJson())\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const localstorage_js_1 = require("./localstorage.js");
|
|
5
|
+
const localStorageStub = {
|
|
6
|
+
getItem: vitest_1.vi.fn().mockImplementation(() => null),
|
|
7
|
+
setItem: vitest_1.vi.fn(),
|
|
8
|
+
};
|
|
9
|
+
(0, vitest_1.describe)('LocalstorageStorage', () => {
|
|
10
|
+
(0, vitest_1.beforeAll)(() => void vitest_1.vi.stubGlobal('localStorage', localStorageStub));
|
|
11
|
+
(0, vitest_1.afterAll)(() => void vitest_1.vi.unstubAllGlobals());
|
|
12
|
+
(0, vitest_1.it)('should load from localstorage', () => {
|
|
13
|
+
const s = new localstorage_js_1.LocalstorageStorage('test');
|
|
14
|
+
s.load();
|
|
15
|
+
(0, vitest_1.expect)(localStorageStub.getItem).toHaveBeenCalledWith('test');
|
|
16
|
+
});
|
|
17
|
+
(0, vitest_1.it)('should save to localstorage', () => {
|
|
18
|
+
const s = new localstorage_js_1.LocalstorageStorage('test');
|
|
19
|
+
s.save();
|
|
20
|
+
(0, vitest_1.expect)(localStorageStub.setItem).toHaveBeenCalledWith('test', vitest_1.expect.any(String));
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=localstorage.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localstorage.test.js","sourceRoot":"","sources":["../../../src/storage/localstorage.test.ts"],"names":[],"mappings":";;AAAA,mCAAsE;AAEtE,uDAAuD;AAEvD,MAAM,gBAAgB,GAAG;IACrB,OAAO,EAAE,WAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;IAC/C,OAAO,EAAE,WAAE,CAAC,EAAE,EAAE;CACnB,CAAA;AACD,IAAA,iBAAQ,EAAC,qBAAqB,EAAE,GAAG,EAAE;IACjC,IAAA,kBAAS,EAAC,GAAG,EAAE,CAAC,KAAK,WAAE,CAAC,UAAU,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAA;IACrE,IAAA,iBAAQ,EAAC,GAAG,EAAE,CAAC,KAAK,WAAE,CAAC,gBAAgB,EAAE,CAAC,CAAA;IAE1C,IAAA,WAAE,EAAC,+BAA+B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,GAAG,IAAI,qCAAmB,CAAC,MAAM,CAAC,CAAA;QACzC,CAAC,CAAC,IAAI,EAAE,CAAA;QAER,IAAA,eAAM,EAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAA;IACjE,CAAC,CAAC,CAAA;IAEF,IAAA,WAAE,EAAC,6BAA6B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,GAAG,IAAI,qCAAmB,CAAC,MAAM,CAAC,CAAA;QACzC,CAAC,CAAC,IAAI,EAAE,CAAA;QAER,IAAA,eAAM,EAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,MAAM,EAAE,eAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACrF,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA","sourcesContent":["import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'\n\nimport { LocalstorageStorage } from './localstorage.js'\n\nconst localStorageStub = {\n getItem: vi.fn().mockImplementation(() => null),\n setItem: vi.fn(),\n}\ndescribe('LocalstorageStorage', () => {\n beforeAll(() => void vi.stubGlobal('localStorage', localStorageStub))\n afterAll(() => void vi.unstubAllGlobals())\n\n it('should load from localstorage', () => {\n const s = new LocalstorageStorage('test')\n s.load()\n\n expect(localStorageStub.getItem).toHaveBeenCalledWith('test')\n })\n\n it('should save to localstorage', () => {\n const s = new LocalstorageStorage('test')\n s.save()\n\n expect(localStorageStub.setItem).toHaveBeenCalledWith('test', expect.any(String))\n })\n})\n"]}
|
package/cjs/storage/memory.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { tl } from '@mtcute/tl';
|
|
2
2
|
import { ITelegramStorage } from './abstract.js';
|
|
3
|
-
declare const CURRENT_VERSION =
|
|
3
|
+
declare const CURRENT_VERSION = 2;
|
|
4
4
|
type PeerInfoWithUpdated = ITelegramStorage.PeerInfo & {
|
|
5
5
|
updated: number;
|
|
6
6
|
};
|
|
@@ -13,6 +13,7 @@ export interface MemorySessionState {
|
|
|
13
13
|
entities: Map<number, PeerInfoWithUpdated>;
|
|
14
14
|
phoneIndex: Map<string, number>;
|
|
15
15
|
usernameIndex: Map<string, number>;
|
|
16
|
+
refs: Map<number, Set<string>>;
|
|
16
17
|
gpts: [number, number, number, number] | null;
|
|
17
18
|
pts: Map<number, number>;
|
|
18
19
|
fsm: Map<string, {
|
|
@@ -25,6 +26,13 @@ export interface MemorySessionState {
|
|
|
25
26
|
}>;
|
|
26
27
|
self: ITelegramStorage.SelfInfo | null;
|
|
27
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* In-memory storage implementation for mtcute.
|
|
31
|
+
*
|
|
32
|
+
* This storage is **not persistent**, meaning that all data
|
|
33
|
+
* **will** be lost on restart. Only use this storage for testing,
|
|
34
|
+
* or if you know what you're doing.
|
|
35
|
+
*/
|
|
28
36
|
export declare class MemoryStorage implements ITelegramStorage {
|
|
29
37
|
protected _state: MemorySessionState;
|
|
30
38
|
private _cachedInputPeers;
|
|
@@ -72,9 +80,12 @@ export declare class MemoryStorage implements ITelegramStorage {
|
|
|
72
80
|
dropAuthKeysFor(dcId: number): void;
|
|
73
81
|
updatePeers(peers: PeerInfoWithUpdated[]): void;
|
|
74
82
|
protected _getInputPeer(peerInfo?: ITelegramStorage.PeerInfo): tl.TypeInputPeer | null;
|
|
83
|
+
private _findPeerByRef;
|
|
75
84
|
getPeerById(peerId: number): tl.TypeInputPeer | null;
|
|
76
85
|
getPeerByPhone(phone: string): tl.TypeInputPeer | null;
|
|
77
86
|
getPeerByUsername(username: string): tl.TypeInputPeer | null;
|
|
87
|
+
saveReferenceMessage(peerId: number, chatId: number, messageId: number): void;
|
|
88
|
+
deleteReferenceMessages(chatId: number, messageIds: number[]): void;
|
|
78
89
|
getSelf(): ITelegramStorage.SelfInfo | null;
|
|
79
90
|
setSelf(self: ITelegramStorage.SelfInfo | null): void;
|
|
80
91
|
setManyChannelPts(values: Map<number, number>): void;
|
package/cjs/storage/memory.js
CHANGED
|
@@ -2,8 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MemoryStorage = void 0;
|
|
4
4
|
const index_js_1 = require("../utils/index.js");
|
|
5
|
-
const CURRENT_VERSION =
|
|
5
|
+
const CURRENT_VERSION = 2;
|
|
6
6
|
const USERNAME_TTL = 86400000; // 24 hours
|
|
7
|
+
/**
|
|
8
|
+
* In-memory storage implementation for mtcute.
|
|
9
|
+
*
|
|
10
|
+
* This storage is **not persistent**, meaning that all data
|
|
11
|
+
* **will** be lost on restart. Only use this storage for testing,
|
|
12
|
+
* or if you know what you're doing.
|
|
13
|
+
*/
|
|
7
14
|
class MemoryStorage {
|
|
8
15
|
constructor(params) {
|
|
9
16
|
this._cachedInputPeers = new index_js_1.LruMap(100);
|
|
@@ -27,12 +34,15 @@ class MemoryStorage {
|
|
|
27
34
|
entities: new Map(),
|
|
28
35
|
phoneIndex: new Map(),
|
|
29
36
|
usernameIndex: new Map(),
|
|
37
|
+
refs: new Map(),
|
|
30
38
|
gpts: null,
|
|
31
39
|
pts: new Map(),
|
|
32
40
|
fsm: new Map(),
|
|
33
41
|
rl: new Map(),
|
|
34
42
|
self: null,
|
|
35
43
|
};
|
|
44
|
+
this._cachedInputPeers?.clear();
|
|
45
|
+
this._cachedFull?.clear();
|
|
36
46
|
}
|
|
37
47
|
/**
|
|
38
48
|
* Set a given object as an underlying state.
|
|
@@ -41,7 +51,13 @@ class MemoryStorage {
|
|
|
41
51
|
* you plan on using it somewhere else, be sure to copy it beforehand.
|
|
42
52
|
*/
|
|
43
53
|
_setStateFrom(obj) {
|
|
44
|
-
|
|
54
|
+
let ver = obj.$version;
|
|
55
|
+
if (ver === 1) {
|
|
56
|
+
// v2: introduced message references
|
|
57
|
+
obj.refs = new Map();
|
|
58
|
+
obj.$version = ver = 2;
|
|
59
|
+
}
|
|
60
|
+
if (ver !== CURRENT_VERSION)
|
|
45
61
|
return;
|
|
46
62
|
// populate indexes if needed
|
|
47
63
|
let populate = false;
|
|
@@ -146,6 +162,10 @@ class MemoryStorage {
|
|
|
146
162
|
if (peer.phone)
|
|
147
163
|
this._state.phoneIndex.set(peer.phone, peer.id);
|
|
148
164
|
this._state.entities.set(peer.id, peer);
|
|
165
|
+
// no point in storing references anymore, since we have the full peer
|
|
166
|
+
if (this._state.refs.has(peer.id)) {
|
|
167
|
+
this._state.refs.delete(peer.id);
|
|
168
|
+
}
|
|
149
169
|
}
|
|
150
170
|
}
|
|
151
171
|
_getInputPeer(peerInfo) {
|
|
@@ -171,11 +191,39 @@ class MemoryStorage {
|
|
|
171
191
|
};
|
|
172
192
|
}
|
|
173
193
|
}
|
|
194
|
+
_findPeerByRef(peerId) {
|
|
195
|
+
const refs = this._state.refs.get(peerId);
|
|
196
|
+
if (!refs || refs.size === 0)
|
|
197
|
+
return null;
|
|
198
|
+
const [ref] = refs.values();
|
|
199
|
+
const [chatId, msgId] = ref.split(':').map(Number);
|
|
200
|
+
const chatPeer = this._getInputPeer(this._state.entities.get(chatId));
|
|
201
|
+
if (!chatPeer)
|
|
202
|
+
return null;
|
|
203
|
+
if (peerId > 0) {
|
|
204
|
+
// user
|
|
205
|
+
return {
|
|
206
|
+
_: 'inputPeerUserFromMessage',
|
|
207
|
+
msgId,
|
|
208
|
+
userId: peerId,
|
|
209
|
+
peer: chatPeer,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
// channel
|
|
213
|
+
return {
|
|
214
|
+
_: 'inputPeerChannelFromMessage',
|
|
215
|
+
msgId,
|
|
216
|
+
channelId: (0, index_js_1.toggleChannelIdMark)(peerId),
|
|
217
|
+
peer: chatPeer,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
174
220
|
getPeerById(peerId) {
|
|
175
221
|
if (this._cachedInputPeers.has(peerId)) {
|
|
176
222
|
return this._cachedInputPeers.get(peerId);
|
|
177
223
|
}
|
|
178
|
-
|
|
224
|
+
let peer = this._getInputPeer(this._state.entities.get(peerId));
|
|
225
|
+
if (!peer)
|
|
226
|
+
peer = this._findPeerByRef(peerId);
|
|
179
227
|
if (peer)
|
|
180
228
|
this._cachedInputPeers.set(peerId, peer);
|
|
181
229
|
return peer;
|
|
@@ -197,6 +245,20 @@ class MemoryStorage {
|
|
|
197
245
|
return null;
|
|
198
246
|
return this._getInputPeer(peer);
|
|
199
247
|
}
|
|
248
|
+
saveReferenceMessage(peerId, chatId, messageId) {
|
|
249
|
+
if (!this._state.refs.has(peerId)) {
|
|
250
|
+
this._state.refs.set(peerId, new Set());
|
|
251
|
+
}
|
|
252
|
+
this._state.refs.get(peerId).add(`${chatId}:${messageId}`);
|
|
253
|
+
}
|
|
254
|
+
deleteReferenceMessages(chatId, messageIds) {
|
|
255
|
+
// not the most efficient way, but it's fine
|
|
256
|
+
for (const refs of this._state.refs.values()) {
|
|
257
|
+
for (const msg of messageIds) {
|
|
258
|
+
refs.delete(`${chatId}:${msg}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
200
262
|
getSelf() {
|
|
201
263
|
return this._state.self;
|
|
202
264
|
}
|