@mt-tl/server 0.1.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.
Potentially problematic release.
This version of @mt-tl/server might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/auth/handshake.d.ts +35 -0
- package/dist/auth/handshake.d.ts.map +1 -0
- package/dist/auth/handshake.js +208 -0
- package/dist/auth/handshake.js.map +1 -0
- package/dist/auth/nonce-store.d.ts +22 -0
- package/dist/auth/nonce-store.d.ts.map +1 -0
- package/dist/auth/nonce-store.js +23 -0
- package/dist/auth/nonce-store.js.map +1 -0
- package/dist/bootstrap.d.ts +36 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +82 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/config.d.ts +103 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -0
- package/dist/core/context.d.ts +57 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +27 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/errors.d.ts +33 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +47 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/rpc.d.ts +83 -0
- package/dist/core/rpc.d.ts.map +1 -0
- package/dist/core/rpc.js +102 -0
- package/dist/core/rpc.js.map +1 -0
- package/dist/core/updates.d.ts +56 -0
- package/dist/core/updates.d.ts.map +1 -0
- package/dist/core/updates.js +34 -0
- package/dist/core/updates.js.map +1 -0
- package/dist/create-server.d.ts +89 -0
- package/dist/create-server.d.ts.map +1 -0
- package/dist/create-server.js +109 -0
- package/dist/create-server.js.map +1 -0
- package/dist/crypto/aes-ige.d.ts +3 -0
- package/dist/crypto/aes-ige.d.ts.map +1 -0
- package/dist/crypto/aes-ige.js +55 -0
- package/dist/crypto/aes-ige.js.map +1 -0
- package/dist/crypto/dh.d.ts +21 -0
- package/dist/crypto/dh.d.ts.map +1 -0
- package/dist/crypto/dh.js +99 -0
- package/dist/crypto/dh.js.map +1 -0
- package/dist/crypto/hashes.d.ts +6 -0
- package/dist/crypto/hashes.d.ts.map +1 -0
- package/dist/crypto/hashes.js +14 -0
- package/dist/crypto/hashes.js.map +1 -0
- package/dist/crypto/msg-key.d.ts +15 -0
- package/dist/crypto/msg-key.d.ts.map +1 -0
- package/dist/crypto/msg-key.js +24 -0
- package/dist/crypto/msg-key.js.map +1 -0
- package/dist/crypto/rsa.d.ts +27 -0
- package/dist/crypto/rsa.d.ts.map +1 -0
- package/dist/crypto/rsa.js +50 -0
- package/dist/crypto/rsa.js.map +1 -0
- package/dist/dispatch/dispatcher.d.ts +72 -0
- package/dist/dispatch/dispatcher.d.ts.map +1 -0
- package/dist/dispatch/dispatcher.js +503 -0
- package/dist/dispatch/dispatcher.js.map +1 -0
- package/dist/dispatch/forwarders/in-process.d.ts +12 -0
- package/dist/dispatch/forwarders/in-process.d.ts.map +1 -0
- package/dist/dispatch/forwarders/in-process.js +15 -0
- package/dist/dispatch/forwarders/in-process.js.map +1 -0
- package/dist/dispatch/forwarders/print.d.ts +14 -0
- package/dist/dispatch/forwarders/print.d.ts.map +1 -0
- package/dist/dispatch/forwarders/print.js +23 -0
- package/dist/dispatch/forwarders/print.js.map +1 -0
- package/dist/dispatch/rpc-forwarder.d.ts +14 -0
- package/dist/dispatch/rpc-forwarder.d.ts.map +1 -0
- package/dist/dispatch/rpc-forwarder.js +2 -0
- package/dist/dispatch/rpc-forwarder.js.map +1 -0
- package/dist/dispatch/types.d.ts +32 -0
- package/dist/dispatch/types.d.ts.map +1 -0
- package/dist/dispatch/types.js +23 -0
- package/dist/dispatch/types.js.map +1 -0
- package/dist/gateway.d.ts +57 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +150 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +12 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +13 -0
- package/dist/lib.js.map +1 -0
- package/dist/server/message-pipeline.d.ts +57 -0
- package/dist/server/message-pipeline.d.ts.map +1 -0
- package/dist/server/message-pipeline.js +199 -0
- package/dist/server/message-pipeline.js.map +1 -0
- package/dist/session/inbound-tracker.d.ts +118 -0
- package/dist/session/inbound-tracker.d.ts.map +1 -0
- package/dist/session/inbound-tracker.js +170 -0
- package/dist/session/inbound-tracker.js.map +1 -0
- package/dist/session/message-id.d.ts +19 -0
- package/dist/session/message-id.d.ts.map +1 -0
- package/dist/session/message-id.js +30 -0
- package/dist/session/message-id.js.map +1 -0
- package/dist/session/salts.d.ts +51 -0
- package/dist/session/salts.d.ts.map +1 -0
- package/dist/session/salts.js +132 -0
- package/dist/session/salts.js.map +1 -0
- package/dist/session/session-manager.d.ts +18 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +43 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/storage/index.d.ts +14 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +16 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/memory.d.ts +3 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +91 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/mongo.d.ts +3 -0
- package/dist/storage/mongo.d.ts.map +1 -0
- package/dist/storage/mongo.js +175 -0
- package/dist/storage/mongo.js.map +1 -0
- package/dist/storage/types.d.ts +85 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +3 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/testkit.d.ts +11 -0
- package/dist/testkit.d.ts.map +1 -0
- package/dist/testkit.js +17 -0
- package/dist/testkit.js.map +1 -0
- package/dist/tl/codec.d.ts +37 -0
- package/dist/tl/codec.d.ts.map +1 -0
- package/dist/tl/codec.js +297 -0
- package/dist/tl/codec.js.map +1 -0
- package/dist/tl/layered-registry.d.ts +29 -0
- package/dist/tl/layered-registry.d.ts.map +1 -0
- package/dist/tl/layered-registry.js +118 -0
- package/dist/tl/layered-registry.js.map +1 -0
- package/dist/tl/protocol.d.ts +126 -0
- package/dist/tl/protocol.d.ts.map +1 -0
- package/dist/tl/protocol.js +22 -0
- package/dist/tl/protocol.js.map +1 -0
- package/dist/tl/reader.d.ts +30 -0
- package/dist/tl/reader.d.ts.map +1 -0
- package/dist/tl/reader.js +87 -0
- package/dist/tl/reader.js.map +1 -0
- package/dist/tl/registry.d.ts +39 -0
- package/dist/tl/registry.d.ts.map +1 -0
- package/dist/tl/registry.js +52 -0
- package/dist/tl/registry.js.map +1 -0
- package/dist/tl/writer.d.ts +24 -0
- package/dist/tl/writer.d.ts.map +1 -0
- package/dist/tl/writer.js +95 -0
- package/dist/tl/writer.js.map +1 -0
- package/dist/transport/connection-registry.d.ts +31 -0
- package/dist/transport/connection-registry.d.ts.map +1 -0
- package/dist/transport/connection-registry.js +84 -0
- package/dist/transport/connection-registry.js.map +1 -0
- package/dist/transport/connection.d.ts +62 -0
- package/dist/transport/connection.d.ts.map +1 -0
- package/dist/transport/connection.js +77 -0
- package/dist/transport/connection.js.map +1 -0
- package/dist/transport/framing.d.ts +39 -0
- package/dist/transport/framing.d.ts.map +1 -0
- package/dist/transport/framing.js +212 -0
- package/dist/transport/framing.js.map +1 -0
- package/dist/transport/proxy-protocol.d.ts +23 -0
- package/dist/transport/proxy-protocol.d.ts.map +1 -0
- package/dist/transport/proxy-protocol.js +108 -0
- package/dist/transport/proxy-protocol.js.map +1 -0
- package/dist/transport/server-common.d.ts +27 -0
- package/dist/transport/server-common.d.ts.map +1 -0
- package/dist/transport/server-common.js +27 -0
- package/dist/transport/server-common.js.map +1 -0
- package/dist/transport/tcp-server.d.ts +26 -0
- package/dist/transport/tcp-server.d.ts.map +1 -0
- package/dist/transport/tcp-server.js +91 -0
- package/dist/transport/tcp-server.js.map +1 -0
- package/dist/transport/ws-server.d.ts +19 -0
- package/dist/transport/ws-server.d.ts.map +1 -0
- package/dist/transport/ws-server.js +78 -0
- package/dist/transport/ws-server.js.map +1 -0
- package/dist/update-publisher.d.ts +34 -0
- package/dist/update-publisher.d.ts.map +1 -0
- package/dist/update-publisher.js +29 -0
- package/dist/update-publisher.js.map +1 -0
- package/dist/updates/mongo-update-log.d.ts +13 -0
- package/dist/updates/mongo-update-log.d.ts.map +1 -0
- package/dist/updates/mongo-update-log.js +39 -0
- package/dist/updates/mongo-update-log.js.map +1 -0
- package/dist/updates/presence-binder.d.ts +29 -0
- package/dist/updates/presence-binder.d.ts.map +1 -0
- package/dist/updates/presence-binder.js +36 -0
- package/dist/updates/presence-binder.js.map +1 -0
- package/dist/updates/presence.d.ts +31 -0
- package/dist/updates/presence.d.ts.map +1 -0
- package/dist/updates/presence.js +44 -0
- package/dist/updates/presence.js.map +1 -0
- package/dist/updates/push.d.ts +25 -0
- package/dist/updates/push.d.ts.map +1 -0
- package/dist/updates/push.js +72 -0
- package/dist/updates/push.js.map +1 -0
- package/dist/updates/redis-bus.d.ts +45 -0
- package/dist/updates/redis-bus.d.ts.map +1 -0
- package/dist/updates/redis-bus.js +59 -0
- package/dist/updates/redis-bus.js.map +1 -0
- package/dist/updates/redis-presence.d.ts +43 -0
- package/dist/updates/redis-presence.d.ts.map +1 -0
- package/dist/updates/redis-presence.js +65 -0
- package/dist/updates/redis-presence.js.map +1 -0
- package/dist/updates/render.d.ts +16 -0
- package/dist/updates/render.d.ts.map +1 -0
- package/dist/updates/render.js +46 -0
- package/dist/updates/render.js.map +1 -0
- package/dist/updates/router.d.ts +27 -0
- package/dist/updates/router.d.ts.map +1 -0
- package/dist/updates/router.js +36 -0
- package/dist/updates/router.js.map +1 -0
- package/dist/updates/types.d.ts +23 -0
- package/dist/updates/types.d.ts.map +1 -0
- package/dist/updates/types.js +2 -0
- package/dist/updates/types.js.map +1 -0
- package/dist/updates/update-bus.d.ts +29 -0
- package/dist/updates/update-bus.d.ts.map +1 -0
- package/dist/updates/update-bus.js +24 -0
- package/dist/updates/update-bus.js.map +1 -0
- package/dist/util/bytes.d.ts +12 -0
- package/dist/util/bytes.d.ts.map +1 -0
- package/dist/util/bytes.js +46 -0
- package/dist/util/bytes.js.map +1 -0
- package/package.json +84 -0
- package/src/auth/handshake.ts +262 -0
- package/src/auth/nonce-store.ts +39 -0
- package/src/bootstrap.ts +114 -0
- package/src/config.ts +103 -0
- package/src/core/context.ts +94 -0
- package/src/core/errors.ts +52 -0
- package/src/core/index.ts +4 -0
- package/src/core/rpc.ts +165 -0
- package/src/core/updates.ts +69 -0
- package/src/create-server.ts +181 -0
- package/src/crypto/aes-ige.ts +57 -0
- package/src/crypto/dh.ts +101 -0
- package/src/crypto/hashes.ts +17 -0
- package/src/crypto/msg-key.ts +29 -0
- package/src/crypto/rsa.ts +70 -0
- package/src/dispatch/dispatcher.ts +586 -0
- package/src/dispatch/forwarders/in-process.ts +14 -0
- package/src/dispatch/forwarders/print.ts +22 -0
- package/src/dispatch/rpc-forwarder.ts +15 -0
- package/src/dispatch/types.ts +60 -0
- package/src/gateway.ts +214 -0
- package/src/index.ts +53 -0
- package/src/lib.ts +24 -0
- package/src/server/message-pipeline.ts +256 -0
- package/src/session/inbound-tracker.ts +221 -0
- package/src/session/message-id.ts +43 -0
- package/src/session/salts.ts +162 -0
- package/src/session/session-manager.ts +66 -0
- package/src/storage/index.ts +26 -0
- package/src/storage/memory.ts +101 -0
- package/src/storage/mongo.ts +215 -0
- package/src/storage/types.ts +92 -0
- package/src/testkit.ts +19 -0
- package/src/tl/codec.ts +292 -0
- package/src/tl/layered-registry.ts +132 -0
- package/src/tl/protocol.ts +146 -0
- package/src/tl/reader.ts +99 -0
- package/src/tl/registry.ts +78 -0
- package/src/tl/writer.ts +104 -0
- package/src/transport/connection-registry.ts +91 -0
- package/src/transport/connection.ts +113 -0
- package/src/transport/framing.ts +223 -0
- package/src/transport/proxy-protocol.ts +109 -0
- package/src/transport/server-common.ts +49 -0
- package/src/transport/tcp-server.ts +102 -0
- package/src/transport/ws-server.ts +94 -0
- package/src/update-publisher.ts +47 -0
- package/src/updates/mongo-update-log.ts +49 -0
- package/src/updates/presence-binder.ts +51 -0
- package/src/updates/presence.ts +61 -0
- package/src/updates/push.ts +90 -0
- package/src/updates/redis-bus.ts +86 -0
- package/src/updates/redis-presence.ts +87 -0
- package/src/updates/render.ts +53 -0
- package/src/updates/router.ts +52 -0
- package/src/updates/types.ts +24 -0
- package/src/updates/update-bus.ts +49 -0
- package/src/util/bytes.ts +49 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { toBigIntLE } from '../util/bytes.js';
|
|
2
|
+
export const BOOL_TRUE_ID = 0x997275b5;
|
|
3
|
+
export const BOOL_FALSE_ID = 0xbc799737;
|
|
4
|
+
export const VECTOR_ID = 0x1cb5c415;
|
|
5
|
+
/**
|
|
6
|
+
* Low-level reader for the TL wire format. Exposes only primitive reads; the
|
|
7
|
+
* codec drives constructor-id dispatch, vectors and flags. Ported from the
|
|
8
|
+
* existing `protocolBuffer.js` (same little-endian / padding rules).
|
|
9
|
+
*/
|
|
10
|
+
export class TlReader {
|
|
11
|
+
buf;
|
|
12
|
+
pos = 0;
|
|
13
|
+
constructor(buf) {
|
|
14
|
+
this.buf = buf;
|
|
15
|
+
}
|
|
16
|
+
get position() {
|
|
17
|
+
return this.pos;
|
|
18
|
+
}
|
|
19
|
+
get remaining() {
|
|
20
|
+
return this.buf.length - this.pos;
|
|
21
|
+
}
|
|
22
|
+
expect(len) {
|
|
23
|
+
if (this.buf.length < this.pos + len) {
|
|
24
|
+
throw new Error(`TL read out of bounds: need ${len}, have ${this.remaining}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
read(len) {
|
|
28
|
+
this.expect(len);
|
|
29
|
+
const out = this.buf.subarray(this.pos, this.pos + len);
|
|
30
|
+
this.pos += len;
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
skip(len) {
|
|
34
|
+
this.expect(len);
|
|
35
|
+
this.pos += len;
|
|
36
|
+
}
|
|
37
|
+
readUInt8() {
|
|
38
|
+
this.expect(1);
|
|
39
|
+
return this.buf.readUInt8(this.pos++);
|
|
40
|
+
}
|
|
41
|
+
readUInt32() {
|
|
42
|
+
this.expect(4);
|
|
43
|
+
const v = this.buf.readUInt32LE(this.pos);
|
|
44
|
+
this.pos += 4;
|
|
45
|
+
return v;
|
|
46
|
+
}
|
|
47
|
+
readInt32() {
|
|
48
|
+
this.expect(4);
|
|
49
|
+
const v = this.buf.readInt32LE(this.pos);
|
|
50
|
+
this.pos += 4;
|
|
51
|
+
return v;
|
|
52
|
+
}
|
|
53
|
+
/** TL `long` — 8 bytes LE, read as an unsigned bigint (matches existing server). */
|
|
54
|
+
readLong() {
|
|
55
|
+
return toBigIntLE(this.read(8));
|
|
56
|
+
}
|
|
57
|
+
readDouble() {
|
|
58
|
+
this.expect(8);
|
|
59
|
+
const v = this.buf.readDoubleLE(this.pos);
|
|
60
|
+
this.pos += 8;
|
|
61
|
+
return v;
|
|
62
|
+
}
|
|
63
|
+
readInt128() {
|
|
64
|
+
return Buffer.from(this.read(16));
|
|
65
|
+
}
|
|
66
|
+
readInt256() {
|
|
67
|
+
return Buffer.from(this.read(32));
|
|
68
|
+
}
|
|
69
|
+
/** TL `bytes`/`string` — length-prefixed with 4-byte alignment padding. */
|
|
70
|
+
readBytes() {
|
|
71
|
+
let extra = 1;
|
|
72
|
+
let len = this.readUInt8();
|
|
73
|
+
if (len >= 254) {
|
|
74
|
+
len = this.readUInt8() + this.readUInt8() * 256 + this.readUInt8() * 65536;
|
|
75
|
+
extra = 4;
|
|
76
|
+
}
|
|
77
|
+
const out = Buffer.from(this.read(len));
|
|
78
|
+
const rem = (len + extra) % 4;
|
|
79
|
+
if (rem > 0)
|
|
80
|
+
this.skip(4 - rem);
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
readString() {
|
|
84
|
+
return this.readBytes().toString('utf-8');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/tl/reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAA;AACtC,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAA;AACvC,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAA;AAEnC;;;;GAIG;AACH,MAAM,OAAO,QAAQ;IAGY;IAFrB,GAAG,GAAG,CAAC,CAAA;IAEf,YAA6B,GAAW;QAAX,QAAG,GAAH,GAAG,CAAQ;IAAG,CAAC;IAE5C,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,GAAG,CAAA;IACnB,CAAC;IAED,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAA;IACrC,CAAC;IAEO,MAAM,CAAC,GAAW;QACtB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,UAAU,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;QACjF,CAAC;IACL,CAAC;IAED,IAAI,CAAC,GAAW;QACZ,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;QACvD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAA;QACf,OAAO,GAAG,CAAA;IACd,CAAC;IAED,IAAI,CAAC,GAAW;QACZ,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAChB,IAAI,CAAC,GAAG,IAAI,GAAG,CAAA;IACnB,CAAC;IAED,SAAS;QACL,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACd,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;IACzC,CAAC;IAED,UAAU;QACN,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACd,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;QACb,OAAO,CAAC,CAAA;IACZ,CAAC;IAED,SAAS;QACL,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACd,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACxC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;QACb,OAAO,CAAC,CAAA;IACZ,CAAC;IAED,oFAAoF;IACpF,QAAQ;QACJ,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACnC,CAAC;IAED,UAAU;QACN,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACd,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;QACb,OAAO,CAAC,CAAA;IACZ,CAAC;IAED,UAAU;QACN,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;IACrC,CAAC;IAED,UAAU;QACN,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;IACrC,CAAC;IAED,2EAA2E;IAC3E,SAAS;QACL,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;QAC1B,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;YACb,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,KAAK,CAAA;YAC1E,KAAK,GAAG,CAAC,CAAA;QACb,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACvC,MAAM,GAAG,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;QAC7B,IAAI,GAAG,GAAG,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAA;QAC/B,OAAO,GAAG,CAAA;IACd,CAAC;IAED,UAAU;QACN,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC7C,CAAC;CACJ"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { TlDef } from '@mt-tl/tl';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves TL definitions both ways: by wire constructor id (for decoding) and
|
|
4
|
+
* by name (for encoding a result the backend returned as `{ _: name, ... }`).
|
|
5
|
+
*
|
|
6
|
+
* Hand-written protocol/service classes register a {@link ProtocolCodec} for
|
|
7
|
+
* their id so the pipeline can read/write them with typed code; everything else
|
|
8
|
+
* falls through to the generic, IR-driven codec.
|
|
9
|
+
*/
|
|
10
|
+
export interface ProtocolCodec {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
read(reader: import('./reader.js').TlReader): unknown;
|
|
14
|
+
write(writer: import('./writer.js').TlWriter, value: unknown): void;
|
|
15
|
+
}
|
|
16
|
+
export declare class TlRegistry {
|
|
17
|
+
private byId;
|
|
18
|
+
private byName;
|
|
19
|
+
private protocolCodecs;
|
|
20
|
+
register(def: TlDef): void;
|
|
21
|
+
registerProtocolCodec(codec: ProtocolCodec): void;
|
|
22
|
+
getById(idNum: number): TlDef | undefined;
|
|
23
|
+
getByName(name: string): TlDef | undefined;
|
|
24
|
+
getProtocolCodec(idNum: number): ProtocolCodec | undefined;
|
|
25
|
+
get size(): number;
|
|
26
|
+
}
|
|
27
|
+
export interface LoadSchemaResult {
|
|
28
|
+
registry: TlRegistry;
|
|
29
|
+
constructors: number;
|
|
30
|
+
methods: number;
|
|
31
|
+
crcMismatches: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Loads + merges one or more `.tl` schema directories into a single registry.
|
|
35
|
+
* The gateway merges the framework's protocol schema with the app's business
|
|
36
|
+
* schema — pass protocol first (earlier dirs win a name/id clash).
|
|
37
|
+
*/
|
|
38
|
+
export declare function loadSchema(dirs: string | string[]): LoadSchemaResult;
|
|
39
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tl/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AAGtC;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,MAAM,EAAE,OAAO,aAAa,EAAE,QAAQ,GAAG,OAAO,CAAA;IACrD,KAAK,CAAC,MAAM,EAAE,OAAO,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;CACtE;AAED,qBAAa,UAAU;IACnB,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,cAAc,CAAmC;IAEzD,QAAQ,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI;IAK1B,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAIjD,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAIzC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAI1C,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI1D,IAAI,IAAI,IAAI,MAAM,CAEjB;CACJ;AAED,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,EAAE,UAAU,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,gBAAgB,CAgBpE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { parseSchemaDir } from '@mt-tl/tl';
|
|
2
|
+
export class TlRegistry {
|
|
3
|
+
byId = new Map();
|
|
4
|
+
byName = new Map();
|
|
5
|
+
protocolCodecs = new Map();
|
|
6
|
+
register(def) {
|
|
7
|
+
if (!this.byId.has(def.idNum))
|
|
8
|
+
this.byId.set(def.idNum, def);
|
|
9
|
+
if (!this.byName.has(def.name))
|
|
10
|
+
this.byName.set(def.name, def);
|
|
11
|
+
}
|
|
12
|
+
registerProtocolCodec(codec) {
|
|
13
|
+
this.protocolCodecs.set(parseInt(codec.id, 16) >>> 0, codec);
|
|
14
|
+
}
|
|
15
|
+
getById(idNum) {
|
|
16
|
+
return this.byId.get(idNum >>> 0);
|
|
17
|
+
}
|
|
18
|
+
getByName(name) {
|
|
19
|
+
return this.byName.get(name);
|
|
20
|
+
}
|
|
21
|
+
getProtocolCodec(idNum) {
|
|
22
|
+
return this.protocolCodecs.get(idNum >>> 0);
|
|
23
|
+
}
|
|
24
|
+
get size() {
|
|
25
|
+
return this.byId.size;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Loads + merges one or more `.tl` schema directories into a single registry.
|
|
30
|
+
* The gateway merges the framework's protocol schema with the app's business
|
|
31
|
+
* schema — pass protocol first (earlier dirs win a name/id clash).
|
|
32
|
+
*/
|
|
33
|
+
export function loadSchema(dirs) {
|
|
34
|
+
const list = Array.isArray(dirs) ? dirs : [dirs];
|
|
35
|
+
const registry = new TlRegistry();
|
|
36
|
+
let constructors = 0;
|
|
37
|
+
let methods = 0;
|
|
38
|
+
let crcMismatches = 0;
|
|
39
|
+
for (const dir of list) {
|
|
40
|
+
const parsed = parseSchemaDir(dir);
|
|
41
|
+
crcMismatches += parsed.crcMismatches.length;
|
|
42
|
+
for (const def of parsed.defs) {
|
|
43
|
+
registry.register(def);
|
|
44
|
+
if (def.kind === 'method')
|
|
45
|
+
methods++;
|
|
46
|
+
else
|
|
47
|
+
constructors++;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return { registry, constructors, methods, crcMismatches };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tl/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAiB1C,MAAM,OAAO,UAAU;IACX,IAAI,GAAG,IAAI,GAAG,EAAiB,CAAA;IAC/B,MAAM,GAAG,IAAI,GAAG,EAAiB,CAAA;IACjC,cAAc,GAAG,IAAI,GAAG,EAAyB,CAAA;IAEzD,QAAQ,CAAC,GAAU;QACf,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAC5D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAClE,CAAC;IAED,qBAAqB,CAAC,KAAoB;QACtC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;IAChE,CAAC;IAED,OAAO,CAAC,KAAa;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAA;IACrC,CAAC;IAED,SAAS,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAChC,CAAC;IAED,gBAAgB,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;IACzB,CAAC;CACJ;AASD;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,IAAuB;IAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAChD,MAAM,QAAQ,GAAG,IAAI,UAAU,EAAE,CAAA;IACjC,IAAI,YAAY,GAAG,CAAC,CAAA;IACpB,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,IAAI,aAAa,GAAG,CAAC,CAAA;IACrB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;QAClC,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,CAAA;QAC5C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5B,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;YACtB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAA;;gBAC/B,YAAY,EAAE,CAAA;QACvB,CAAC;IACL,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,CAAA;AAC7D,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level writer for the TL wire format. Grows its backing buffer in 1 KiB
|
|
3
|
+
* steps. Ported from the existing `protocolBuffer.js`.
|
|
4
|
+
*/
|
|
5
|
+
export declare class TlWriter {
|
|
6
|
+
private buf;
|
|
7
|
+
private pos;
|
|
8
|
+
private readonly step;
|
|
9
|
+
constructor(preallocate?: number);
|
|
10
|
+
private alloc;
|
|
11
|
+
writeRaw(val: Buffer, len?: number): this;
|
|
12
|
+
writeUInt8(val: number): this;
|
|
13
|
+
writeUInt32(val: number): this;
|
|
14
|
+
writeInt32(val: number): this;
|
|
15
|
+
writeLong(val: bigint): this;
|
|
16
|
+
writeDouble(val: number): this;
|
|
17
|
+
/** 16/32 raw bytes for int128/int256 (left-padded if a short buffer is given). */
|
|
18
|
+
writeFixed(val: Buffer, len: number): this;
|
|
19
|
+
writeBytes(val: Buffer): this;
|
|
20
|
+
writeString(val: string): this;
|
|
21
|
+
writeBool(val: boolean): this;
|
|
22
|
+
toBuffer(): Buffer;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/tl/writer.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,QAAQ;IACjB,OAAO,CAAC,GAAG,CAAQ;IACnB,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAO;gBAEhB,WAAW,SAAO;IAI9B,OAAO,CAAC,KAAK;IASb,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI;IAO7C,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAM7B,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAO9B,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAO7B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI5B,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAO9B,kFAAkF;IAClF,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAO1C,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAqB7B,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI9B,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAI7B,QAAQ,IAAI,MAAM;CAGrB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { toBufferLE } from '../util/bytes.js';
|
|
2
|
+
import { BOOL_FALSE_ID, BOOL_TRUE_ID } from './reader.js';
|
|
3
|
+
/**
|
|
4
|
+
* Low-level writer for the TL wire format. Grows its backing buffer in 1 KiB
|
|
5
|
+
* steps. Ported from the existing `protocolBuffer.js`.
|
|
6
|
+
*/
|
|
7
|
+
export class TlWriter {
|
|
8
|
+
buf;
|
|
9
|
+
pos = 0;
|
|
10
|
+
step = 1024;
|
|
11
|
+
constructor(preallocate = 1024) {
|
|
12
|
+
this.buf = Buffer.allocUnsafe(preallocate);
|
|
13
|
+
}
|
|
14
|
+
alloc(len) {
|
|
15
|
+
if (this.buf.length >= this.pos + len)
|
|
16
|
+
return;
|
|
17
|
+
let target = this.buf.length + this.step;
|
|
18
|
+
while (target < this.pos + len)
|
|
19
|
+
target += this.step;
|
|
20
|
+
const next = Buffer.allocUnsafe(target);
|
|
21
|
+
this.buf.copy(next, 0, 0, this.pos);
|
|
22
|
+
this.buf = next;
|
|
23
|
+
}
|
|
24
|
+
writeRaw(val, len = val.length) {
|
|
25
|
+
this.alloc(len);
|
|
26
|
+
val.copy(this.buf, this.pos, 0, len);
|
|
27
|
+
this.pos += len;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
writeUInt8(val) {
|
|
31
|
+
this.alloc(1);
|
|
32
|
+
this.buf.writeUInt8(val & 0xff, this.pos++);
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
writeUInt32(val) {
|
|
36
|
+
this.alloc(4);
|
|
37
|
+
this.buf.writeUInt32LE(val >>> 0, this.pos);
|
|
38
|
+
this.pos += 4;
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
writeInt32(val) {
|
|
42
|
+
this.alloc(4);
|
|
43
|
+
this.buf.writeInt32LE(val | 0, this.pos);
|
|
44
|
+
this.pos += 4;
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
writeLong(val) {
|
|
48
|
+
return this.writeRaw(toBufferLE(BigInt(val), 8), 8);
|
|
49
|
+
}
|
|
50
|
+
writeDouble(val) {
|
|
51
|
+
this.alloc(8);
|
|
52
|
+
this.buf.writeDoubleLE(val, this.pos);
|
|
53
|
+
this.pos += 8;
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
/** 16/32 raw bytes for int128/int256 (left-padded if a short buffer is given). */
|
|
57
|
+
writeFixed(val, len) {
|
|
58
|
+
if (val.length === len)
|
|
59
|
+
return this.writeRaw(val, len);
|
|
60
|
+
const padded = Buffer.alloc(len);
|
|
61
|
+
val.copy(padded, len - val.length);
|
|
62
|
+
return this.writeRaw(padded, len);
|
|
63
|
+
}
|
|
64
|
+
writeBytes(val) {
|
|
65
|
+
let len;
|
|
66
|
+
if (val.length < 254) {
|
|
67
|
+
this.writeUInt8(val.length);
|
|
68
|
+
len = 1;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// 0xfe marker + 3-byte LE length
|
|
72
|
+
this.writeUInt8(254);
|
|
73
|
+
this.writeUInt32(val.length);
|
|
74
|
+
this.pos--;
|
|
75
|
+
len = 4;
|
|
76
|
+
}
|
|
77
|
+
this.writeRaw(val);
|
|
78
|
+
len += val.length;
|
|
79
|
+
while (len % 4 !== 0) {
|
|
80
|
+
this.writeUInt8(0);
|
|
81
|
+
len++;
|
|
82
|
+
}
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
writeString(val) {
|
|
86
|
+
return this.writeBytes(val ? Buffer.from(val, 'utf-8') : Buffer.alloc(0));
|
|
87
|
+
}
|
|
88
|
+
writeBool(val) {
|
|
89
|
+
return this.writeUInt32(val ? BOOL_TRUE_ID : BOOL_FALSE_ID);
|
|
90
|
+
}
|
|
91
|
+
toBuffer() {
|
|
92
|
+
return Buffer.from(this.buf.subarray(0, this.pos));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/tl/writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Connection } from './connection.js';
|
|
2
|
+
/**
|
|
3
|
+
* Per-node map of authorized subject -> live connections, used to deliver
|
|
4
|
+
* server-pushed updates to the right sockets. A subject (internal user id) may
|
|
5
|
+
* have several connections (multiple devices/sessions) on one node.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ConnectionRegistry {
|
|
8
|
+
private bySubject;
|
|
9
|
+
private connSubject;
|
|
10
|
+
private byAuthKey;
|
|
11
|
+
private connAuthKey;
|
|
12
|
+
register(subject: string, conn: Connection): void;
|
|
13
|
+
/** Index a connection by its auth key, for delivery before/without a subject. */
|
|
14
|
+
registerAuthKey(authKeyId: string, conn: Connection): void;
|
|
15
|
+
/** Remove a connection from both indexes; returns the keys it was held under. */
|
|
16
|
+
unregister(conn: Connection): {
|
|
17
|
+
subject?: string;
|
|
18
|
+
authKeyId?: string;
|
|
19
|
+
};
|
|
20
|
+
subjectOf(conn: Connection): string | undefined;
|
|
21
|
+
hasSubject(subject: string): boolean;
|
|
22
|
+
hasAuthKey(authKeyId: string): boolean;
|
|
23
|
+
getBySubject(subject: string): Connection[];
|
|
24
|
+
getByAuthKey(authKeyId: string): Connection[];
|
|
25
|
+
/** All subjects with at least one local connection (for presence heartbeat). */
|
|
26
|
+
subjects(): string[];
|
|
27
|
+
/** All auth keys with at least one local connection (for presence heartbeat). */
|
|
28
|
+
authKeys(): string[];
|
|
29
|
+
get size(): number;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=connection-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-registry.d.ts","sourceRoot":"","sources":["../../src/transport/connection-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;;;GAIG;AACH,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,WAAW,CAAgC;IAEnD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI;IAOjD,iFAAiF;IACjF,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI;IAM1D,iFAAiF;IACjF,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IActE,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS;IAI/C,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAGpC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAItC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE;IAI3C,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE;IAK7C,gFAAgF;IAChF,QAAQ,IAAI,MAAM,EAAE;IAGpB,iFAAiF;IACjF,QAAQ,IAAI,MAAM,EAAE;IAIpB,IAAI,IAAI,IAAI,MAAM,CAEjB;CACJ"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-node map of authorized subject -> live connections, used to deliver
|
|
3
|
+
* server-pushed updates to the right sockets. A subject (internal user id) may
|
|
4
|
+
* have several connections (multiple devices/sessions) on one node.
|
|
5
|
+
*/
|
|
6
|
+
export class ConnectionRegistry {
|
|
7
|
+
bySubject = new Map();
|
|
8
|
+
connSubject = new Map();
|
|
9
|
+
byAuthKey = new Map();
|
|
10
|
+
connAuthKey = new Map();
|
|
11
|
+
register(subject, conn) {
|
|
12
|
+
const prev = this.connSubject.get(conn);
|
|
13
|
+
if (prev !== undefined && prev !== subject)
|
|
14
|
+
removeFrom(this.bySubject, prev, conn);
|
|
15
|
+
this.connSubject.set(conn, subject);
|
|
16
|
+
addTo(this.bySubject, subject, conn);
|
|
17
|
+
}
|
|
18
|
+
/** Index a connection by its auth key, for delivery before/without a subject. */
|
|
19
|
+
registerAuthKey(authKeyId, conn) {
|
|
20
|
+
if (this.connAuthKey.get(conn) === authKeyId)
|
|
21
|
+
return;
|
|
22
|
+
this.connAuthKey.set(conn, authKeyId);
|
|
23
|
+
addTo(this.byAuthKey, authKeyId, conn);
|
|
24
|
+
}
|
|
25
|
+
/** Remove a connection from both indexes; returns the keys it was held under. */
|
|
26
|
+
unregister(conn) {
|
|
27
|
+
const subject = this.connSubject.get(conn);
|
|
28
|
+
if (subject !== undefined) {
|
|
29
|
+
this.connSubject.delete(conn);
|
|
30
|
+
removeFrom(this.bySubject, subject, conn);
|
|
31
|
+
}
|
|
32
|
+
const authKeyId = this.connAuthKey.get(conn);
|
|
33
|
+
if (authKeyId !== undefined) {
|
|
34
|
+
this.connAuthKey.delete(conn);
|
|
35
|
+
removeFrom(this.byAuthKey, authKeyId, conn);
|
|
36
|
+
}
|
|
37
|
+
return { subject, authKeyId };
|
|
38
|
+
}
|
|
39
|
+
subjectOf(conn) {
|
|
40
|
+
return this.connSubject.get(conn);
|
|
41
|
+
}
|
|
42
|
+
hasSubject(subject) {
|
|
43
|
+
return this.bySubject.has(subject);
|
|
44
|
+
}
|
|
45
|
+
hasAuthKey(authKeyId) {
|
|
46
|
+
return this.byAuthKey.has(authKeyId);
|
|
47
|
+
}
|
|
48
|
+
getBySubject(subject) {
|
|
49
|
+
const set = this.bySubject.get(subject);
|
|
50
|
+
return set ? [...set] : [];
|
|
51
|
+
}
|
|
52
|
+
getByAuthKey(authKeyId) {
|
|
53
|
+
const set = this.byAuthKey.get(authKeyId);
|
|
54
|
+
return set ? [...set] : [];
|
|
55
|
+
}
|
|
56
|
+
/** All subjects with at least one local connection (for presence heartbeat). */
|
|
57
|
+
subjects() {
|
|
58
|
+
return [...this.bySubject.keys()];
|
|
59
|
+
}
|
|
60
|
+
/** All auth keys with at least one local connection (for presence heartbeat). */
|
|
61
|
+
authKeys() {
|
|
62
|
+
return [...this.byAuthKey.keys()];
|
|
63
|
+
}
|
|
64
|
+
get size() {
|
|
65
|
+
return this.connSubject.size;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function addTo(map, key, conn) {
|
|
69
|
+
let set = map.get(key);
|
|
70
|
+
if (!set) {
|
|
71
|
+
set = new Set();
|
|
72
|
+
map.set(key, set);
|
|
73
|
+
}
|
|
74
|
+
set.add(conn);
|
|
75
|
+
}
|
|
76
|
+
function removeFrom(map, key, conn) {
|
|
77
|
+
const set = map.get(key);
|
|
78
|
+
if (!set)
|
|
79
|
+
return;
|
|
80
|
+
set.delete(conn);
|
|
81
|
+
if (set.size === 0)
|
|
82
|
+
map.delete(key);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=connection-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-registry.js","sourceRoot":"","sources":["../../src/transport/connection-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type Logger } from '@mt-tl/tl';
|
|
2
|
+
import { Framing } from './framing.js';
|
|
3
|
+
import { type MsgIdState } from '../session/message-id.js';
|
|
4
|
+
import { InboundTracker } from '../session/inbound-tracker.js';
|
|
5
|
+
/**
|
|
6
|
+
* Per-connection state. Holds transport framing, the negotiated TL layer,
|
|
7
|
+
* auth-key/session binding (filled after the handshake and first encrypted
|
|
8
|
+
* message), and outgoing message-id/seq counters.
|
|
9
|
+
*/
|
|
10
|
+
export interface ConnectionCtx extends MsgIdState {
|
|
11
|
+
connectionId: number;
|
|
12
|
+
remoteAddress?: string;
|
|
13
|
+
apiLayer: number;
|
|
14
|
+
authKeyId?: bigint;
|
|
15
|
+
authKey?: Buffer;
|
|
16
|
+
sessionId?: bigint;
|
|
17
|
+
uniqueId?: bigint;
|
|
18
|
+
serverSalt?: bigint;
|
|
19
|
+
apiId?: number;
|
|
20
|
+
deviceModel?: string;
|
|
21
|
+
systemVersion?: string;
|
|
22
|
+
appVersion?: string;
|
|
23
|
+
systemLangCode?: string;
|
|
24
|
+
langCode?: string;
|
|
25
|
+
/** Bound subject (internal user id) once the auth key is authorized. */
|
|
26
|
+
subject?: string;
|
|
27
|
+
/** Set when the client wrapped a query in `invokeWithoutUpdates` — this
|
|
28
|
+
* connection is excluded from server-push delivery. */
|
|
29
|
+
noUpdates?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare class Connection {
|
|
32
|
+
private readonly transportSend;
|
|
33
|
+
private readonly transportClose;
|
|
34
|
+
readonly id: number;
|
|
35
|
+
/** Per-connection logger (carrier-scoped child); also passed to framing. */
|
|
36
|
+
readonly log: Logger;
|
|
37
|
+
readonly framing: Framing;
|
|
38
|
+
/** Inbound msg_id/seqno validation + received-message state (per session). */
|
|
39
|
+
readonly tracker: InboundTracker;
|
|
40
|
+
ctx: ConnectionCtx;
|
|
41
|
+
closed: boolean;
|
|
42
|
+
private tail;
|
|
43
|
+
/** Idle-disconnect window (ms) requested via `ping_delay_disconnect`; 0 = none. */
|
|
44
|
+
private disconnectMs;
|
|
45
|
+
private disconnectTimer?;
|
|
46
|
+
constructor(id: number, transportSend: (bytes: Buffer) => void, transportClose: () => void, remoteAddress?: string, defaultLayer?: number, log?: Logger);
|
|
47
|
+
/** Frame a fully-built MTProto packet (plaintext or encrypted) and send it. */
|
|
48
|
+
send(packet: Buffer): void;
|
|
49
|
+
nextMessageId(isNotification?: boolean): bigint;
|
|
50
|
+
nextSeqNo(contentRelated?: boolean): number;
|
|
51
|
+
/** Serialize async work per connection so messages are processed in order. */
|
|
52
|
+
enqueue(fn: () => void | Promise<void>): void;
|
|
53
|
+
/**
|
|
54
|
+
* Arm (or re-arm) the `ping_delay_disconnect` idle timer: close the connection
|
|
55
|
+
* after `delaySec` seconds of inactivity. A delay of 0 disarms it.
|
|
56
|
+
*/
|
|
57
|
+
armDisconnect(delaySec: number): void;
|
|
58
|
+
/** Reset the idle timer on activity. No-op unless armed via {@link armDisconnect}. */
|
|
59
|
+
resetDisconnect(): void;
|
|
60
|
+
close(): void;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/transport/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAA4B,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAE9D;;;;GAIG;AACH,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC7C,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAEhB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IAGnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB;2DACuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,qBAAa,UAAU;IAgBf,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAhBnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,4EAA4E;IAC5E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,iBAAuB;IACvC,GAAG,EAAE,aAAa,CAAA;IAClB,MAAM,UAAQ;IACd,OAAO,CAAC,IAAI,CAAmC;IAC/C,mFAAmF;IACnF,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,eAAe,CAAC,CAA+B;gBAGnD,EAAE,EAAE,MAAM,EACO,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACtC,cAAc,EAAE,MAAM,IAAI,EAC3C,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,SAAM,EAClB,GAAG,GAAE,MAAmB;IAc5B,+EAA+E;IAC/E,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK1B,aAAa,CAAC,cAAc,UAAQ,GAAG,MAAM;IAI7C,SAAS,CAAC,cAAc,UAAO,GAAG,MAAM;IAIxC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI7C;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKrC,sFAAsF;IACtF,eAAe,IAAI,IAAI;IAOvB,KAAK,IAAI,IAAI;CAMhB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { noopLogger } from '@mt-tl/tl';
|
|
2
|
+
import { Framing } from './framing.js';
|
|
3
|
+
import { nextMessageId, nextSeqNo } from '../session/message-id.js';
|
|
4
|
+
import { InboundTracker } from '../session/inbound-tracker.js';
|
|
5
|
+
export class Connection {
|
|
6
|
+
transportSend;
|
|
7
|
+
transportClose;
|
|
8
|
+
id;
|
|
9
|
+
/** Per-connection logger (carrier-scoped child); also passed to framing. */
|
|
10
|
+
log;
|
|
11
|
+
framing;
|
|
12
|
+
/** Inbound msg_id/seqno validation + received-message state (per session). */
|
|
13
|
+
tracker = new InboundTracker();
|
|
14
|
+
ctx;
|
|
15
|
+
closed = false;
|
|
16
|
+
tail = Promise.resolve();
|
|
17
|
+
/** Idle-disconnect window (ms) requested via `ping_delay_disconnect`; 0 = none. */
|
|
18
|
+
disconnectMs = 0;
|
|
19
|
+
disconnectTimer;
|
|
20
|
+
constructor(id, transportSend, transportClose, remoteAddress, defaultLayer = 204, log = noopLogger) {
|
|
21
|
+
this.transportSend = transportSend;
|
|
22
|
+
this.transportClose = transportClose;
|
|
23
|
+
this.id = id;
|
|
24
|
+
this.log = log;
|
|
25
|
+
this.framing = new Framing(log);
|
|
26
|
+
this.ctx = {
|
|
27
|
+
connectionId: id,
|
|
28
|
+
remoteAddress,
|
|
29
|
+
apiLayer: defaultLayer,
|
|
30
|
+
lastMessageId: null,
|
|
31
|
+
messageSeqNo: 0,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Frame a fully-built MTProto packet (plaintext or encrypted) and send it. */
|
|
35
|
+
send(packet) {
|
|
36
|
+
if (this.closed)
|
|
37
|
+
return;
|
|
38
|
+
this.transportSend(this.framing.frame(packet));
|
|
39
|
+
}
|
|
40
|
+
nextMessageId(isNotification = false) {
|
|
41
|
+
return nextMessageId(this.ctx, isNotification);
|
|
42
|
+
}
|
|
43
|
+
nextSeqNo(contentRelated = true) {
|
|
44
|
+
return nextSeqNo(this.ctx, contentRelated);
|
|
45
|
+
}
|
|
46
|
+
/** Serialize async work per connection so messages are processed in order. */
|
|
47
|
+
enqueue(fn) {
|
|
48
|
+
this.tail = this.tail.then(fn).catch(() => { });
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Arm (or re-arm) the `ping_delay_disconnect` idle timer: close the connection
|
|
52
|
+
* after `delaySec` seconds of inactivity. A delay of 0 disarms it.
|
|
53
|
+
*/
|
|
54
|
+
armDisconnect(delaySec) {
|
|
55
|
+
this.disconnectMs = Math.max(0, Math.floor(delaySec)) * 1000;
|
|
56
|
+
this.resetDisconnect();
|
|
57
|
+
}
|
|
58
|
+
/** Reset the idle timer on activity. No-op unless armed via {@link armDisconnect}. */
|
|
59
|
+
resetDisconnect() {
|
|
60
|
+
if (this.disconnectTimer)
|
|
61
|
+
clearTimeout(this.disconnectTimer);
|
|
62
|
+
if (!this.disconnectMs)
|
|
63
|
+
return;
|
|
64
|
+
this.disconnectTimer = setTimeout(() => this.close(), this.disconnectMs);
|
|
65
|
+
if (typeof this.disconnectTimer.unref === 'function')
|
|
66
|
+
this.disconnectTimer.unref();
|
|
67
|
+
}
|
|
68
|
+
close() {
|
|
69
|
+
if (this.closed)
|
|
70
|
+
return;
|
|
71
|
+
this.closed = true;
|
|
72
|
+
if (this.disconnectTimer)
|
|
73
|
+
clearTimeout(this.disconnectTimer);
|
|
74
|
+
this.transportClose();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/transport/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type Logger } from '@mt-tl/tl';
|
|
2
|
+
/**
|
|
3
|
+
* MTProto transport framing. The same four modes the existing server supports
|
|
4
|
+
* are delivered identically over TCP or inside binary WebSocket frames, so the
|
|
5
|
+
* gateway feeds raw bytes here regardless of carrier.
|
|
6
|
+
*
|
|
7
|
+
* Modes: abridged (0xef), intermediate (0xeeeeeeee), full, and obfuscated
|
|
8
|
+
* (a 64-byte AES-CTR header that wraps abridged/intermediate). Detection mirrors
|
|
9
|
+
* `server.js` exactly for wire-compatibility.
|
|
10
|
+
*/
|
|
11
|
+
export type InnerMode = 'abridged' | 'intermediate' | 'full';
|
|
12
|
+
export type Mode = InnerMode | 'obfuscated';
|
|
13
|
+
export declare class Framing {
|
|
14
|
+
private readonly log;
|
|
15
|
+
mode?: Mode;
|
|
16
|
+
private inner?;
|
|
17
|
+
/** Plaintext queue from which inner packets are read. */
|
|
18
|
+
private queue;
|
|
19
|
+
/** Pre-detection accumulation. */
|
|
20
|
+
private detectBuf;
|
|
21
|
+
private sequenceIn;
|
|
22
|
+
private sequenceOut;
|
|
23
|
+
private decryptor?;
|
|
24
|
+
private encryptor?;
|
|
25
|
+
constructor(log?: Logger);
|
|
26
|
+
/** Feed received bytes; returns any complete packets that became available. */
|
|
27
|
+
feed(chunk: Buffer): Buffer[];
|
|
28
|
+
/** Frame an outgoing packet for the negotiated mode. */
|
|
29
|
+
frame(packet: Buffer): Buffer;
|
|
30
|
+
private effectiveMode;
|
|
31
|
+
private detect;
|
|
32
|
+
private drain;
|
|
33
|
+
private readOne;
|
|
34
|
+
private readAbridged;
|
|
35
|
+
private readIntermediate;
|
|
36
|
+
private readFull;
|
|
37
|
+
private frameInner;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=framing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framing.d.ts","sourceRoot":"","sources":["../../src/transport/framing.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,WAAW,CAAA;AAKnD;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,cAAc,GAAG,MAAM,CAAA;AAC5D,MAAM,MAAM,IAAI,GAAG,SAAS,GAAG,YAAY,CAAA;AAQ3C,qBAAa,OAAO;IAYJ,OAAO,CAAC,QAAQ,CAAC,GAAG;IAXhC,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,OAAO,CAAC,KAAK,CAAC,CAAW;IACzB,yDAAyD;IACzD,OAAO,CAAC,KAAK,CAAkB;IAC/B,kCAAkC;IAClC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,SAAS,CAAC,CAAU;IAC5B,OAAO,CAAC,SAAS,CAAC,CAAU;gBAEC,GAAG,GAAE,MAAmB;IAErD,+EAA+E;IAC/E,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAY7B,wDAAwD;IACxD,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAM7B,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,MAAM;IA4Dd,OAAO,CAAC,KAAK;IAUb,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,UAAU;CAiCrB"}
|