@labostack/typebridge 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.
- package/README.md +62 -0
- package/dist/adapters/decorators.d.ts +11 -0
- package/dist/adapters/decorators.d.ts.map +1 -0
- package/dist/adapters/decorators.js +20 -0
- package/dist/adapters/decorators.js.map +1 -0
- package/dist/adapters/deepkit-adapter.d.ts +11 -0
- package/dist/adapters/deepkit-adapter.d.ts.map +1 -0
- package/dist/adapters/deepkit-adapter.js +39 -0
- package/dist/adapters/deepkit-adapter.js.map +1 -0
- package/dist/adapters/generic-adapter.d.ts +12 -0
- package/dist/adapters/generic-adapter.d.ts.map +1 -0
- package/dist/adapters/generic-adapter.js +28 -0
- package/dist/adapters/generic-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +5 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/nest-adapter.d.ts +14 -0
- package/dist/adapters/nest-adapter.d.ts.map +1 -0
- package/dist/adapters/nest-adapter.js +33 -0
- package/dist/adapters/nest-adapter.js.map +1 -0
- package/dist/adapters/tsed-adapter.d.ts +10 -0
- package/dist/adapters/tsed-adapter.d.ts.map +1 -0
- package/dist/adapters/tsed-adapter.js +31 -0
- package/dist/adapters/tsed-adapter.js.map +1 -0
- package/dist/autobarrel/index.d.ts +2 -0
- package/dist/autobarrel/index.d.ts.map +1 -0
- package/dist/autobarrel/index.js +2 -0
- package/dist/autobarrel/index.js.map +1 -0
- package/dist/autobarrel/scanner.d.ts +14 -0
- package/dist/autobarrel/scanner.d.ts.map +1 -0
- package/dist/autobarrel/scanner.js +93 -0
- package/dist/autobarrel/scanner.js.map +1 -0
- package/dist/bridge.d.ts +54 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +151 -0
- package/dist/bridge.js.map +1 -0
- package/dist/discovery/dns.d.ts +10 -0
- package/dist/discovery/dns.d.ts.map +1 -0
- package/dist/discovery/dns.js +19 -0
- package/dist/discovery/dns.js.map +1 -0
- package/dist/discovery/index.d.ts +4 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +4 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/mdns.d.ts +18 -0
- package/dist/discovery/mdns.d.ts.map +1 -0
- package/dist/discovery/mdns.js +49 -0
- package/dist/discovery/mdns.js.map +1 -0
- package/dist/discovery/resolver.d.ts +16 -0
- package/dist/discovery/resolver.d.ts.map +1 -0
- package/dist/discovery/resolver.js +36 -0
- package/dist/discovery/resolver.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/mesh/index.d.ts +2 -0
- package/dist/mesh/index.d.ts.map +1 -0
- package/dist/mesh/index.js +2 -0
- package/dist/mesh/index.js.map +1 -0
- package/dist/mesh/mesh-manager.d.ts +55 -0
- package/dist/mesh/mesh-manager.d.ts.map +1 -0
- package/dist/mesh/mesh-manager.js +179 -0
- package/dist/mesh/mesh-manager.js.map +1 -0
- package/dist/proxy/client-proxy.d.ts +20 -0
- package/dist/proxy/client-proxy.d.ts.map +1 -0
- package/dist/proxy/client-proxy.js +69 -0
- package/dist/proxy/client-proxy.js.map +1 -0
- package/dist/proxy/index.d.ts +2 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +2 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/reflection/extractor.d.ts +13 -0
- package/dist/reflection/extractor.d.ts.map +1 -0
- package/dist/reflection/extractor.js +62 -0
- package/dist/reflection/extractor.js.map +1 -0
- package/dist/reflection/index.d.ts +2 -0
- package/dist/reflection/index.d.ts.map +1 -0
- package/dist/reflection/index.js +2 -0
- package/dist/reflection/index.js.map +1 -0
- package/dist/registry/index.d.ts +3 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +2 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/method-registry.d.ts +56 -0
- package/dist/registry/method-registry.d.ts.map +1 -0
- package/dist/registry/method-registry.js +84 -0
- package/dist/registry/method-registry.js.map +1 -0
- package/dist/serialization/error-ext.d.ts +38 -0
- package/dist/serialization/error-ext.d.ts.map +1 -0
- package/dist/serialization/error-ext.js +76 -0
- package/dist/serialization/error-ext.js.map +1 -0
- package/dist/serialization/index.d.ts +4 -0
- package/dist/serialization/index.d.ts.map +1 -0
- package/dist/serialization/index.js +3 -0
- package/dist/serialization/index.js.map +1 -0
- package/dist/serialization/msgpack.d.ts +30 -0
- package/dist/serialization/msgpack.d.ts.map +1 -0
- package/dist/serialization/msgpack.js +76 -0
- package/dist/serialization/msgpack.js.map +1 -0
- package/dist/serialization/serializer.d.ts +15 -0
- package/dist/serialization/serializer.d.ts.map +1 -0
- package/dist/serialization/serializer.js +2 -0
- package/dist/serialization/serializer.js.map +1 -0
- package/dist/transport/client.d.ts +38 -0
- package/dist/transport/client.d.ts.map +1 -0
- package/dist/transport/client.js +57 -0
- package/dist/transport/client.js.map +1 -0
- package/dist/transport/connection.d.ts +57 -0
- package/dist/transport/connection.d.ts.map +1 -0
- package/dist/transport/connection.js +212 -0
- package/dist/transport/connection.js.map +1 -0
- package/dist/transport/constants.d.ts +2 -0
- package/dist/transport/constants.d.ts.map +1 -0
- package/dist/transport/constants.js +2 -0
- package/dist/transport/constants.js.map +1 -0
- package/dist/transport/framing.d.ts +54 -0
- package/dist/transport/framing.d.ts.map +1 -0
- package/dist/transport/framing.js +107 -0
- package/dist/transport/framing.js.map +1 -0
- package/dist/transport/index.d.ts +7 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +7 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/peer-manager.d.ts +67 -0
- package/dist/transport/peer-manager.d.ts.map +1 -0
- package/dist/transport/peer-manager.js +172 -0
- package/dist/transport/peer-manager.js.map +1 -0
- package/dist/transport/server.d.ts +37 -0
- package/dist/transport/server.d.ts.map +1 -0
- package/dist/transport/server.js +88 -0
- package/dist/transport/server.js.map +1 -0
- package/dist/types/adapter.d.ts +33 -0
- package/dist/types/adapter.d.ts.map +1 -0
- package/dist/types/adapter.js +2 -0
- package/dist/types/adapter.js.map +1 -0
- package/dist/types/descriptor.d.ts +35 -0
- package/dist/types/descriptor.d.ts.map +1 -0
- package/dist/types/descriptor.js +2 -0
- package/dist/types/descriptor.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/options.d.ts +55 -0
- package/dist/types/options.d.ts.map +1 -0
- package/dist/types/options.js +6 -0
- package/dist/types/options.js.map +1 -0
- package/dist/types/protocol.d.ts +94 -0
- package/dist/types/protocol.d.ts.map +1 -0
- package/dist/types/protocol.js +43 -0
- package/dist/types/protocol.js.map +1 -0
- package/dist/types/type-descriptor.d.ts +64 -0
- package/dist/types/type-descriptor.d.ts.map +1 -0
- package/dist/types/type-descriptor.js +2 -0
- package/dist/types/type-descriptor.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Error serialization/deserialization.
|
|
3
|
+
*
|
|
4
|
+
* Errors are fully serialized as-is:
|
|
5
|
+
* - name, message, stack (exact)
|
|
6
|
+
* - cause chains (recursive)
|
|
7
|
+
* - All enumerable custom properties (statusCode, details, etc.)
|
|
8
|
+
*
|
|
9
|
+
* The client receives the exact same error the server threw. Period.
|
|
10
|
+
*/
|
|
11
|
+
/** Marker to identify serialized Error objects in MessagePack payload */
|
|
12
|
+
export const ERROR_MARKER = "__typebridge_error__";
|
|
13
|
+
/**
|
|
14
|
+
* Serialize an Error object into a plain object that can be encoded by MessagePack.
|
|
15
|
+
* Recursively serializes `cause` chains and captures all enumerable properties.
|
|
16
|
+
*/
|
|
17
|
+
export function serializeError(error) {
|
|
18
|
+
if (!(error instanceof Error)) {
|
|
19
|
+
// Wrap non-Error throwables
|
|
20
|
+
return {
|
|
21
|
+
[ERROR_MARKER]: true,
|
|
22
|
+
name: "Error",
|
|
23
|
+
message: String(error),
|
|
24
|
+
stack: undefined,
|
|
25
|
+
properties: { originalValue: error },
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const serialized = {
|
|
29
|
+
[ERROR_MARKER]: true,
|
|
30
|
+
name: error.name,
|
|
31
|
+
message: error.message,
|
|
32
|
+
stack: error.stack,
|
|
33
|
+
properties: {},
|
|
34
|
+
};
|
|
35
|
+
// Recursively serialize cause chain
|
|
36
|
+
if (error.cause !== undefined) {
|
|
37
|
+
serialized.cause = serializeError(error.cause);
|
|
38
|
+
}
|
|
39
|
+
// Capture all enumerable properties (statusCode, details, code, etc.)
|
|
40
|
+
for (const key of Object.keys(error)) {
|
|
41
|
+
if (key !== "name" && key !== "message" && key !== "stack" && key !== "cause") {
|
|
42
|
+
serialized.properties[key] = error[key];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return serialized;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Deserialize a SerializedError back into an Error object.
|
|
49
|
+
* Reconstructs cause chains and restores all custom properties.
|
|
50
|
+
*/
|
|
51
|
+
export function deserializeError(data) {
|
|
52
|
+
const error = new Error(data.message);
|
|
53
|
+
error.name = data.name;
|
|
54
|
+
if (data.stack !== undefined) {
|
|
55
|
+
error.stack = data.stack;
|
|
56
|
+
}
|
|
57
|
+
// Restore cause chain
|
|
58
|
+
if (data.cause !== undefined) {
|
|
59
|
+
error.cause = deserializeError(data.cause);
|
|
60
|
+
}
|
|
61
|
+
// Restore all custom properties
|
|
62
|
+
for (const [key, value] of Object.entries(data.properties)) {
|
|
63
|
+
error[key] = value;
|
|
64
|
+
}
|
|
65
|
+
return error;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if a value is a serialized TypeBridge Error.
|
|
69
|
+
*/
|
|
70
|
+
export function isSerializedError(value) {
|
|
71
|
+
return (typeof value === "object" &&
|
|
72
|
+
value !== null &&
|
|
73
|
+
ERROR_MARKER in value &&
|
|
74
|
+
value[ERROR_MARKER] === true);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=error-ext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-ext.js","sourceRoot":"","sources":["../../src/serialization/error-ext.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AAcnD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,4BAA4B;QAC5B,OAAO;YACL,CAAC,YAAY,CAAC,EAAE,IAAI;YACpB,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;YACtB,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE;SACrC,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAoB;QAClC,CAAC,YAAY,CAAC,EAAE,IAAI;QACpB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,UAAU,EAAE,EAAE;KACf,CAAC;IAEF,oCAAoC;IACpC,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,UAAU,CAAC,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,sEAAsE;IACtE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YAC9E,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,GAAI,KAA4C,CAAC,GAAG,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAqB;IACpD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAEvB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC7B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAC3B,CAAC;IAED,sBAAsB;IACtB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC7B,KAAK,CAAC,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,gCAAgC;IAChC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1D,KAA4C,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC7D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,YAAY,IAAI,KAAK;QACpB,KAAiC,CAAC,YAAY,CAAC,KAAK,IAAI,CAC1D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/serialization/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,GACb,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/serialization/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,GACb,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Serializer } from "./serializer.js";
|
|
2
|
+
import { serializeError, deserializeError, isSerializedError, ERROR_MARKER } from "./error-ext.js";
|
|
3
|
+
/**
|
|
4
|
+
* MessagePack serializer using `msgpackr`.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Fast binary encode/decode (faster than JSON, smaller payloads)
|
|
8
|
+
* - Native Buffer/Uint8Array support (no base64)
|
|
9
|
+
* - Custom Error serialization (full passthrough of name, stack, cause, properties)
|
|
10
|
+
* - Low GC pressure via buffer pooling
|
|
11
|
+
*/
|
|
12
|
+
export declare class MsgPackSerializer implements Serializer {
|
|
13
|
+
private readonly packr;
|
|
14
|
+
readonly supportsStreaming = false;
|
|
15
|
+
constructor();
|
|
16
|
+
encode(value: unknown): Buffer;
|
|
17
|
+
decode<T = unknown>(buffer: Buffer): T;
|
|
18
|
+
/**
|
|
19
|
+
* Recursively prepare a value for MessagePack encoding.
|
|
20
|
+
* Converts Error objects to serialized form.
|
|
21
|
+
*/
|
|
22
|
+
private prepareForEncode;
|
|
23
|
+
/**
|
|
24
|
+
* Recursively restore decoded values.
|
|
25
|
+
* Converts serialized Error markers back into Error objects.
|
|
26
|
+
*/
|
|
27
|
+
private restoreAfterDecode;
|
|
28
|
+
}
|
|
29
|
+
export { serializeError, deserializeError, isSerializedError, ERROR_MARKER };
|
|
30
|
+
//# sourceMappingURL=msgpack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msgpack.d.ts","sourceRoot":"","sources":["../../src/serialization/msgpack.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACb,MAAM,gBAAgB,CAAC;AAExB;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,YAAW,UAAU;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B,QAAQ,CAAC,iBAAiB,SAAS;;IAanC,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAK9B,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC;IAKtC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAmB3B;AAGD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Packr } from "msgpackr";
|
|
2
|
+
import { serializeError, deserializeError, isSerializedError, ERROR_MARKER, } from "./error-ext.js";
|
|
3
|
+
/**
|
|
4
|
+
* MessagePack serializer using `msgpackr`.
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Fast binary encode/decode (faster than JSON, smaller payloads)
|
|
8
|
+
* - Native Buffer/Uint8Array support (no base64)
|
|
9
|
+
* - Custom Error serialization (full passthrough of name, stack, cause, properties)
|
|
10
|
+
* - Low GC pressure via buffer pooling
|
|
11
|
+
*/
|
|
12
|
+
export class MsgPackSerializer {
|
|
13
|
+
packr;
|
|
14
|
+
supportsStreaming = false;
|
|
15
|
+
constructor() {
|
|
16
|
+
this.packr = new Packr({
|
|
17
|
+
// Use standard msgpack structures for interoperability
|
|
18
|
+
useRecords: false,
|
|
19
|
+
// Encode Maps as objects
|
|
20
|
+
mapsAsObjects: true,
|
|
21
|
+
// Encode undefined as null for compatibility
|
|
22
|
+
encodeUndefinedAsNil: true,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
encode(value) {
|
|
26
|
+
const prepared = this.prepareForEncode(value);
|
|
27
|
+
return this.packr.pack(prepared);
|
|
28
|
+
}
|
|
29
|
+
decode(buffer) {
|
|
30
|
+
const raw = this.packr.unpack(buffer);
|
|
31
|
+
return this.restoreAfterDecode(raw);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Recursively prepare a value for MessagePack encoding.
|
|
35
|
+
* Converts Error objects to serialized form.
|
|
36
|
+
*/
|
|
37
|
+
prepareForEncode(value) {
|
|
38
|
+
if (value instanceof Error) {
|
|
39
|
+
return serializeError(value);
|
|
40
|
+
}
|
|
41
|
+
if (Array.isArray(value)) {
|
|
42
|
+
return value.map((item) => this.prepareForEncode(item));
|
|
43
|
+
}
|
|
44
|
+
if (value !== null && typeof value === "object" && !(value instanceof Buffer) && !(value instanceof Uint8Array)) {
|
|
45
|
+
const result = {};
|
|
46
|
+
for (const [key, val] of Object.entries(value)) {
|
|
47
|
+
result[key] = this.prepareForEncode(val);
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Recursively restore decoded values.
|
|
55
|
+
* Converts serialized Error markers back into Error objects.
|
|
56
|
+
*/
|
|
57
|
+
restoreAfterDecode(value) {
|
|
58
|
+
if (isSerializedError(value)) {
|
|
59
|
+
return deserializeError(value);
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(value)) {
|
|
62
|
+
return value.map((item) => this.restoreAfterDecode(item));
|
|
63
|
+
}
|
|
64
|
+
if (value !== null && typeof value === "object" && !(value instanceof Buffer) && !(value instanceof Uint8Array)) {
|
|
65
|
+
const result = {};
|
|
66
|
+
for (const [key, val] of Object.entries(value)) {
|
|
67
|
+
result[key] = this.restoreAfterDecode(val);
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Re-export error utilities for direct use
|
|
75
|
+
export { serializeError, deserializeError, isSerializedError, ERROR_MARKER };
|
|
76
|
+
//# sourceMappingURL=msgpack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msgpack.js","sourceRoot":"","sources":["../../src/serialization/msgpack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serializer interface — abstraction over the wire format.
|
|
3
|
+
*
|
|
4
|
+
* Default implementation uses MessagePack (msgpackr).
|
|
5
|
+
* Can be swapped for CBOR, Protobuf, or any other binary format.
|
|
6
|
+
*/
|
|
7
|
+
export interface Serializer {
|
|
8
|
+
/** Encode a value into a binary buffer */
|
|
9
|
+
encode(value: unknown): Buffer;
|
|
10
|
+
/** Decode a binary buffer back into a value */
|
|
11
|
+
decode<T = unknown>(buffer: Buffer): T;
|
|
12
|
+
/** Whether this serializer supports streaming encode/decode */
|
|
13
|
+
readonly supportsStreaming: boolean;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../../src/serialization/serializer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IAE/B,+CAA+C;IAC/C,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC;IAEvC,+DAA+D;IAC/D,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.js","sourceRoot":"","sources":["../../src/serialization/serializer.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Connection } from "./connection.js";
|
|
2
|
+
import type { Serializer } from "../serialization/serializer.js";
|
|
3
|
+
export interface TransportClientOptions {
|
|
4
|
+
/** Target host */
|
|
5
|
+
host: string;
|
|
6
|
+
/** Target port. Default: 4242 */
|
|
7
|
+
port?: number;
|
|
8
|
+
/** Serializer to use. Default: MsgPackSerializer */
|
|
9
|
+
serializer?: Serializer;
|
|
10
|
+
/** Request timeout in ms. Default: 30000 */
|
|
11
|
+
timeout?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* TCP transport client — connects to a remote TransportServer.
|
|
15
|
+
*/
|
|
16
|
+
export declare class TransportClient {
|
|
17
|
+
private connection;
|
|
18
|
+
private readonly serializer;
|
|
19
|
+
private readonly targetHost;
|
|
20
|
+
private readonly targetPort;
|
|
21
|
+
private readonly timeout;
|
|
22
|
+
constructor(options: TransportClientOptions);
|
|
23
|
+
/** The underlying connection (null if not connected) */
|
|
24
|
+
get conn(): Connection | null;
|
|
25
|
+
/**
|
|
26
|
+
* Connect to the remote server.
|
|
27
|
+
*/
|
|
28
|
+
connect(): Promise<Connection>;
|
|
29
|
+
/**
|
|
30
|
+
* Send an RPC request to the remote server.
|
|
31
|
+
*/
|
|
32
|
+
request(method: string, args: unknown[]): Promise<unknown>;
|
|
33
|
+
/**
|
|
34
|
+
* Close the connection.
|
|
35
|
+
*/
|
|
36
|
+
close(): void;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/transport/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAIjE,MAAM,WAAW,sBAAsB;IACrC,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,sBAAsB;IAO3C,wDAAwD;IACxD,IAAI,IAAI,IAAI,UAAU,GAAG,IAAI,CAE5B;IAED;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAgBpC;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAOhE;;OAEG;IACH,KAAK,IAAI,IAAI;CAMd"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { connect as netConnect } from "node:net";
|
|
2
|
+
import { Connection } from "./connection.js";
|
|
3
|
+
import { MsgPackSerializer } from "../serialization/msgpack.js";
|
|
4
|
+
import { DEFAULT_PORT } from "../types/options.js";
|
|
5
|
+
/**
|
|
6
|
+
* TCP transport client — connects to a remote TransportServer.
|
|
7
|
+
*/
|
|
8
|
+
export class TransportClient {
|
|
9
|
+
connection = null;
|
|
10
|
+
serializer;
|
|
11
|
+
targetHost;
|
|
12
|
+
targetPort;
|
|
13
|
+
timeout;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.serializer = options.serializer ?? new MsgPackSerializer();
|
|
16
|
+
this.targetHost = options.host;
|
|
17
|
+
this.targetPort = options.port ?? DEFAULT_PORT;
|
|
18
|
+
this.timeout = options.timeout ?? 30_000;
|
|
19
|
+
}
|
|
20
|
+
/** The underlying connection (null if not connected) */
|
|
21
|
+
get conn() {
|
|
22
|
+
return this.connection;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Connect to the remote server.
|
|
26
|
+
*/
|
|
27
|
+
async connect() {
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
const socket = netConnect({ host: this.targetHost, port: this.targetPort }, () => {
|
|
30
|
+
this.connection = new Connection(socket, this.serializer, this.timeout);
|
|
31
|
+
resolve(this.connection);
|
|
32
|
+
});
|
|
33
|
+
socket.on("error", (err) => {
|
|
34
|
+
reject(err);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Send an RPC request to the remote server.
|
|
40
|
+
*/
|
|
41
|
+
async request(method, args) {
|
|
42
|
+
if (!this.connection || !this.connection.isOpen) {
|
|
43
|
+
throw new Error("Not connected");
|
|
44
|
+
}
|
|
45
|
+
return this.connection.request(method, args);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Close the connection.
|
|
49
|
+
*/
|
|
50
|
+
close() {
|
|
51
|
+
if (this.connection) {
|
|
52
|
+
this.connection.close();
|
|
53
|
+
this.connection = null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/transport/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAe,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAanD;;GAEG;AACH,MAAM,OAAO,eAAe;IAClB,UAAU,GAAsB,IAAI,CAAC;IAC5B,UAAU,CAAa;IACvB,UAAU,CAAS;IACnB,UAAU,CAAS;IACnB,OAAO,CAAS;IAEjC,YAAY,OAA+B;QACzC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,iBAAiB,EAAE,CAAC;QAChE,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,IAAI,YAAY,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC;IAC3C,CAAC;IAED,wDAAwD;IACxD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,MAAM,GAAW,UAAU,CAC/B,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,EAChD,GAAG,EAAE;gBACH,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC3B,CAAC,CACF,CAAC;YAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACzB,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,IAAe;QAC3C,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type Socket } from "node:net";
|
|
2
|
+
import { EventEmitter } from "node:events";
|
|
3
|
+
import type { Serializer } from "../serialization/serializer.js";
|
|
4
|
+
/**
|
|
5
|
+
* Manages a single TCP connection — handles frame read/write,
|
|
6
|
+
* request multiplexing, and heartbeats.
|
|
7
|
+
*/
|
|
8
|
+
export declare class Connection extends EventEmitter {
|
|
9
|
+
private readonly socket;
|
|
10
|
+
private readonly serializer;
|
|
11
|
+
private readonly timeout;
|
|
12
|
+
private readonly frameReader;
|
|
13
|
+
private readonly pendingRequests;
|
|
14
|
+
private nextRequestId;
|
|
15
|
+
private closed;
|
|
16
|
+
constructor(socket: Socket, serializer: Serializer, timeout?: number);
|
|
17
|
+
/** Whether this connection is still open */
|
|
18
|
+
get isOpen(): boolean;
|
|
19
|
+
/** Whether this connection is closed */
|
|
20
|
+
get isClosed(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Send an RPC request and wait for the response.
|
|
23
|
+
* Returns a Promise that resolves with the response value or rejects with a remote error.
|
|
24
|
+
*/
|
|
25
|
+
request(method: string, args: unknown[]): Promise<unknown>;
|
|
26
|
+
/**
|
|
27
|
+
* Send a response frame for a given request ID.
|
|
28
|
+
*/
|
|
29
|
+
sendResponse(requestId: number, result: unknown): void;
|
|
30
|
+
/**
|
|
31
|
+
* Send an error response frame for a given request ID.
|
|
32
|
+
*/
|
|
33
|
+
sendError(requestId: number, error: unknown): void;
|
|
34
|
+
/**
|
|
35
|
+
* Send a handshake frame.
|
|
36
|
+
*/
|
|
37
|
+
sendHandshake(data: unknown): void;
|
|
38
|
+
/**
|
|
39
|
+
* Send a handshake acknowledgment frame.
|
|
40
|
+
*/
|
|
41
|
+
sendHandshakeAck(data: unknown): void;
|
|
42
|
+
/**
|
|
43
|
+
* Send a heartbeat frame.
|
|
44
|
+
*/
|
|
45
|
+
sendHeartbeat(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Close the connection gracefully.
|
|
48
|
+
*/
|
|
49
|
+
close(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Destroy the connection immediately.
|
|
52
|
+
*/
|
|
53
|
+
destroy(): void;
|
|
54
|
+
private sendFrame;
|
|
55
|
+
private handleFrame;
|
|
56
|
+
}
|
|
57
|
+
//# 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,EAAE,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAEjE;;;GAGG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAWxC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAZ1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAI3B;IACL,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,MAAM,CAAS;gBAGJ,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,MAAe;IAiC3C,4CAA4C;IAC5C,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,wCAAwC;IACxC,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;OAGG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IA0BhE;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAWtD;;OAEG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAWlD;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAWlC;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAWrC;;OAEG;IACH,aAAa,IAAI,IAAI;IAUrB;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,WAAW;CAmDpB"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import { FrameReader, encodeFrame } from "./framing.js";
|
|
3
|
+
import { PROTOCOL_VERSION, MessageType, FrameFlags } from "./constants.js";
|
|
4
|
+
/**
|
|
5
|
+
* Manages a single TCP connection — handles frame read/write,
|
|
6
|
+
* request multiplexing, and heartbeats.
|
|
7
|
+
*/
|
|
8
|
+
export class Connection extends EventEmitter {
|
|
9
|
+
socket;
|
|
10
|
+
serializer;
|
|
11
|
+
timeout;
|
|
12
|
+
frameReader = new FrameReader();
|
|
13
|
+
pendingRequests = new Map();
|
|
14
|
+
nextRequestId = 1;
|
|
15
|
+
closed = false;
|
|
16
|
+
constructor(socket, serializer, timeout = 30_000) {
|
|
17
|
+
super();
|
|
18
|
+
this.socket = socket;
|
|
19
|
+
this.serializer = serializer;
|
|
20
|
+
this.timeout = timeout;
|
|
21
|
+
socket.on("data", (data) => {
|
|
22
|
+
try {
|
|
23
|
+
const frames = this.frameReader.feed(data);
|
|
24
|
+
for (const frame of frames) {
|
|
25
|
+
this.handleFrame(frame);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
this.emit("error", err);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
socket.on("close", () => {
|
|
33
|
+
this.closed = true;
|
|
34
|
+
// Reject all pending requests
|
|
35
|
+
for (const [id, pending] of this.pendingRequests) {
|
|
36
|
+
clearTimeout(pending.timer);
|
|
37
|
+
pending.reject(new Error("Connection closed"));
|
|
38
|
+
this.pendingRequests.delete(id);
|
|
39
|
+
}
|
|
40
|
+
this.emit("close");
|
|
41
|
+
});
|
|
42
|
+
socket.on("error", (err) => {
|
|
43
|
+
// Suppress ECONNRESET when connection is already closed (normal shutdown)
|
|
44
|
+
if (this.closed && err.code === "ECONNRESET")
|
|
45
|
+
return;
|
|
46
|
+
this.emit("error", err);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Whether this connection is still open */
|
|
50
|
+
get isOpen() {
|
|
51
|
+
return !this.closed && !this.socket.destroyed;
|
|
52
|
+
}
|
|
53
|
+
/** Whether this connection is closed */
|
|
54
|
+
get isClosed() {
|
|
55
|
+
return this.closed || this.socket.destroyed;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Send an RPC request and wait for the response.
|
|
59
|
+
* Returns a Promise that resolves with the response value or rejects with a remote error.
|
|
60
|
+
*/
|
|
61
|
+
async request(method, args) {
|
|
62
|
+
if (!this.isOpen) {
|
|
63
|
+
throw new Error("Connection is closed");
|
|
64
|
+
}
|
|
65
|
+
const requestId = this.nextRequestId++;
|
|
66
|
+
const payload = this.serializer.encode({ method, args });
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
const timer = setTimeout(() => {
|
|
69
|
+
this.pendingRequests.delete(requestId);
|
|
70
|
+
reject(new Error(`Request timeout after ${this.timeout}ms: ${method}`));
|
|
71
|
+
}, this.timeout);
|
|
72
|
+
this.pendingRequests.set(requestId, { resolve, reject, timer });
|
|
73
|
+
this.sendFrame({
|
|
74
|
+
version: PROTOCOL_VERSION,
|
|
75
|
+
flags: FrameFlags.None,
|
|
76
|
+
requestId,
|
|
77
|
+
messageType: MessageType.Request,
|
|
78
|
+
payload,
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Send a response frame for a given request ID.
|
|
84
|
+
*/
|
|
85
|
+
sendResponse(requestId, result) {
|
|
86
|
+
const payload = this.serializer.encode({ result });
|
|
87
|
+
this.sendFrame({
|
|
88
|
+
version: PROTOCOL_VERSION,
|
|
89
|
+
flags: FrameFlags.None,
|
|
90
|
+
requestId,
|
|
91
|
+
messageType: MessageType.Response,
|
|
92
|
+
payload,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Send an error response frame for a given request ID.
|
|
97
|
+
*/
|
|
98
|
+
sendError(requestId, error) {
|
|
99
|
+
const payload = this.serializer.encode({ error });
|
|
100
|
+
this.sendFrame({
|
|
101
|
+
version: PROTOCOL_VERSION,
|
|
102
|
+
flags: FrameFlags.None,
|
|
103
|
+
requestId,
|
|
104
|
+
messageType: MessageType.Error,
|
|
105
|
+
payload,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Send a handshake frame.
|
|
110
|
+
*/
|
|
111
|
+
sendHandshake(data) {
|
|
112
|
+
const payload = this.serializer.encode(data);
|
|
113
|
+
this.sendFrame({
|
|
114
|
+
version: PROTOCOL_VERSION,
|
|
115
|
+
flags: FrameFlags.None,
|
|
116
|
+
requestId: 0,
|
|
117
|
+
messageType: MessageType.Handshake,
|
|
118
|
+
payload,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Send a handshake acknowledgment frame.
|
|
123
|
+
*/
|
|
124
|
+
sendHandshakeAck(data) {
|
|
125
|
+
const payload = this.serializer.encode(data);
|
|
126
|
+
this.sendFrame({
|
|
127
|
+
version: PROTOCOL_VERSION,
|
|
128
|
+
flags: FrameFlags.None,
|
|
129
|
+
requestId: 0,
|
|
130
|
+
messageType: MessageType.HandshakeAck,
|
|
131
|
+
payload,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Send a heartbeat frame.
|
|
136
|
+
*/
|
|
137
|
+
sendHeartbeat() {
|
|
138
|
+
this.sendFrame({
|
|
139
|
+
version: PROTOCOL_VERSION,
|
|
140
|
+
flags: FrameFlags.None,
|
|
141
|
+
requestId: 0,
|
|
142
|
+
messageType: MessageType.Heartbeat,
|
|
143
|
+
payload: Buffer.alloc(0),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Close the connection gracefully.
|
|
148
|
+
*/
|
|
149
|
+
close() {
|
|
150
|
+
this.closed = true;
|
|
151
|
+
this.socket.end();
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Destroy the connection immediately.
|
|
155
|
+
*/
|
|
156
|
+
destroy() {
|
|
157
|
+
this.closed = true;
|
|
158
|
+
this.socket.destroy();
|
|
159
|
+
}
|
|
160
|
+
sendFrame(frame) {
|
|
161
|
+
if (!this.isOpen)
|
|
162
|
+
return;
|
|
163
|
+
const encoded = encodeFrame(frame);
|
|
164
|
+
this.socket.write(encoded);
|
|
165
|
+
}
|
|
166
|
+
handleFrame(frame) {
|
|
167
|
+
switch (frame.messageType) {
|
|
168
|
+
case MessageType.Response: {
|
|
169
|
+
const pending = this.pendingRequests.get(frame.requestId);
|
|
170
|
+
if (pending) {
|
|
171
|
+
clearTimeout(pending.timer);
|
|
172
|
+
this.pendingRequests.delete(frame.requestId);
|
|
173
|
+
const { result } = this.serializer.decode(frame.payload);
|
|
174
|
+
pending.resolve(result);
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
case MessageType.Error: {
|
|
179
|
+
const pending = this.pendingRequests.get(frame.requestId);
|
|
180
|
+
if (pending) {
|
|
181
|
+
clearTimeout(pending.timer);
|
|
182
|
+
this.pendingRequests.delete(frame.requestId);
|
|
183
|
+
const { error } = this.serializer.decode(frame.payload);
|
|
184
|
+
pending.reject(error instanceof Error ? error : new Error(String(error)));
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
case MessageType.Request: {
|
|
189
|
+
const data = this.serializer.decode(frame.payload);
|
|
190
|
+
this.emit("request", frame.requestId, data.method, data.args);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
case MessageType.Handshake: {
|
|
194
|
+
const data = this.serializer.decode(frame.payload);
|
|
195
|
+
this.emit("handshake", data);
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
case MessageType.HandshakeAck: {
|
|
199
|
+
const data = this.serializer.decode(frame.payload);
|
|
200
|
+
this.emit("handshake-ack", data);
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
case MessageType.Heartbeat: {
|
|
204
|
+
this.emit("heartbeat");
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
default:
|
|
208
|
+
this.emit("error", new Error(`Unknown message type: ${frame.messageType}`));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# 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 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/transport/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,UAAU,GACX,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/transport/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,UAAU,GACX,MAAM,sBAAsB,CAAC"}
|