@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.
Files changed (158) hide show
  1. package/README.md +62 -0
  2. package/dist/adapters/decorators.d.ts +11 -0
  3. package/dist/adapters/decorators.d.ts.map +1 -0
  4. package/dist/adapters/decorators.js +20 -0
  5. package/dist/adapters/decorators.js.map +1 -0
  6. package/dist/adapters/deepkit-adapter.d.ts +11 -0
  7. package/dist/adapters/deepkit-adapter.d.ts.map +1 -0
  8. package/dist/adapters/deepkit-adapter.js +39 -0
  9. package/dist/adapters/deepkit-adapter.js.map +1 -0
  10. package/dist/adapters/generic-adapter.d.ts +12 -0
  11. package/dist/adapters/generic-adapter.d.ts.map +1 -0
  12. package/dist/adapters/generic-adapter.js +28 -0
  13. package/dist/adapters/generic-adapter.js.map +1 -0
  14. package/dist/adapters/index.d.ts +5 -0
  15. package/dist/adapters/index.d.ts.map +1 -0
  16. package/dist/adapters/index.js +5 -0
  17. package/dist/adapters/index.js.map +1 -0
  18. package/dist/adapters/nest-adapter.d.ts +14 -0
  19. package/dist/adapters/nest-adapter.d.ts.map +1 -0
  20. package/dist/adapters/nest-adapter.js +33 -0
  21. package/dist/adapters/nest-adapter.js.map +1 -0
  22. package/dist/adapters/tsed-adapter.d.ts +10 -0
  23. package/dist/adapters/tsed-adapter.d.ts.map +1 -0
  24. package/dist/adapters/tsed-adapter.js +31 -0
  25. package/dist/adapters/tsed-adapter.js.map +1 -0
  26. package/dist/autobarrel/index.d.ts +2 -0
  27. package/dist/autobarrel/index.d.ts.map +1 -0
  28. package/dist/autobarrel/index.js +2 -0
  29. package/dist/autobarrel/index.js.map +1 -0
  30. package/dist/autobarrel/scanner.d.ts +14 -0
  31. package/dist/autobarrel/scanner.d.ts.map +1 -0
  32. package/dist/autobarrel/scanner.js +93 -0
  33. package/dist/autobarrel/scanner.js.map +1 -0
  34. package/dist/bridge.d.ts +54 -0
  35. package/dist/bridge.d.ts.map +1 -0
  36. package/dist/bridge.js +151 -0
  37. package/dist/bridge.js.map +1 -0
  38. package/dist/discovery/dns.d.ts +10 -0
  39. package/dist/discovery/dns.d.ts.map +1 -0
  40. package/dist/discovery/dns.js +19 -0
  41. package/dist/discovery/dns.js.map +1 -0
  42. package/dist/discovery/index.d.ts +4 -0
  43. package/dist/discovery/index.d.ts.map +1 -0
  44. package/dist/discovery/index.js +4 -0
  45. package/dist/discovery/index.js.map +1 -0
  46. package/dist/discovery/mdns.d.ts +18 -0
  47. package/dist/discovery/mdns.d.ts.map +1 -0
  48. package/dist/discovery/mdns.js +49 -0
  49. package/dist/discovery/mdns.js.map +1 -0
  50. package/dist/discovery/resolver.d.ts +16 -0
  51. package/dist/discovery/resolver.d.ts.map +1 -0
  52. package/dist/discovery/resolver.js +36 -0
  53. package/dist/discovery/resolver.js.map +1 -0
  54. package/dist/index.d.ts +21 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +19 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/mesh/index.d.ts +2 -0
  59. package/dist/mesh/index.d.ts.map +1 -0
  60. package/dist/mesh/index.js +2 -0
  61. package/dist/mesh/index.js.map +1 -0
  62. package/dist/mesh/mesh-manager.d.ts +55 -0
  63. package/dist/mesh/mesh-manager.d.ts.map +1 -0
  64. package/dist/mesh/mesh-manager.js +179 -0
  65. package/dist/mesh/mesh-manager.js.map +1 -0
  66. package/dist/proxy/client-proxy.d.ts +20 -0
  67. package/dist/proxy/client-proxy.d.ts.map +1 -0
  68. package/dist/proxy/client-proxy.js +69 -0
  69. package/dist/proxy/client-proxy.js.map +1 -0
  70. package/dist/proxy/index.d.ts +2 -0
  71. package/dist/proxy/index.d.ts.map +1 -0
  72. package/dist/proxy/index.js +2 -0
  73. package/dist/proxy/index.js.map +1 -0
  74. package/dist/reflection/extractor.d.ts +13 -0
  75. package/dist/reflection/extractor.d.ts.map +1 -0
  76. package/dist/reflection/extractor.js +62 -0
  77. package/dist/reflection/extractor.js.map +1 -0
  78. package/dist/reflection/index.d.ts +2 -0
  79. package/dist/reflection/index.d.ts.map +1 -0
  80. package/dist/reflection/index.js +2 -0
  81. package/dist/reflection/index.js.map +1 -0
  82. package/dist/registry/index.d.ts +3 -0
  83. package/dist/registry/index.d.ts.map +1 -0
  84. package/dist/registry/index.js +2 -0
  85. package/dist/registry/index.js.map +1 -0
  86. package/dist/registry/method-registry.d.ts +56 -0
  87. package/dist/registry/method-registry.d.ts.map +1 -0
  88. package/dist/registry/method-registry.js +84 -0
  89. package/dist/registry/method-registry.js.map +1 -0
  90. package/dist/serialization/error-ext.d.ts +38 -0
  91. package/dist/serialization/error-ext.d.ts.map +1 -0
  92. package/dist/serialization/error-ext.js +76 -0
  93. package/dist/serialization/error-ext.js.map +1 -0
  94. package/dist/serialization/index.d.ts +4 -0
  95. package/dist/serialization/index.d.ts.map +1 -0
  96. package/dist/serialization/index.js +3 -0
  97. package/dist/serialization/index.js.map +1 -0
  98. package/dist/serialization/msgpack.d.ts +30 -0
  99. package/dist/serialization/msgpack.d.ts.map +1 -0
  100. package/dist/serialization/msgpack.js +76 -0
  101. package/dist/serialization/msgpack.js.map +1 -0
  102. package/dist/serialization/serializer.d.ts +15 -0
  103. package/dist/serialization/serializer.d.ts.map +1 -0
  104. package/dist/serialization/serializer.js +2 -0
  105. package/dist/serialization/serializer.js.map +1 -0
  106. package/dist/transport/client.d.ts +38 -0
  107. package/dist/transport/client.d.ts.map +1 -0
  108. package/dist/transport/client.js +57 -0
  109. package/dist/transport/client.js.map +1 -0
  110. package/dist/transport/connection.d.ts +57 -0
  111. package/dist/transport/connection.d.ts.map +1 -0
  112. package/dist/transport/connection.js +212 -0
  113. package/dist/transport/connection.js.map +1 -0
  114. package/dist/transport/constants.d.ts +2 -0
  115. package/dist/transport/constants.d.ts.map +1 -0
  116. package/dist/transport/constants.js +2 -0
  117. package/dist/transport/constants.js.map +1 -0
  118. package/dist/transport/framing.d.ts +54 -0
  119. package/dist/transport/framing.d.ts.map +1 -0
  120. package/dist/transport/framing.js +107 -0
  121. package/dist/transport/framing.js.map +1 -0
  122. package/dist/transport/index.d.ts +7 -0
  123. package/dist/transport/index.d.ts.map +1 -0
  124. package/dist/transport/index.js +7 -0
  125. package/dist/transport/index.js.map +1 -0
  126. package/dist/transport/peer-manager.d.ts +67 -0
  127. package/dist/transport/peer-manager.d.ts.map +1 -0
  128. package/dist/transport/peer-manager.js +172 -0
  129. package/dist/transport/peer-manager.js.map +1 -0
  130. package/dist/transport/server.d.ts +37 -0
  131. package/dist/transport/server.d.ts.map +1 -0
  132. package/dist/transport/server.js +88 -0
  133. package/dist/transport/server.js.map +1 -0
  134. package/dist/types/adapter.d.ts +33 -0
  135. package/dist/types/adapter.d.ts.map +1 -0
  136. package/dist/types/adapter.js +2 -0
  137. package/dist/types/adapter.js.map +1 -0
  138. package/dist/types/descriptor.d.ts +35 -0
  139. package/dist/types/descriptor.d.ts.map +1 -0
  140. package/dist/types/descriptor.js +2 -0
  141. package/dist/types/descriptor.js.map +1 -0
  142. package/dist/types/index.d.ts +8 -0
  143. package/dist/types/index.d.ts.map +1 -0
  144. package/dist/types/index.js +3 -0
  145. package/dist/types/index.js.map +1 -0
  146. package/dist/types/options.d.ts +55 -0
  147. package/dist/types/options.d.ts.map +1 -0
  148. package/dist/types/options.js +6 -0
  149. package/dist/types/options.js.map +1 -0
  150. package/dist/types/protocol.d.ts +94 -0
  151. package/dist/types/protocol.d.ts.map +1 -0
  152. package/dist/types/protocol.js +43 -0
  153. package/dist/types/protocol.js.map +1 -0
  154. package/dist/types/type-descriptor.d.ts +64 -0
  155. package/dist/types/type-descriptor.d.ts.map +1 -0
  156. package/dist/types/type-descriptor.js +2 -0
  157. package/dist/types/type-descriptor.js.map +1 -0
  158. package/package.json +41 -0
@@ -0,0 +1,179 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { TransportClient } from "../transport/client.js";
3
+ /**
4
+ * MeshManager — automatic peer discovery, connection, and controller routing.
5
+ *
6
+ * Each TypeBridge node has a MeshManager that:
7
+ * 1. Browses for other nodes via mDNS
8
+ * 2. Auto-connects and exchanges catalogs
9
+ * 3. Maintains a routing table: controllerName → Connection
10
+ * 4. Routes method calls to the right peer
11
+ */
12
+ export class MeshManager extends EventEmitter {
13
+ localName;
14
+ localRegistry;
15
+ /** peerName → Connection */
16
+ peers = new Map();
17
+ /** controllerName → peerName */
18
+ routes = new Map();
19
+ /** Clients we created (for cleanup) */
20
+ clients = [];
21
+ /** mDNS browser stop handle */
22
+ stopBrowsing = null;
23
+ constructor(localName, localRegistry) {
24
+ super();
25
+ this.localName = localName;
26
+ this.localRegistry = localRegistry;
27
+ }
28
+ /**
29
+ * Start browsing for other TypeBridge nodes via mDNS.
30
+ */
31
+ async startBrowsing() {
32
+ try {
33
+ const bonjourModule = await import("bonjour-service");
34
+ const Bonjour = bonjourModule.default ?? bonjourModule;
35
+ const bonjour = typeof Bonjour === "function" ? new Bonjour() : Bonjour;
36
+ const browser = bonjour.find({ type: "typebridge" });
37
+ browser.on("up", (service) => {
38
+ // Skip self
39
+ if (service.name === this.localName)
40
+ return;
41
+ // Skip already connected
42
+ if (this.peers.has(service.name))
43
+ return;
44
+ const host = service.addresses?.[0] ?? service.host ?? "127.0.0.1";
45
+ const port = service.port;
46
+ this.connectToPeer(service.name, host, port).catch(() => {
47
+ // Connection failed — will retry on next mDNS event
48
+ });
49
+ });
50
+ this.stopBrowsing = () => {
51
+ browser.stop();
52
+ bonjour.destroy();
53
+ };
54
+ }
55
+ catch {
56
+ // mDNS not available — that's fine, peers can still connect to us
57
+ }
58
+ }
59
+ /**
60
+ * Connect to a discovered peer, exchange catalogs.
61
+ */
62
+ async connectToPeer(name, host, port) {
63
+ if (this.peers.has(name))
64
+ return; // already connected
65
+ const client = new TransportClient({ host, port });
66
+ this.clients.push(client);
67
+ const connection = await client.connect();
68
+ // Send handshake WITH our catalog
69
+ connection.sendHandshake({
70
+ name: this.localName,
71
+ version: 1,
72
+ catalog: this.localRegistry.toCatalog(),
73
+ });
74
+ // Wait for handshake ack with their catalog
75
+ const peerCatalog = await new Promise((resolve, reject) => {
76
+ const timer = setTimeout(() => reject(new Error("Handshake timeout")), 10_000);
77
+ connection.on("handshake-ack", (data) => {
78
+ clearTimeout(timer);
79
+ resolve(data.catalog ?? {});
80
+ });
81
+ });
82
+ // Register the peer
83
+ this.registerPeer(name, connection, peerCatalog);
84
+ }
85
+ /**
86
+ * Register an incoming peer (called from server-side handshake handler).
87
+ */
88
+ registerIncomingPeer(name, connection, catalog) {
89
+ if (this.peers.has(name))
90
+ return; // already connected
91
+ this.registerPeer(name, connection, catalog);
92
+ }
93
+ /**
94
+ * Register a peer and its controllers in the routing table.
95
+ */
96
+ registerPeer(name, connection, catalog) {
97
+ this.peers.set(name, connection);
98
+ // Build routing table: controllerName → peerName
99
+ for (const controllerName of Object.keys(catalog)) {
100
+ this.routes.set(controllerName, name);
101
+ }
102
+ // Wire incoming requests (bidirectional — peer calls our controllers)
103
+ connection.on("request", async (reqId, method, args) => {
104
+ try {
105
+ const [controllerName, methodName] = method.split(".");
106
+ if (!controllerName || !methodName) {
107
+ throw new Error(`Invalid method format: "${method}"`);
108
+ }
109
+ const result = await this.localRegistry.invoke(controllerName, methodName, args);
110
+ connection.sendResponse(reqId, result);
111
+ }
112
+ catch (error) {
113
+ connection.sendError(reqId, error);
114
+ }
115
+ });
116
+ // Handle disconnection — remove from routing table
117
+ connection.on("close", () => {
118
+ this.peers.delete(name);
119
+ for (const [ctrl, peer] of this.routes) {
120
+ if (peer === name)
121
+ this.routes.delete(ctrl);
122
+ }
123
+ });
124
+ // Notify waiters that a new peer is available
125
+ this.emit("peer-available", name);
126
+ }
127
+ /**
128
+ * Get the connection for a controller.
129
+ * If the controller isn't found yet, waits for discovery (with timeout).
130
+ */
131
+ async getConnection(controllerName, timeout = 10_000) {
132
+ // Already known?
133
+ const peerName = this.routes.get(controllerName);
134
+ if (peerName) {
135
+ const conn = this.peers.get(peerName);
136
+ if (conn && conn.isOpen)
137
+ return conn;
138
+ }
139
+ // Wait for a peer with this controller to appear
140
+ return new Promise((resolve, reject) => {
141
+ const timer = setTimeout(() => {
142
+ this.off("peer-available", check);
143
+ reject(new Error(`Controller "${controllerName}" not found on any peer (timeout ${timeout}ms). ` +
144
+ `Make sure the service exposing it is running.`));
145
+ }, timeout);
146
+ const check = () => {
147
+ const peerName = this.routes.get(controllerName);
148
+ if (peerName) {
149
+ const conn = this.peers.get(peerName);
150
+ if (conn && conn.isOpen) {
151
+ clearTimeout(timer);
152
+ this.off("peer-available", check);
153
+ resolve(conn);
154
+ }
155
+ }
156
+ };
157
+ this.on("peer-available", check);
158
+ });
159
+ }
160
+ /**
161
+ * Check if a controller is available on any peer.
162
+ */
163
+ hasController(controllerName) {
164
+ return this.routes.has(controllerName);
165
+ }
166
+ /**
167
+ * Close all peer connections and stop browsing.
168
+ */
169
+ async close() {
170
+ this.stopBrowsing?.();
171
+ for (const client of this.clients) {
172
+ client.close();
173
+ }
174
+ this.clients = [];
175
+ this.peers.clear();
176
+ this.routes.clear();
177
+ }
178
+ }
179
+ //# sourceMappingURL=mesh-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-manager.js","sourceRoot":"","sources":["../../src/mesh/mesh-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAIzD;;;;;;;;GAQG;AACH,MAAM,OAAO,WAAY,SAAQ,YAAY;IAWxB;IACA;IAXnB,4BAA4B;IACpB,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC9C,gCAAgC;IACxB,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,uCAAuC;IAC/B,OAAO,GAAsB,EAAE,CAAC;IACxC,+BAA+B;IACvB,YAAY,GAAwB,IAAI,CAAC;IAEjD,YACmB,SAAiB,EACjB,aAA6B;QAE9C,KAAK,EAAE,CAAC;QAHS,cAAS,GAAT,SAAS,CAAQ;QACjB,kBAAa,GAAb,aAAa,CAAgB;IAGhD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,aAAa,CAAC;YACvD,MAAM,OAAO,GAAG,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,IAAK,OAAe,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YAEjF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;YAErD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,OAAY,EAAE,EAAE;gBAChC,YAAY;gBACZ,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS;oBAAE,OAAO;gBAC5C,yBAAyB;gBACzB,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;oBAAE,OAAO;gBAEzC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;gBACnE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBAE1B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;oBACtD,oDAAoD;gBACtD,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,YAAY,GAAG,GAAG,EAAE;gBACvB,OAAO,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,CAAC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,IAAY,EAAE,IAAY;QAC1D,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,oBAAoB;QAEtD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE1B,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QAE1C,kCAAkC;QAClC,UAAU,CAAC,aAAa,CAAC;YACvB,IAAI,EAAE,IAAI,CAAC,SAAS;YACpB,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;SACxC,CAAC,CAAC;QAEH,4CAA4C;QAC5C,MAAM,WAAW,GAAG,MAAM,IAAI,OAAO,CAAuC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC9F,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YAC/E,UAAU,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,IAAS,EAAE,EAAE;gBAC3C,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YAC9B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,oBAAoB;QACpB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,oBAAoB,CAClB,IAAY,EACZ,UAAsB,EACtB,OAA6C;QAE7C,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,oBAAoB;QACtD,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACK,YAAY,CAClB,IAAY,EACZ,UAAsB,EACtB,OAA6C;QAE7C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAEjC,iDAAiD;QACjD,KAAK,MAAM,cAAc,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACxC,CAAC;QAED,sEAAsE;QACtE,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,KAAa,EAAE,MAAc,EAAE,IAAe,EAAE,EAAE;YAChF,IAAI,CAAC;gBACH,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACvD,IAAI,CAAC,cAAc,IAAI,CAAC,UAAU,EAAE,CAAC;oBACnC,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,GAAG,CAAC,CAAC;gBACxD,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;gBACjF,UAAU,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,UAAU,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACrC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,mDAAmD;QACnD,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACxB,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACvC,IAAI,IAAI,KAAK,IAAI;oBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,8CAA8C;QAC9C,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa,CAAC,cAAsB,EAAE,OAAO,GAAG,MAAM;QAC1D,iBAAiB;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACjD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACtC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;QACvC,CAAC;QAED,iDAAiD;QACjD,OAAO,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACjD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;gBAClC,MAAM,CAAC,IAAI,KAAK,CACd,eAAe,cAAc,oCAAoC,OAAO,OAAO;oBAC/E,+CAA+C,CAChD,CAAC,CAAC;YACL,CAAC,EAAE,OAAO,CAAC,CAAC;YAEZ,MAAM,KAAK,GAAG,GAAG,EAAE;gBACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBACjD,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;oBACtC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;wBACxB,YAAY,CAAC,KAAK,CAAC,CAAC;wBACpB,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;wBAClC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAChB,CAAC;gBACH,CAAC;YACH,CAAC,CAAC;YAEF,IAAI,CAAC,EAAE,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,cAAsB;QAClC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACtB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ import type { MethodRegistry } from "../registry/method-registry.js";
2
+ import type { MeshManager } from "../mesh/mesh-manager.js";
3
+ /**
4
+ * Create a smart mesh proxy.
5
+ *
6
+ * This proxy routes method calls to the right place:
7
+ * - Local controllers → invoke directly via MethodRegistry
8
+ * - Remote controllers → route via MeshManager (auto-discovered)
9
+ *
10
+ * The proxy is what TypeBridge.create() returns. It IS the API:
11
+ *
12
+ * const api = await TypeBridge.create(adapter, { controllers });
13
+ * api.userController.findById("abc"); // local or remote — just works
14
+ *
15
+ * @param localRegistry - local controllers
16
+ * @param meshManager - handles remote controller routing
17
+ * @param ownProps - own properties (close, port, name, etc.)
18
+ */
19
+ export declare function createMeshProxy<T = unknown>(localRegistry: MethodRegistry, meshManager: MeshManager, ownProps?: Record<string, unknown>): T;
20
+ //# sourceMappingURL=client-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-proxy.d.ts","sourceRoot":"","sources":["../../src/proxy/client-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,CAAC,GAAG,OAAO,EACzC,aAAa,EAAE,cAAc,EAC7B,WAAW,EAAE,WAAW,EACxB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,CAAC,CA0BH"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Create a smart mesh proxy.
3
+ *
4
+ * This proxy routes method calls to the right place:
5
+ * - Local controllers → invoke directly via MethodRegistry
6
+ * - Remote controllers → route via MeshManager (auto-discovered)
7
+ *
8
+ * The proxy is what TypeBridge.create() returns. It IS the API:
9
+ *
10
+ * const api = await TypeBridge.create(adapter, { controllers });
11
+ * api.userController.findById("abc"); // local or remote — just works
12
+ *
13
+ * @param localRegistry - local controllers
14
+ * @param meshManager - handles remote controller routing
15
+ * @param ownProps - own properties (close, port, name, etc.)
16
+ */
17
+ export function createMeshProxy(localRegistry, meshManager, ownProps = {}) {
18
+ return new Proxy(ownProps, {
19
+ get(target, prop) {
20
+ if (typeof prop === "symbol")
21
+ return undefined;
22
+ if (prop === "then" || prop === "catch" || prop === "finally")
23
+ return undefined;
24
+ // Own properties (close, port, name, __controllers) take priority
25
+ if (prop in target) {
26
+ return target[prop];
27
+ }
28
+ // Return a controller proxy — will route to local or remote
29
+ return createControllerProxy(localRegistry, meshManager, prop);
30
+ },
31
+ ownKeys(target) {
32
+ return Object.keys(target);
33
+ },
34
+ getOwnPropertyDescriptor(target, prop) {
35
+ if (prop in target) {
36
+ return { configurable: true, enumerable: true, value: target[prop] };
37
+ }
38
+ return undefined;
39
+ },
40
+ });
41
+ }
42
+ /**
43
+ * Controller-level proxy — intercepts method calls and routes them.
44
+ */
45
+ function createControllerProxy(localRegistry, meshManager, controllerName) {
46
+ return new Proxy(() => { }, {
47
+ get(_target, methodName) {
48
+ if (typeof methodName === "symbol")
49
+ return undefined;
50
+ if (methodName === "then" || methodName === "catch" || methodName === "finally")
51
+ return undefined;
52
+ // Return a function that routes the call
53
+ return async (...args) => {
54
+ // 1. Local? Call directly — no network involved
55
+ if (localRegistry.hasController(controllerName)) {
56
+ return localRegistry.invoke(controllerName, String(methodName), args);
57
+ }
58
+ // 2. Remote? Route via mesh (waits for discovery if needed)
59
+ const conn = await meshManager.getConnection(controllerName);
60
+ return conn.request(`${controllerName}.${String(methodName)}`, args);
61
+ };
62
+ },
63
+ apply() {
64
+ throw new Error(`Cannot call controller "${controllerName}" directly. ` +
65
+ `Access a method: api.${controllerName}.methodName(args)`);
66
+ },
67
+ });
68
+ }
69
+ //# sourceMappingURL=client-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-proxy.js","sourceRoot":"","sources":["../../src/proxy/client-proxy.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAC7B,aAA6B,EAC7B,WAAwB,EACxB,WAAoC,EAAE;IAEtC,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE;QACzB,GAAG,CAAC,MAAM,EAAE,IAAqB;YAC/B,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAC;YAC/C,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAEhF,kEAAkE;YAClE,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;gBACnB,OAAQ,MAAkC,CAAC,IAAI,CAAC,CAAC;YACnD,CAAC;YAED,4DAA4D;YAC5D,OAAO,qBAAqB,CAAC,aAAa,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,CAAC,MAAM;YACZ,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;QAED,wBAAwB,CAAC,MAAM,EAAE,IAAI;YACnC,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;gBACnB,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAG,MAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAChF,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAM,CAAC;AACV,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAC5B,aAA6B,EAC7B,WAAwB,EACxB,cAAsB;IAEtB,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE;QACzB,GAAG,CAAC,OAAO,EAAE,UAA2B;YACtC,IAAI,OAAO,UAAU,KAAK,QAAQ;gBAAE,OAAO,SAAS,CAAC;YACrD,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,OAAO,IAAI,UAAU,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAElG,yCAAyC;YACzC,OAAO,KAAK,EAAE,GAAG,IAAe,EAAE,EAAE;gBAClC,gDAAgD;gBAChD,IAAI,aAAa,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;oBAChD,OAAO,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;gBACxE,CAAC;gBAED,4DAA4D;gBAC5D,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;gBAC7D,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,cAAc,IAAI,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YACvE,CAAC,CAAC;QACJ,CAAC;QAED,KAAK;YACH,MAAM,IAAI,KAAK,CACb,2BAA2B,cAAc,cAAc;gBACvD,wBAAwB,cAAc,mBAAmB,CAC1D,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createMeshProxy } from "./client-proxy.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/proxy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createMeshProxy } from "./client-proxy.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/proxy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { MethodDescriptor } from "../types/descriptor.js";
2
+ /**
3
+ * Extract method descriptors from a plain class by inspecting its prototype.
4
+ *
5
+ * This is the fallback/generic extractor used when no adapter-specific
6
+ * metadata is available. It produces basic descriptors by inspecting
7
+ * the class prototype's own methods.
8
+ *
9
+ * Framework-specific adapters (NestAdapter, TsedAdapter, etc.) may
10
+ * override this with richer metadata from decorator reflection.
11
+ */
12
+ export declare function extractMethodsFromPrototype(controllerName: string, controllerClass: new (...args: unknown[]) => unknown): MethodDescriptor[];
13
+ //# sourceMappingURL=extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/reflection/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAuB,MAAM,wBAAwB,CAAC;AAGpF;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GACnD,gBAAgB,EAAE,CAkCpB"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Extract method descriptors from a plain class by inspecting its prototype.
3
+ *
4
+ * This is the fallback/generic extractor used when no adapter-specific
5
+ * metadata is available. It produces basic descriptors by inspecting
6
+ * the class prototype's own methods.
7
+ *
8
+ * Framework-specific adapters (NestAdapter, TsedAdapter, etc.) may
9
+ * override this with richer metadata from decorator reflection.
10
+ */
11
+ export function extractMethodsFromPrototype(controllerName, controllerClass) {
12
+ const prototype = controllerClass.prototype;
13
+ const methods = [];
14
+ const ownMethodNames = Object.getOwnPropertyNames(prototype).filter((name) => name !== "constructor" && typeof prototype[name] === "function");
15
+ for (const methodName of ownMethodNames) {
16
+ const method = prototype[methodName];
17
+ // Try to extract parameter names from function source (best-effort)
18
+ const paramNames = extractParamNames(method);
19
+ const parameters = paramNames.map((name, index) => ({
20
+ name,
21
+ index,
22
+ type: { kind: "unknown" },
23
+ isOptional: false,
24
+ }));
25
+ const descriptor = {
26
+ controllerName,
27
+ methodName,
28
+ parameters,
29
+ returnType: { kind: "unknown" },
30
+ isAsync: method.constructor.name === "AsyncFunction",
31
+ decorators: [],
32
+ };
33
+ methods.push(descriptor);
34
+ }
35
+ return methods;
36
+ }
37
+ /**
38
+ * Extract parameter names from a function's toString() representation.
39
+ * Best-effort — works for simple cases. Complex destructuring or
40
+ * compiled code may not parse correctly.
41
+ */
42
+ function extractParamNames(fn) {
43
+ const source = fn.toString();
44
+ const match = source.match(/\(([^)]*)\)/);
45
+ if (!match || !match[1])
46
+ return [];
47
+ return match[1]
48
+ .split(",")
49
+ .map((param) => param.trim())
50
+ .filter((param) => param.length > 0)
51
+ .map((param) => {
52
+ // Handle default values: "name = 'default'" → "name"
53
+ const eqIdx = param.indexOf("=");
54
+ if (eqIdx > 0)
55
+ return param.substring(0, eqIdx).trim();
56
+ // Handle rest params: "...args" → "args"
57
+ if (param.startsWith("..."))
58
+ return param.substring(3);
59
+ return param;
60
+ });
61
+ }
62
+ //# sourceMappingURL=extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/reflection/extractor.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,MAAM,UAAU,2BAA2B,CACzC,cAAsB,EACtB,eAAoD;IAEpD,MAAM,SAAS,GAAG,eAAe,CAAC,SAAoC,CAAC;IACvE,MAAM,OAAO,GAAuB,EAAE,CAAC;IAEvC,MAAM,cAAc,GAAG,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,MAAM,CACjE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,aAAa,IAAI,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,UAAU,CAC1E,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,cAAc,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,CAAa,CAAC;QAEjD,oEAAoE;QACpE,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAE7C,MAAM,UAAU,GAA0B,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACzE,IAAI;YACJ,KAAK;YACL,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAoB;YAC3C,UAAU,EAAE,KAAK;SAClB,CAAC,CAAC,CAAC;QAEJ,MAAM,UAAU,GAAqB;YACnC,cAAc;YACd,UAAU;YACV,UAAU;YACV,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAoB;YACjD,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,KAAK,eAAe;YACpD,UAAU,EAAE,EAAE;SACf,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,EAAY;IACrC,MAAM,MAAM,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAC1C,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,OAAO,KAAK,CAAC,CAAC,CAAC;SACZ,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;SACnC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,qDAAqD;QACrD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACvD,yCAAyC;QACzC,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACvD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { extractMethodsFromPrototype } from "./extractor.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reflection/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { extractMethodsFromPrototype } from "./extractor.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reflection/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { MethodRegistry } from "./method-registry.js";
2
+ export type { MethodCatalogEntry } from "./method-registry.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { MethodRegistry } from "./method-registry.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/registry/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { MethodDescriptor } from "../types/descriptor.js";
2
+ /**
3
+ * MethodRegistry — stores all registered controllers and their methods.
4
+ *
5
+ * Each controller is registered with a key name (e.g., "userController")
6
+ * and its instance + extracted method descriptors.
7
+ */
8
+ export declare class MethodRegistry {
9
+ /** controller name → method descriptors */
10
+ private readonly methods;
11
+ /** controller name → controller instance (for invoking methods) */
12
+ private readonly instances;
13
+ /**
14
+ * Register a controller with its method descriptors and instance.
15
+ */
16
+ register(controllerName: string, instance: unknown, methods: MethodDescriptor[]): void;
17
+ /**
18
+ * Get all method descriptors for a controller.
19
+ */
20
+ getMethods(controllerName: string): MethodDescriptor[] | undefined;
21
+ /**
22
+ * Get a specific method descriptor.
23
+ */
24
+ getMethod(controllerName: string, methodName: string): MethodDescriptor | undefined;
25
+ /**
26
+ * Get the instance for a controller (used to actually call methods).
27
+ */
28
+ getInstance(controllerName: string): unknown | undefined;
29
+ /**
30
+ * Check if a controller is registered.
31
+ */
32
+ hasController(controllerName: string): boolean;
33
+ /**
34
+ * Get all registered controller names.
35
+ */
36
+ getControllerNames(): string[];
37
+ /**
38
+ * Invoke a method on a registered controller.
39
+ */
40
+ invoke(controllerName: string, methodName: string, args: unknown[]): Promise<unknown>;
41
+ /**
42
+ * Generate a serializable type catalog for the handshake.
43
+ * Contains all controllers, methods, and their parameter info.
44
+ */
45
+ toCatalog(): Record<string, MethodCatalogEntry[]>;
46
+ }
47
+ /**
48
+ * Single method entry in the serializable catalog.
49
+ */
50
+ export interface MethodCatalogEntry {
51
+ methodName: string;
52
+ parameterNames: string[];
53
+ parameterCount: number;
54
+ isAsync: boolean;
55
+ }
56
+ //# sourceMappingURL=method-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method-registry.d.ts","sourceRoot":"","sources":["../../src/registry/method-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IACjE,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IAExD;;OAEG;IACH,QAAQ,CACN,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,gBAAgB,EAAE,GAC1B,IAAI;IAKP;;OAEG;IACH,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,gBAAgB,EAAE,GAAG,SAAS;IAIlE;;OAEG;IACH,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAMnF;;OAEG;IACH,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAIxD;;OAEG;IACH,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAI9C;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACG,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAe3F;;;OAGG;IACH,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAclD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * MethodRegistry — stores all registered controllers and their methods.
3
+ *
4
+ * Each controller is registered with a key name (e.g., "userController")
5
+ * and its instance + extracted method descriptors.
6
+ */
7
+ export class MethodRegistry {
8
+ /** controller name → method descriptors */
9
+ methods = new Map();
10
+ /** controller name → controller instance (for invoking methods) */
11
+ instances = new Map();
12
+ /**
13
+ * Register a controller with its method descriptors and instance.
14
+ */
15
+ register(controllerName, instance, methods) {
16
+ this.methods.set(controllerName, methods);
17
+ this.instances.set(controllerName, instance);
18
+ }
19
+ /**
20
+ * Get all method descriptors for a controller.
21
+ */
22
+ getMethods(controllerName) {
23
+ return this.methods.get(controllerName);
24
+ }
25
+ /**
26
+ * Get a specific method descriptor.
27
+ */
28
+ getMethod(controllerName, methodName) {
29
+ const methods = this.methods.get(controllerName);
30
+ if (!methods)
31
+ return undefined;
32
+ return methods.find((m) => m.methodName === methodName);
33
+ }
34
+ /**
35
+ * Get the instance for a controller (used to actually call methods).
36
+ */
37
+ getInstance(controllerName) {
38
+ return this.instances.get(controllerName);
39
+ }
40
+ /**
41
+ * Check if a controller is registered.
42
+ */
43
+ hasController(controllerName) {
44
+ return this.methods.has(controllerName);
45
+ }
46
+ /**
47
+ * Get all registered controller names.
48
+ */
49
+ getControllerNames() {
50
+ return Array.from(this.methods.keys());
51
+ }
52
+ /**
53
+ * Invoke a method on a registered controller.
54
+ */
55
+ async invoke(controllerName, methodName, args) {
56
+ const instance = this.instances.get(controllerName);
57
+ if (!instance) {
58
+ throw new Error(`Controller not found: ${controllerName}`);
59
+ }
60
+ const method = instance[methodName];
61
+ if (typeof method !== "function") {
62
+ throw new Error(`Method not found: ${controllerName}.${methodName}`);
63
+ }
64
+ // Call the method on the instance with the provided args
65
+ return method.call(instance, ...args);
66
+ }
67
+ /**
68
+ * Generate a serializable type catalog for the handshake.
69
+ * Contains all controllers, methods, and their parameter info.
70
+ */
71
+ toCatalog() {
72
+ const catalog = {};
73
+ for (const [controllerName, methods] of this.methods) {
74
+ catalog[controllerName] = methods.map((m) => ({
75
+ methodName: m.methodName,
76
+ parameterNames: m.parameters.map((p) => p.name),
77
+ parameterCount: m.parameters.length,
78
+ isAsync: m.isAsync,
79
+ }));
80
+ }
81
+ return catalog;
82
+ }
83
+ }
84
+ //# sourceMappingURL=method-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method-registry.js","sourceRoot":"","sources":["../../src/registry/method-registry.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IACzB,2CAA2C;IAC1B,OAAO,GAAG,IAAI,GAAG,EAA8B,CAAC;IACjE,mEAAmE;IAClD,SAAS,GAAG,IAAI,GAAG,EAAmB,CAAC;IAExD;;OAEG;IACH,QAAQ,CACN,cAAsB,EACtB,QAAiB,EACjB,OAA2B;QAE3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,cAAsB;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,cAAsB,EAAE,UAAkB;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAC/B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,cAAsB;QAChC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,cAAsB;QAClC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,cAAsB,EAAE,UAAkB,EAAE,IAAe;QACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QACpD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,yBAAyB,cAAc,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,MAAM,GAAI,QAAoC,CAAC,UAAU,CAAC,CAAC;QACjE,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,qBAAqB,cAAc,IAAI,UAAU,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,yDAAyD;QACzD,OAAQ,MAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC;IACtD,CAAC;IAED;;;OAGG;IACH,SAAS;QACP,MAAM,OAAO,GAAyC,EAAE,CAAC;QAEzD,KAAK,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACrD,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC5C,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,cAAc,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC/C,cAAc,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM;gBACnC,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC,CAAC,CAAC;QACN,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
@@ -0,0 +1,38 @@
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 declare const ERROR_MARKER = "__typebridge_error__";
13
+ /**
14
+ * Serialized representation of an Error.
15
+ */
16
+ export interface SerializedError {
17
+ [ERROR_MARKER]: true;
18
+ name: string;
19
+ message: string;
20
+ stack: string | undefined;
21
+ cause?: SerializedError;
22
+ properties: Record<string, unknown>;
23
+ }
24
+ /**
25
+ * Serialize an Error object into a plain object that can be encoded by MessagePack.
26
+ * Recursively serializes `cause` chains and captures all enumerable properties.
27
+ */
28
+ export declare function serializeError(error: unknown): SerializedError;
29
+ /**
30
+ * Deserialize a SerializedError back into an Error object.
31
+ * Reconstructs cause chains and restores all custom properties.
32
+ */
33
+ export declare function deserializeError(data: SerializedError): Error;
34
+ /**
35
+ * Check if a value is a serialized TypeBridge Error.
36
+ */
37
+ export declare function isSerializedError(value: unknown): value is SerializedError;
38
+ //# sourceMappingURL=error-ext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-ext.d.ts","sourceRoot":"","sources":["../../src/serialization/error-ext.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,yEAAyE;AACzE,eAAO,MAAM,YAAY,yBAAyB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAiC9D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,KAAK,CAmB7D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAO1E"}