@olane/o-node 0.7.12-alpha.3 → 0.7.12-alpha.31

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 (254) hide show
  1. package/dist/o-core/src/connection/o-response.d.ts +12 -0
  2. package/dist/o-core/src/connection/o-response.d.ts.map +1 -0
  3. package/dist/o-core/src/connection/o-response.js +18 -0
  4. package/dist/o-core/src/error/enums/codes.error.d.ts +20 -0
  5. package/dist/o-core/src/error/enums/codes.error.d.ts.map +1 -0
  6. package/dist/o-core/src/error/enums/codes.error.js +20 -0
  7. package/dist/o-core/src/error/interfaces/o-error.interface.d.ts +6 -0
  8. package/dist/o-core/src/error/interfaces/o-error.interface.d.ts.map +1 -0
  9. package/dist/o-core/src/error/interfaces/o-error.interface.js +1 -0
  10. package/dist/o-core/src/error/o-error.d.ts +15 -0
  11. package/dist/o-core/src/error/o-error.d.ts.map +1 -0
  12. package/dist/o-core/src/error/o-error.js +27 -0
  13. package/dist/o-core/src/streaming/index.d.ts +11 -0
  14. package/dist/o-core/src/streaming/index.d.ts.map +1 -0
  15. package/dist/o-core/src/streaming/index.js +14 -0
  16. package/dist/o-core/src/streaming/protocol-builder.d.ts +62 -0
  17. package/dist/o-core/src/streaming/protocol-builder.d.ts.map +1 -0
  18. package/dist/o-core/src/streaming/protocol-builder.js +93 -0
  19. package/dist/o-core/src/streaming/stream-config.d.ts +36 -0
  20. package/dist/o-core/src/streaming/stream-config.d.ts.map +1 -0
  21. package/dist/o-core/src/streaming/stream-config.js +19 -0
  22. package/dist/o-core/src/streaming/stream-handler.base.d.ts +85 -0
  23. package/dist/o-core/src/streaming/stream-handler.base.d.ts.map +1 -0
  24. package/dist/o-core/src/streaming/stream-handler.base.js +112 -0
  25. package/dist/o-core/src/streaming/stream-transport.interface.d.ts +61 -0
  26. package/dist/o-core/src/streaming/stream-transport.interface.d.ts.map +1 -0
  27. package/dist/o-core/src/streaming/stream-transport.interface.js +10 -0
  28. package/dist/o-core/src/utils/streaming.utils.d.ts +22 -0
  29. package/dist/o-core/src/utils/streaming.utils.d.ts.map +1 -0
  30. package/dist/o-core/src/utils/streaming.utils.js +45 -0
  31. package/dist/o-node/src/connection/index.d.ts +5 -0
  32. package/dist/o-node/src/connection/index.d.ts.map +1 -0
  33. package/dist/o-node/src/connection/index.js +4 -0
  34. package/dist/o-node/src/connection/interfaces/o-node-connection-manager.config.d.ts +6 -0
  35. package/dist/o-node/src/connection/interfaces/o-node-connection-manager.config.d.ts.map +1 -0
  36. package/dist/o-node/src/connection/interfaces/o-node-connection-manager.config.js +1 -0
  37. package/dist/o-node/src/connection/interfaces/o-node-connection.config.d.ts +6 -0
  38. package/dist/o-node/src/connection/interfaces/o-node-connection.config.d.ts.map +1 -0
  39. package/dist/o-node/src/connection/interfaces/o-node-connection.config.js +1 -0
  40. package/dist/o-node/src/connection/o-node-connection.d.ts +13 -0
  41. package/dist/o-node/src/connection/o-node-connection.d.ts.map +1 -0
  42. package/dist/o-node/src/connection/o-node-connection.js +80 -0
  43. package/dist/o-node/src/connection/o-node-connection.manager.d.ts +19 -0
  44. package/dist/o-node/src/connection/o-node-connection.manager.d.ts.map +1 -0
  45. package/dist/o-node/src/connection/o-node-connection.manager.js +93 -0
  46. package/dist/o-node/src/connection/o-stream.request.d.ts +11 -0
  47. package/dist/o-node/src/connection/o-stream.request.d.ts.map +1 -0
  48. package/dist/o-node/src/connection/o-stream.request.js +7 -0
  49. package/dist/o-node/src/index.d.ts +11 -0
  50. package/dist/o-node/src/index.d.ts.map +1 -0
  51. package/dist/o-node/src/index.js +10 -0
  52. package/dist/o-node/src/interfaces/i-heartbeatable-node.d.ts +49 -0
  53. package/dist/o-node/src/interfaces/i-heartbeatable-node.d.ts.map +1 -0
  54. package/dist/o-node/src/interfaces/i-heartbeatable-node.js +1 -0
  55. package/dist/o-node/src/interfaces/i-reconnectable-node.d.ts +46 -0
  56. package/dist/o-node/src/interfaces/i-reconnectable-node.d.ts.map +1 -0
  57. package/dist/o-node/src/interfaces/i-reconnectable-node.js +1 -0
  58. package/dist/o-node/src/interfaces/o-node.config.d.ts +66 -0
  59. package/dist/o-node/src/interfaces/o-node.config.d.ts.map +1 -0
  60. package/dist/o-node/src/interfaces/o-node.config.js +1 -0
  61. package/dist/o-node/src/interfaces/o-node.tool-config.d.ts +4 -0
  62. package/dist/o-node/src/interfaces/o-node.tool-config.d.ts.map +1 -0
  63. package/dist/o-node/src/interfaces/o-node.tool-config.js +1 -0
  64. package/dist/o-node/src/lib/network-activity.lib.d.ts +1 -0
  65. package/dist/o-node/src/lib/network-activity.lib.d.ts.map +1 -0
  66. package/dist/o-node/src/lib/network-activity.lib.js +34 -0
  67. package/dist/o-node/src/managers/o-connection-heartbeat.manager.d.ts +62 -0
  68. package/dist/o-node/src/managers/o-connection-heartbeat.manager.d.ts.map +1 -0
  69. package/dist/o-node/src/managers/o-connection-heartbeat.manager.js +213 -0
  70. package/dist/o-node/src/managers/o-reconnection.manager.d.ts +51 -0
  71. package/dist/o-node/src/managers/o-reconnection.manager.d.ts.map +1 -0
  72. package/dist/o-node/src/managers/o-reconnection.manager.js +266 -0
  73. package/dist/o-node/src/nodes/client.node.d.ts +7 -0
  74. package/dist/o-node/src/nodes/client.node.d.ts.map +1 -0
  75. package/dist/o-node/src/nodes/client.node.js +16 -0
  76. package/dist/o-node/src/nodes/index.d.ts +4 -0
  77. package/dist/o-node/src/nodes/index.d.ts.map +1 -0
  78. package/dist/o-node/src/nodes/index.js +3 -0
  79. package/dist/o-node/src/nodes/server.node.d.ts +7 -0
  80. package/dist/o-node/src/nodes/server.node.d.ts.map +1 -0
  81. package/dist/o-node/src/nodes/server.node.js +20 -0
  82. package/dist/o-node/src/nodes/websocket.node.d.ts +7 -0
  83. package/dist/o-node/src/nodes/websocket.node.d.ts.map +1 -0
  84. package/dist/o-node/src/nodes/websocket.node.js +18 -0
  85. package/dist/o-node/src/o-node.d.ts +73 -0
  86. package/dist/o-node/src/o-node.d.ts.map +1 -0
  87. package/dist/o-node/src/o-node.hierarchy-manager.d.ts +15 -0
  88. package/dist/o-node/src/o-node.hierarchy-manager.d.ts.map +1 -0
  89. package/dist/o-node/src/o-node.hierarchy-manager.js +15 -0
  90. package/dist/o-node/src/o-node.js +414 -0
  91. package/dist/o-node/src/o-node.notification-manager.d.ts +52 -0
  92. package/dist/o-node/src/o-node.notification-manager.d.ts.map +1 -0
  93. package/dist/o-node/src/o-node.notification-manager.js +185 -0
  94. package/dist/o-node/src/o-node.tool.d.ts +18 -0
  95. package/dist/o-node/src/o-node.tool.d.ts.map +1 -0
  96. package/dist/o-node/src/o-node.tool.js +90 -0
  97. package/dist/o-node/src/router/index.d.ts +6 -0
  98. package/dist/o-node/src/router/index.d.ts.map +1 -0
  99. package/dist/o-node/src/router/index.js +5 -0
  100. package/dist/o-node/src/router/interfaces/o-node-router.config.d.ts +3 -0
  101. package/dist/o-node/src/router/interfaces/o-node-router.config.d.ts.map +1 -0
  102. package/dist/o-node/src/router/interfaces/o-node-router.config.js +1 -0
  103. package/dist/o-node/src/router/interfaces/o-node-router.response.d.ts +8 -0
  104. package/dist/o-node/src/router/interfaces/o-node-router.response.d.ts.map +1 -0
  105. package/dist/o-node/src/router/interfaces/o-node-router.response.js +1 -0
  106. package/dist/o-node/src/router/o-node.address.d.ts +18 -0
  107. package/dist/o-node/src/router/o-node.address.d.ts.map +1 -0
  108. package/dist/o-node/src/router/o-node.address.js +29 -0
  109. package/dist/o-node/src/router/o-node.router.d.ts +45 -0
  110. package/dist/o-node/src/router/o-node.router.d.ts.map +1 -0
  111. package/dist/o-node/src/router/o-node.router.js +135 -0
  112. package/dist/o-node/src/router/o-node.routing-policy.d.ts +30 -0
  113. package/dist/o-node/src/router/o-node.routing-policy.d.ts.map +1 -0
  114. package/dist/o-node/src/router/o-node.routing-policy.js +57 -0
  115. package/dist/o-node/src/router/o-node.transport.d.ts +11 -0
  116. package/dist/o-node/src/router/o-node.transport.d.ts.map +1 -0
  117. package/dist/o-node/src/router/o-node.transport.js +18 -0
  118. package/dist/o-node/src/router/resolvers/index.d.ts +4 -0
  119. package/dist/o-node/src/router/resolvers/index.d.ts.map +1 -0
  120. package/dist/o-node/src/router/resolvers/index.js +3 -0
  121. package/dist/o-node/src/router/resolvers/o-node.leader-resolver-fallback.d.ts +8 -0
  122. package/dist/o-node/src/router/resolvers/o-node.leader-resolver-fallback.d.ts.map +1 -0
  123. package/dist/o-node/src/router/resolvers/o-node.leader-resolver-fallback.js +35 -0
  124. package/dist/{src/router/resolvers/o-node.child-resolver.d.ts → o-node/src/router/resolvers/o-node.resolver.d.ts} +2 -2
  125. package/dist/o-node/src/router/resolvers/o-node.resolver.d.ts.map +1 -0
  126. package/dist/o-node/src/router/resolvers/o-node.resolver.js +41 -0
  127. package/dist/o-node/src/router/resolvers/o-node.search-resolver.d.ts +170 -0
  128. package/dist/o-node/src/router/resolvers/o-node.search-resolver.d.ts.map +1 -0
  129. package/dist/o-node/src/router/resolvers/o-node.search-resolver.js +285 -0
  130. package/dist/o-node/src/router/route.request.d.ts +14 -0
  131. package/dist/o-node/src/router/route.request.d.ts.map +1 -0
  132. package/dist/o-node/src/router/route.request.js +1 -0
  133. package/dist/o-node/src/streaming/index.d.ts +10 -0
  134. package/dist/o-node/src/streaming/index.d.ts.map +1 -0
  135. package/dist/o-node/src/streaming/index.js +12 -0
  136. package/dist/o-node/src/streaming/libp2p-stream-transport.d.ts +50 -0
  137. package/dist/o-node/src/streaming/libp2p-stream-transport.d.ts.map +1 -0
  138. package/dist/o-node/src/streaming/libp2p-stream-transport.js +137 -0
  139. package/dist/o-node/src/streaming/node-stream-handler.d.ts +65 -0
  140. package/dist/o-node/src/streaming/node-stream-handler.d.ts.map +1 -0
  141. package/dist/o-node/src/streaming/node-stream-handler.js +101 -0
  142. package/dist/o-node/src/utils/circuit-breaker.d.ts +107 -0
  143. package/dist/o-node/src/utils/circuit-breaker.d.ts.map +1 -0
  144. package/dist/o-node/src/utils/circuit-breaker.js +175 -0
  145. package/dist/o-node/src/utils/index.d.ts +5 -0
  146. package/dist/o-node/src/utils/index.d.ts.map +1 -0
  147. package/dist/o-node/src/utils/index.js +4 -0
  148. package/dist/o-node/src/utils/leader-request-wrapper.d.ts +66 -0
  149. package/dist/o-node/src/utils/leader-request-wrapper.d.ts.map +1 -0
  150. package/dist/o-node/src/utils/leader-request-wrapper.js +160 -0
  151. package/dist/o-node/src/utils/network.utils.d.ts +20 -0
  152. package/dist/o-node/src/utils/network.utils.d.ts.map +1 -0
  153. package/dist/o-node/src/utils/network.utils.js +74 -0
  154. package/dist/o-node/src/utils/stream.utils.d.ts +6 -0
  155. package/dist/o-node/src/utils/stream.utils.d.ts.map +1 -0
  156. package/dist/o-node/src/utils/stream.utils.js +27 -0
  157. package/dist/o-node/test/circuit-breaker.test.d.ts +2 -0
  158. package/dist/o-node/test/circuit-breaker.test.d.ts.map +1 -0
  159. package/dist/o-node/test/circuit-breaker.test.js +262 -0
  160. package/dist/o-node/test/leader-request-wrapper.test.d.ts +1 -0
  161. package/dist/o-node/test/leader-request-wrapper.test.d.ts.map +1 -0
  162. package/dist/o-node/test/leader-request-wrapper.test.js +246 -0
  163. package/dist/o-node/test/o-node.spec.d.ts +2 -0
  164. package/dist/o-node/test/o-node.spec.d.ts.map +1 -0
  165. package/dist/o-node/test/o-node.spec.js +20 -0
  166. package/dist/o-node/test/search-resolver.spec.d.ts +2 -0
  167. package/dist/o-node/test/search-resolver.spec.d.ts.map +1 -0
  168. package/dist/o-node/test/search-resolver.spec.js +693 -0
  169. package/dist/src/connection/o-node-connection.d.ts +1 -2
  170. package/dist/src/connection/o-node-connection.d.ts.map +1 -1
  171. package/dist/src/connection/o-node-connection.js +25 -18
  172. package/dist/src/connection/o-node-connection.manager.d.ts +3 -1
  173. package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
  174. package/dist/src/connection/o-node-connection.manager.js +45 -20
  175. package/dist/src/connection/o-stream.request.d.ts +11 -0
  176. package/dist/src/connection/o-stream.request.d.ts.map +1 -0
  177. package/dist/src/connection/o-stream.request.js +7 -0
  178. package/dist/src/index.d.ts +2 -1
  179. package/dist/src/index.d.ts.map +1 -1
  180. package/dist/src/index.js +2 -1
  181. package/dist/src/interfaces/i-heartbeatable-node.d.ts +49 -0
  182. package/dist/src/interfaces/i-heartbeatable-node.d.ts.map +1 -0
  183. package/dist/src/interfaces/i-heartbeatable-node.js +1 -0
  184. package/dist/src/interfaces/i-reconnectable-node.d.ts +46 -0
  185. package/dist/src/interfaces/i-reconnectable-node.d.ts.map +1 -0
  186. package/dist/src/interfaces/i-reconnectable-node.js +1 -0
  187. package/dist/src/interfaces/o-node.config.d.ts +42 -0
  188. package/dist/src/interfaces/o-node.config.d.ts.map +1 -1
  189. package/dist/src/managers/o-connection-heartbeat.manager.d.ts +62 -0
  190. package/dist/src/managers/o-connection-heartbeat.manager.d.ts.map +1 -0
  191. package/dist/src/managers/o-connection-heartbeat.manager.js +213 -0
  192. package/dist/src/managers/o-reconnection.manager.d.ts +51 -0
  193. package/dist/src/managers/o-reconnection.manager.d.ts.map +1 -0
  194. package/dist/src/managers/o-reconnection.manager.js +266 -0
  195. package/dist/src/o-node.d.ts +20 -2
  196. package/dist/src/o-node.d.ts.map +1 -1
  197. package/dist/src/o-node.js +161 -32
  198. package/dist/src/o-node.notification-manager.d.ts +52 -0
  199. package/dist/src/o-node.notification-manager.d.ts.map +1 -0
  200. package/dist/src/o-node.notification-manager.js +185 -0
  201. package/dist/src/o-node.tool.d.ts.map +1 -1
  202. package/dist/src/o-node.tool.js +29 -22
  203. package/dist/src/router/o-node.router.d.ts +1 -0
  204. package/dist/src/router/o-node.router.d.ts.map +1 -1
  205. package/dist/src/router/o-node.router.js +61 -5
  206. package/dist/src/router/o-node.routing-policy.d.ts.map +1 -1
  207. package/dist/src/router/o-node.routing-policy.js +7 -2
  208. package/dist/src/router/resolvers/o-node.resolver.d.ts.map +1 -1
  209. package/dist/src/router/resolvers/o-node.resolver.js +5 -1
  210. package/dist/src/router/resolvers/o-node.search-resolver.d.ts.map +1 -1
  211. package/dist/src/router/resolvers/o-node.search-resolver.js +40 -10
  212. package/dist/src/streaming/index.d.ts +10 -0
  213. package/dist/src/streaming/index.d.ts.map +1 -0
  214. package/dist/src/streaming/index.js +12 -0
  215. package/dist/src/streaming/libp2p-stream-transport.d.ts +50 -0
  216. package/dist/src/streaming/libp2p-stream-transport.d.ts.map +1 -0
  217. package/dist/src/streaming/libp2p-stream-transport.js +137 -0
  218. package/dist/src/streaming/node-stream-handler.d.ts +65 -0
  219. package/dist/src/streaming/node-stream-handler.d.ts.map +1 -0
  220. package/dist/src/streaming/node-stream-handler.js +101 -0
  221. package/dist/src/streaming/o-node-streaming-client.d.ts +33 -0
  222. package/dist/src/streaming/o-node-streaming-client.d.ts.map +1 -0
  223. package/dist/src/streaming/o-node-streaming-client.js +130 -0
  224. package/dist/src/utils/circuit-breaker.d.ts +107 -0
  225. package/dist/src/utils/circuit-breaker.d.ts.map +1 -0
  226. package/dist/src/utils/circuit-breaker.js +175 -0
  227. package/dist/src/utils/circuit-breaker.test.d.ts +2 -0
  228. package/dist/src/utils/circuit-breaker.test.d.ts.map +1 -0
  229. package/dist/src/utils/circuit-breaker.test.js +262 -0
  230. package/dist/src/utils/index.d.ts +3 -0
  231. package/dist/src/utils/index.d.ts.map +1 -0
  232. package/dist/src/utils/index.js +2 -0
  233. package/dist/src/utils/leader-request-wrapper.d.ts +66 -0
  234. package/dist/src/utils/leader-request-wrapper.d.ts.map +1 -0
  235. package/dist/src/utils/leader-request-wrapper.js +160 -0
  236. package/dist/src/utils/leader-request-wrapper.test.d.ts +1 -0
  237. package/dist/src/utils/leader-request-wrapper.test.d.ts.map +1 -0
  238. package/dist/src/utils/leader-request-wrapper.test.js +246 -0
  239. package/dist/src/utils/stream.utils.d.ts +6 -0
  240. package/dist/src/utils/stream.utils.d.ts.map +1 -0
  241. package/dist/src/utils/stream.utils.js +31 -0
  242. package/dist/test/circuit-breaker.test.d.ts +2 -0
  243. package/dist/test/circuit-breaker.test.d.ts.map +1 -0
  244. package/dist/test/circuit-breaker.test.js +262 -0
  245. package/dist/test/helpers/test-node.tool.d.ts +15 -0
  246. package/dist/test/helpers/test-node.tool.d.ts.map +1 -0
  247. package/dist/test/helpers/test-node.tool.js +27 -0
  248. package/dist/test/leader-request-wrapper.test.d.ts +1 -0
  249. package/dist/test/leader-request-wrapper.test.d.ts.map +1 -0
  250. package/dist/test/leader-request-wrapper.test.js +246 -0
  251. package/dist/test/search-resolver.spec.js +79 -0
  252. package/package.json +6 -6
  253. package/dist/src/router/resolvers/o-node.child-resolver.d.ts.map +0 -1
  254. package/dist/src/router/resolvers/o-node.child-resolver.js +0 -58
@@ -1,7 +1,8 @@
1
- import { oAddress, oError, oErrorCodes, oRequest, } from '@olane/o-core';
1
+ import { CoreUtils, oAddress, oError, oErrorCodes, oRequest, ResponseBuilder, } from '@olane/o-core';
2
2
  import { oToolRouter } from '@olane/o-tool';
3
3
  import { oNodeConnection } from '../connection/o-node-connection.js';
4
4
  import { oNodeRoutingPolicy } from './o-node.routing-policy.js';
5
+ import { oStreamRequest } from '../connection/o-stream.request.js';
5
6
  export class oNodeRouter extends oToolRouter {
6
7
  constructor() {
7
8
  super();
@@ -25,6 +26,9 @@ export class oNodeRouter extends oToolRouter {
25
26
  params: request.params,
26
27
  id: request.id,
27
28
  });
29
+ if (request.stream) {
30
+ nextHopRequest.stream = request.stream;
31
+ }
28
32
  // Handle self-routing: execute locally instead of dialing
29
33
  if (this.routingPolicy.isSelfAddress(address, node)) {
30
34
  return this.executeSelfRouting(request, node);
@@ -39,17 +43,55 @@ export class oNodeRouter extends oToolRouter {
39
43
  }
40
44
  /**
41
45
  * Executes a request locally when routing to self.
46
+ * Now uses ResponseBuilder for consistency with useSelf() behavior.
42
47
  */
43
48
  async executeSelfRouting(request, node) {
44
49
  const { payload } = request.params;
45
50
  const params = payload.params;
46
51
  const localRequest = new oRequest({
47
52
  method: payload.method,
48
- params: { ...params },
53
+ params: {
54
+ ...params,
55
+ _connectionId: request.params._connectionId,
56
+ _requestMethod: payload.method,
57
+ },
49
58
  id: request.id,
50
59
  });
51
- const result = await node.execute(localRequest);
52
- return result;
60
+ // Create ResponseBuilder with metrics tracking
61
+ const responseBuilder = ResponseBuilder.create().withMetrics(node.metrics);
62
+ // Handle streaming requests
63
+ const isStream = request.params._isStreaming;
64
+ if (isStream && request.stream) {
65
+ // For streaming, we need to handle the stream chunks
66
+ try {
67
+ const result = await node.execute(localRequest, request.stream);
68
+ const response = await responseBuilder.build(localRequest, result, null, {
69
+ isStream: true,
70
+ });
71
+ // Return unwrapped data for consistency with dialAndTransmit
72
+ return response.result.data;
73
+ }
74
+ catch (error) {
75
+ const errorResponse = await responseBuilder.buildError(localRequest, error, {
76
+ isStream: true,
77
+ });
78
+ // For errors, throw to match remote behavior
79
+ throw responseBuilder.normalizeError(error);
80
+ }
81
+ }
82
+ // Handle non-streaming requests with error handling
83
+ try {
84
+ const result = await node.execute(localRequest);
85
+ const response = await responseBuilder.build(localRequest, result, null);
86
+ // Return unwrapped data to match dialAndTransmit behavior
87
+ return response.result.data;
88
+ }
89
+ catch (error) {
90
+ // Build error response for metrics tracking
91
+ await responseBuilder.buildError(localRequest, error);
92
+ // Then throw the normalized error
93
+ throw responseBuilder.normalizeError(error);
94
+ }
53
95
  }
54
96
  /**
55
97
  * Checks if the next hop is the final destination address.
@@ -65,10 +107,11 @@ export class oNodeRouter extends oToolRouter {
65
107
  unwrapDestinationRequest(request) {
66
108
  const { payload } = request.params;
67
109
  const params = payload.params;
68
- return new oRequest({
110
+ return new oStreamRequest({
69
111
  method: payload.method,
70
112
  params: { ...params },
71
113
  id: request.id,
114
+ stream: request.stream,
72
115
  });
73
116
  }
74
117
  /**
@@ -76,13 +119,26 @@ export class oNodeRouter extends oToolRouter {
76
119
  */
77
120
  async dialAndTransmit(address, request, node) {
78
121
  try {
122
+ const isStream = request.params._isStreaming ||
123
+ request.params.payload?.params?._isStreaming;
79
124
  const connection = await node.p2pNode.dial(address.libp2pTransports.map((t) => t.toMultiaddr()));
80
125
  const nodeConnection = new oNodeConnection({
81
126
  p2pConnection: connection,
82
127
  nextHopAddress: address,
83
128
  address: node.address,
84
129
  callerAddress: node.address,
130
+ isStream: isStream,
85
131
  });
132
+ if (isStream) {
133
+ const routeRequest = request;
134
+ if (!routeRequest.stream) {
135
+ throw new oError(oErrorCodes.INVALID_REQUEST, 'Stream is required');
136
+ }
137
+ nodeConnection.onChunk(async (response) => {
138
+ CoreUtils.sendStreamResponse(response, routeRequest.stream);
139
+ });
140
+ // allow this to continue as we will tell the transmitter to stream the response and we will intercept via the above listener
141
+ }
86
142
  const response = await nodeConnection.transmit(request);
87
143
  return response.result.data;
88
144
  }
@@ -1 +1 @@
1
- {"version":3,"file":"o-node.routing-policy.d.ts","sourceRoot":"","sources":["../../../src/router/o-node.routing-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAG1C;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;IACpD;;;;;;;;;OASG;IACH,iBAAiB,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO;IAkB1D;;;;;;;;OAQG;IACH,0BAA0B,CACxB,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,KAAK,GACV,aAAa,GAAG,IAAI;CAuBxB"}
1
+ {"version":3,"file":"o-node.routing-policy.d.ts","sourceRoot":"","sources":["../../../src/router/o-node.routing-policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAG1C;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;IACpD;;;;;;;;;OASG;IACH,iBAAiB,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO;IAuB1D;;;;;;;;OAQG;IACH,0BAA0B,CACxB,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,KAAK,GACV,aAAa,GAAG,IAAI;CAmBxB"}
@@ -17,11 +17,16 @@ export class oNodeRoutingPolicy extends oRoutingPolicy {
17
17
  */
18
18
  isInternalAddress(address, node) {
19
19
  const nodeAddress = address;
20
+ // if we are trying to connect to a parent, it's internal
21
+ if (node.hierarchyManager.parents.some((p) => p.equals(address))) {
22
+ return true;
23
+ }
20
24
  if (nodeAddress.paths.indexOf(oAddress.leader().paths) !== -1 && // if the address has a leader
21
25
  nodeAddress.libp2pTransports?.length > 0) {
22
26
  // transports are provided, let's see if they match our known leaders
23
27
  const isLeaderRef = nodeAddress.toString() === oAddress.leader().toString();
24
- const isOurLeaderRef = node.hierarchyManager.leaders.some((l) => l.equals(nodeAddress));
28
+ const isOurLeaderRef = node.address.equals(nodeAddress) ||
29
+ node.hierarchyManager.leaders.some((l) => l.equals(nodeAddress));
25
30
  return isLeaderRef || isOurLeaderRef;
26
31
  }
27
32
  return true;
@@ -40,7 +45,7 @@ export class oNodeRoutingPolicy extends oRoutingPolicy {
40
45
  const isInternal = this.isInternalAddress(address, node);
41
46
  if (!isInternal) {
42
47
  // external address, so we need to route
43
- this.logger.debug('Address is external, routing...', nodeAddress.toString(), nodeAddress.libp2pTransports.map((t) => t.toString()));
48
+ this.logger.debug('Address is external, routing...', nodeAddress);
44
49
  // route to leader of external OS
45
50
  return {
46
51
  nextHopAddress: new oNodeAddress(oAddress.leader().toString(), nodeAddress.libp2pTransports),
@@ -1 +1 @@
1
- {"version":3,"file":"o-node.resolver.d.ts","sourceRoot":"","sources":["../../../../src/router/resolvers/o-node.resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,aAAa,EAEd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,qBAAa,aAAc,SAAQ,gBAAgB;IACrC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY;gBAArB,OAAO,EAAE,YAAY;IAIpD,IAAI,mBAAmB,IAAI,aAAa,EAAE,CAEzC;IAEK,OAAO,CAAC,YAAY,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAsC1E"}
1
+ {"version":3,"file":"o-node.resolver.d.ts","sourceRoot":"","sources":["../../../../src/router/resolvers/o-node.resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,aAAa,EAId,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,qBAAa,aAAc,SAAQ,gBAAgB;IACrC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY;gBAArB,OAAO,EAAE,YAAY;IAIpD,IAAI,mBAAmB,IAAI,aAAa,EAAE,CAEzC;IAEK,OAAO,CAAC,YAAY,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC;CA8C1E"}
@@ -1,4 +1,4 @@
1
- import { oAddressResolver, TransportType, } from '@olane/o-core';
1
+ import { oAddressResolver, oAddress, TransportType, oError, oErrorCodes, } from '@olane/o-core';
2
2
  import { oNodeAddress } from '../o-node.address.js';
3
3
  export class oNodeResolver extends oAddressResolver {
4
4
  constructor(address) {
@@ -32,6 +32,10 @@ export class oNodeResolver extends oAddressResolver {
32
32
  requestOverride: request,
33
33
  };
34
34
  }
35
+ // no child address, and we have already been to the leader, fail
36
+ if (address.toString().indexOf(oAddress.leader().toString()) > -1) {
37
+ throw new oError(oErrorCodes.NOT_FOUND, targetAddress.toString() + ' node not found.');
38
+ }
35
39
  return {
36
40
  nextHopAddress: address,
37
41
  targetAddress: targetAddress,
@@ -1 +1 @@
1
- {"version":3,"file":"o-node.search-resolver.d.ts","sourceRoot":"","sources":["../../../../src/router/resolvers/o-node.search-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,KAAK,EAEL,UAAU,EACV,cAAc,EAEd,aAAa,EAEd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AACH,qBAAa,eAAgB,SAAQ,gBAAgB;IACvC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ;gBAAjB,OAAO,EAAE,QAAQ;IAIhD,IAAI,gBAAgB,IAAI,UAAU,EAAE,CAEnC;IAED;;;;OAIG;IACH,SAAS,CAAC,kBAAkB,IAAI,QAAQ;IAIxC;;;;OAIG;IACH,SAAS,CAAC,eAAe,IAAI,MAAM;IAInC;;;;;OAKG;IACH,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,GAAG,GAAG;IAOnD;;;;;;OAMG;IACH,SAAS,CAAC,mBAAmB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,GAAG,GAAG,EAAE;IASjE;;;;;OAKG;IACH,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI;IAIlD;;;;;OAKG;IACH,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,GAAG,cAAc,EAAE;IAOtD;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,wBAAwB,CAChC,OAAO,EAAE,QAAQ,EACjB,gBAAgB,EAAE,cAAc,EAAE,EAClC,IAAI,EAAE,KAAK,GACV,cAAc,EAAE;IAgBnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyCG;IACH,SAAS,CAAC,gBAAgB,CACxB,IAAI,EAAE,KAAK,EACX,qBAAqB,EAAE,QAAQ,EAC/B,YAAY,EAAE,GAAG,GAChB,QAAQ;IAsBL,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CA8D/D"}
1
+ {"version":3,"file":"o-node.search-resolver.d.ts","sourceRoot":"","sources":["../../../../src/router/resolvers/o-node.search-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,gBAAgB,EAChB,KAAK,EAEL,UAAU,EACV,cAAc,EAEd,aAAa,EAEd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AACH,qBAAa,eAAgB,SAAQ,gBAAgB;IACvC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ;gBAAjB,OAAO,EAAE,QAAQ;IAIhD,IAAI,gBAAgB,IAAI,UAAU,EAAE,CAEnC;IAED;;;;OAIG;IACH,SAAS,CAAC,kBAAkB,IAAI,QAAQ;IAIxC;;;;OAIG;IACH,SAAS,CAAC,eAAe,IAAI,MAAM;IAInC;;;;;OAKG;IACH,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,GAAG,GAAG;IAOnD;;;;;;OAMG;IACH,SAAS,CAAC,mBAAmB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,GAAG,GAAG,EAAE;IASjE;;;;;OAKG;IACH,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI;IAIlD;;;;;OAKG;IACH,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,GAAG,cAAc,EAAE;IAOtD;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,wBAAwB,CAChC,OAAO,EAAE,QAAQ,EACjB,gBAAgB,EAAE,cAAc,EAAE,EAClC,IAAI,EAAE,KAAK,GACV,cAAc,EAAE;IAgBnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyCG;IACH,SAAS,CAAC,gBAAgB,CACxB,IAAI,EAAE,KAAK,EACX,qBAAqB,EAAE,QAAQ,EAC/B,YAAY,EAAE,GAAG,GAChB,QAAQ;IAeL,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CAsG/D"}
@@ -1,4 +1,4 @@
1
- import { oAddress, oAddressResolver, oCustomTransport, RestrictedAddresses, } from '@olane/o-core';
1
+ import { NodeState, oAddress, oAddressResolver, oCustomTransport, RestrictedAddresses, } from '@olane/o-core';
2
2
  import { oNodeTransport } from '../o-node.transport.js';
3
3
  /**
4
4
  * Address resolver that searches a registry to find transports for addresses.
@@ -78,7 +78,7 @@ export class oSearchResolver extends oAddressResolver {
78
78
  * @returns The registry address to query
79
79
  */
80
80
  getRegistryAddress() {
81
- return new oAddress(RestrictedAddresses.REGISTRY);
81
+ return new oAddress('o://leader/registry');
82
82
  }
83
83
  /**
84
84
  * Returns the method name to call on the registry.
@@ -201,7 +201,6 @@ export class oSearchResolver extends oAddressResolver {
201
201
  determineNextHop(node, resolvedTargetAddress, searchResult) {
202
202
  // Determine next hop using standard hierarchy logic
203
203
  const nextHopAddress = oAddress.next(node.address, resolvedTargetAddress);
204
- this.logger.debug('determineNextHop with params', 'node.address: ' + node.address.toString(), 'resolvedTargetAddress: ' + resolvedTargetAddress.toString(), 'searchResult.address: ' + searchResult.address, 'next hop: ' + nextHopAddress.toString());
205
204
  // Map transports from search result
206
205
  const targetTransports = this.mapTransports(searchResult);
207
206
  // Set transports on the next hop based on routing logic
@@ -218,13 +217,40 @@ export class oSearchResolver extends oAddressResolver {
218
217
  requestOverride: resolveRequest,
219
218
  };
220
219
  }
221
- // Perform registry search
220
+ if (node.state !== NodeState.RUNNING) {
221
+ return {
222
+ nextHopAddress: address,
223
+ targetAddress: targetAddress,
224
+ requestOverride: resolveRequest,
225
+ };
226
+ }
227
+ // Perform registry search with error handling
222
228
  const searchParams = this.buildSearchParams(address);
223
229
  const registryAddress = this.getRegistryAddress();
224
- const searchResponse = await node.use(registryAddress, {
225
- method: this.getSearchMethod(),
226
- params: searchParams,
227
- });
230
+ let searchResponse;
231
+ try {
232
+ searchResponse = await node.use(registryAddress, {
233
+ method: this.getSearchMethod(),
234
+ params: searchParams,
235
+ });
236
+ }
237
+ catch (error) {
238
+ // Log the error but don't throw - allow fallback resolvers to handle it
239
+ const errorMessage = error instanceof Error ? error.message : String(error);
240
+ // Check if this is a circuit breaker error (fast-fail scenario)
241
+ if (errorMessage.includes('Circuit breaker is OPEN')) {
242
+ this.logger.warn(`Registry search blocked by circuit breaker for ${address.toString()}: ${errorMessage}`);
243
+ }
244
+ else {
245
+ this.logger.error(`Registry search failed for ${address.toString()}: ${errorMessage}`);
246
+ }
247
+ // Return original address without transports, letting next resolver in chain handle it
248
+ return {
249
+ nextHopAddress: address,
250
+ targetAddress: targetAddress,
251
+ requestOverride: resolveRequest,
252
+ };
253
+ }
228
254
  // Filter and select result
229
255
  const filteredResults = this.filterSearchResults(searchResponse.result.data, node);
230
256
  const selectedResult = this.selectResult(filteredResults);
@@ -240,8 +266,12 @@ export class oSearchResolver extends oAddressResolver {
240
266
  const extraParams = address
241
267
  .toString() // o://embeddings-text replace o://embeddings-text = ''
242
268
  .replace(address.toRootAddress().toString(), '');
243
- this.logger.debug('Extra params:', extraParams);
244
- const resolvedTargetAddress = new oAddress(selectedResult.address + extraParams);
269
+ // Check if selectedResult.address already contains the complete path
270
+ // This happens when registry finds via staticAddress - the returned address
271
+ // is the canonical hierarchical location, so we shouldn't append extraParams
272
+ const resultAddress = selectedResult.address;
273
+ const shouldAppendParams = extraParams && !resultAddress.endsWith(extraParams);
274
+ const resolvedTargetAddress = new oAddress(shouldAppendParams ? resultAddress + extraParams : resultAddress);
245
275
  // Set transports on the target address
246
276
  resolvedTargetAddress.setTransports(this.mapTransports(selectedResult));
247
277
  // Determine next hop and configure transports
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Streaming functionality for o-node
3
+ *
4
+ * This module provides libp2p-specific implementations of the streaming
5
+ * abstractions defined in o-core.
6
+ */
7
+ export { Libp2pStreamTransport } from './libp2p-stream-transport.js';
8
+ export { NodeStreamHandler, NodeStreamHandlerOptions, } from './node-stream-handler.js';
9
+ export { oNodeStreamingClient } from './o-node-streaming-client.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/streaming/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAGrE,OAAO,EACL,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Streaming functionality for o-node
3
+ *
4
+ * This module provides libp2p-specific implementations of the streaming
5
+ * abstractions defined in o-core.
6
+ */
7
+ // libp2p-specific stream transport
8
+ export { Libp2pStreamTransport } from './libp2p-stream-transport.js';
9
+ // o-node stream handler with metrics
10
+ export { NodeStreamHandler, } from './node-stream-handler.js';
11
+ // o-node streaming client for client-side streaming orchestration
12
+ export { oNodeStreamingClient } from './o-node-streaming-client.js';
@@ -0,0 +1,50 @@
1
+ import { Stream } from '@olane/o-config';
2
+ import { IStreamTransport, StreamStatus, StreamTransportConfig } from '@olane/o-core';
3
+ /**
4
+ * libp2p-specific implementation of IStreamTransport.
5
+ * Wraps a libp2p Stream and handles backpressure, message listening,
6
+ * and stream lifecycle management.
7
+ */
8
+ export declare class Libp2pStreamTransport implements IStreamTransport {
9
+ private readonly stream;
10
+ private messageHandler?;
11
+ private config;
12
+ constructor(stream: Stream, config?: StreamTransportConfig);
13
+ /**
14
+ * Get the underlying libp2p Stream (useful for advanced use cases)
15
+ */
16
+ getStream(): Stream;
17
+ /**
18
+ * Send data through the stream with backpressure handling
19
+ */
20
+ send(data: Uint8Array): Promise<void>;
21
+ /**
22
+ * Set up a message handler for incoming data.
23
+ * IMPORTANT: For libp2p v3, this must be called synchronously after
24
+ * receiving the stream to prevent buffer overflow.
25
+ */
26
+ onMessage(handler: (data: Uint8Array) => void): void;
27
+ /**
28
+ * Remove the message handler
29
+ */
30
+ removeMessageHandler(): void;
31
+ /**
32
+ * Close the stream and clean up resources
33
+ */
34
+ close(): Promise<void>;
35
+ /**
36
+ * Get the current status of the stream
37
+ */
38
+ getStatus(): StreamStatus;
39
+ /**
40
+ * Check if the stream is in a usable state
41
+ */
42
+ isOpen(): boolean;
43
+ /**
44
+ * Wait for the first message with timeout
45
+ * @param timeoutMs - Optional timeout in milliseconds (defaults to config.readTimeoutMs)
46
+ * @returns Promise that resolves with the first message
47
+ */
48
+ waitForMessage(timeoutMs?: number): Promise<Uint8Array>;
49
+ }
50
+ //# sourceMappingURL=libp2p-stream-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"libp2p-stream-transport.d.ts","sourceRoot":"","sources":["../../../src/streaming/libp2p-stream-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,qBAAqB,EACtB,MAAM,eAAe,CAAC;AAUvB;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,gBAAgB;IAK1D,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,OAAO,CAAC,cAAc,CAAC,CAA6B;IACpD,OAAO,CAAC,MAAM,CAAkC;gBAG7B,MAAM,EAAE,MAAM,EAC/B,MAAM,CAAC,EAAE,qBAAqB;IAQhC;;OAEG;IACI,SAAS,IAAI,MAAM;IAI1B;;OAEG;IACG,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB3C;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;IAcpD;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAO5B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B;;OAEG;IACH,SAAS,IAAI,YAAY;IAkBzB;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;;;OAIG;IACG,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAe9D"}
@@ -0,0 +1,137 @@
1
+ import { StreamStatus, } from '@olane/o-core';
2
+ /**
3
+ * Default configuration for libp2p stream transport
4
+ */
5
+ const DEFAULT_CONFIG = {
6
+ drainTimeoutMs: 30000, // 30 seconds
7
+ readTimeoutMs: 120000, // 2 minutes
8
+ };
9
+ /**
10
+ * libp2p-specific implementation of IStreamTransport.
11
+ * Wraps a libp2p Stream and handles backpressure, message listening,
12
+ * and stream lifecycle management.
13
+ */
14
+ export class Libp2pStreamTransport {
15
+ constructor(stream, config) {
16
+ this.stream = stream;
17
+ this.config = {
18
+ ...DEFAULT_CONFIG,
19
+ ...config,
20
+ };
21
+ }
22
+ /**
23
+ * Get the underlying libp2p Stream (useful for advanced use cases)
24
+ */
25
+ getStream() {
26
+ return this.stream;
27
+ }
28
+ /**
29
+ * Send data through the stream with backpressure handling
30
+ */
31
+ async send(data) {
32
+ // Check stream status before sending
33
+ if (this.stream.status !== 'open') {
34
+ throw new Error(`Cannot send on stream with status: ${this.stream.status}`);
35
+ }
36
+ try {
37
+ // Attempt to send the data
38
+ const sent = this.stream.send(data);
39
+ // Handle backpressure if the buffer is full
40
+ if (!sent) {
41
+ // Wait for the stream to drain with timeout
42
+ await this.stream.onDrain({
43
+ signal: AbortSignal.timeout(this.config.drainTimeoutMs),
44
+ });
45
+ }
46
+ }
47
+ catch (error) {
48
+ throw new Error(`Failed to send data: ${error}`);
49
+ }
50
+ }
51
+ /**
52
+ * Set up a message handler for incoming data.
53
+ * IMPORTANT: For libp2p v3, this must be called synchronously after
54
+ * receiving the stream to prevent buffer overflow.
55
+ */
56
+ onMessage(handler) {
57
+ this.messageHandler = handler;
58
+ // Attach the message listener to the stream
59
+ // This is synchronous and must be done immediately for libp2p v3
60
+ this.stream.addEventListener('message', (event) => {
61
+ if (this.messageHandler) {
62
+ // Extract the data from the event
63
+ const data = event.detail;
64
+ this.messageHandler(data);
65
+ }
66
+ });
67
+ }
68
+ /**
69
+ * Remove the message handler
70
+ */
71
+ removeMessageHandler() {
72
+ this.messageHandler = undefined;
73
+ // Note: We don't remove the event listener because libp2p doesn't
74
+ // provide a clean way to do this. The handler being undefined
75
+ // effectively disables it.
76
+ }
77
+ /**
78
+ * Close the stream and clean up resources
79
+ */
80
+ async close() {
81
+ try {
82
+ if (this.stream.status === 'open' || this.stream.status === 'closing') {
83
+ await this.stream.close();
84
+ }
85
+ }
86
+ catch (error) {
87
+ console.error('Error closing stream:', error);
88
+ // Don't throw - closing errors are not critical
89
+ }
90
+ finally {
91
+ this.removeMessageHandler();
92
+ }
93
+ }
94
+ /**
95
+ * Get the current status of the stream
96
+ */
97
+ getStatus() {
98
+ // Map libp2p status to our StreamStatus enum
99
+ const status = this.stream.status;
100
+ switch (status) {
101
+ case 'open':
102
+ return StreamStatus.OPEN;
103
+ case 'closing':
104
+ return StreamStatus.CLOSING;
105
+ case 'closed':
106
+ return StreamStatus.CLOSED;
107
+ case 'reset':
108
+ return StreamStatus.RESET;
109
+ default:
110
+ return StreamStatus.CLOSED;
111
+ }
112
+ }
113
+ /**
114
+ * Check if the stream is in a usable state
115
+ */
116
+ isOpen() {
117
+ return this.stream.status === 'open';
118
+ }
119
+ /**
120
+ * Wait for the first message with timeout
121
+ * @param timeoutMs - Optional timeout in milliseconds (defaults to config.readTimeoutMs)
122
+ * @returns Promise that resolves with the first message
123
+ */
124
+ async waitForMessage(timeoutMs) {
125
+ const timeout = timeoutMs ?? this.config.readTimeoutMs;
126
+ return new Promise((resolve, reject) => {
127
+ const timer = setTimeout(() => {
128
+ this.removeMessageHandler();
129
+ reject(new Error(`Timeout waiting for message after ${timeout}ms`));
130
+ }, timeout);
131
+ this.onMessage((data) => {
132
+ clearTimeout(timer);
133
+ resolve(data);
134
+ });
135
+ });
136
+ }
137
+ }
@@ -0,0 +1,65 @@
1
+ import { StreamHandlerBase, StreamHandlerOptions } from '@olane/o-core';
2
+ import { oRequest } from '@olane/o-protocol';
3
+ import { Libp2pStreamTransport } from './libp2p-stream-transport.js';
4
+ /**
5
+ * Options for NodeStreamHandler
6
+ */
7
+ export interface NodeStreamHandlerOptions extends StreamHandlerOptions {
8
+ /**
9
+ * Enable success count tracking
10
+ */
11
+ trackSuccessCount?: boolean;
12
+ /**
13
+ * Enable error count tracking
14
+ */
15
+ trackErrorCount?: boolean;
16
+ }
17
+ /**
18
+ * o-node specific implementation of StreamHandlerBase.
19
+ * Integrates with libp2p streams and tracks metrics for o-node tools.
20
+ */
21
+ export declare class NodeStreamHandler extends StreamHandlerBase {
22
+ private successCount;
23
+ private errorCount;
24
+ private transport;
25
+ private nodeOptions;
26
+ constructor(transport: Libp2pStreamTransport, options?: NodeStreamHandlerOptions);
27
+ /**
28
+ * Get the success count (number of chunks successfully sent)
29
+ */
30
+ getSuccessCount(): number;
31
+ /**
32
+ * Get the error count
33
+ */
34
+ getErrorCount(): number;
35
+ /**
36
+ * Reset metrics
37
+ */
38
+ resetMetrics(): void;
39
+ /**
40
+ * Implementation of sendChunk using libp2p transport and protocol builder
41
+ */
42
+ protected sendChunk(chunk: unknown, sequence: number, isLast: boolean, request: oRequest): Promise<void>;
43
+ /**
44
+ * Hook: Called when streaming starts
45
+ */
46
+ protected onStreamStart(request: oRequest): void;
47
+ /**
48
+ * Hook: Called when streaming completes successfully
49
+ */
50
+ protected onStreamComplete(request: oRequest, totalChunks: number): void;
51
+ /**
52
+ * Hook: Called when streaming encounters an error
53
+ */
54
+ protected onStreamError(request: oRequest, error: any): void;
55
+ /**
56
+ * Reset the handler for reuse with a new transport
57
+ */
58
+ reset(): void;
59
+ /**
60
+ * Create a new NodeStreamHandler with a different transport
61
+ * (useful for handling multiple streams)
62
+ */
63
+ static create(transport: Libp2pStreamTransport, options?: NodeStreamHandlerOptions): NodeStreamHandler;
64
+ }
65
+ //# sourceMappingURL=node-stream-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-stream-handler.d.ts","sourceRoot":"","sources":["../../../src/streaming/node-stream-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,oBAAoB;IACpE;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,iBAAiB;IACtD,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,WAAW,CAA2B;gBAG5C,SAAS,EAAE,qBAAqB,EAChC,OAAO,GAAE,wBAA6B;IAWxC;;OAEG;IACI,eAAe,IAAI,MAAM;IAIhC;;OAEG;IACI,aAAa,IAAI,MAAM;IAI9B;;OAEG;IACI,YAAY,IAAI,IAAI;IAK3B;;OAEG;cACa,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,IAAI,CAAC;IA0BhB;;OAEG;cACgB,aAAa,CAAC,OAAO,EAAE,QAAQ,GAAG,IAAI;IAOzD;;OAEG;cACgB,gBAAgB,CACjC,OAAO,EAAE,QAAQ,EACjB,WAAW,EAAE,MAAM,GAClB,IAAI;IASP;;OAEG;cACgB,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAUrE;;OAEG;IACI,KAAK,IAAI,IAAI;IAOpB;;;OAGG;WACW,MAAM,CAClB,SAAS,EAAE,qBAAqB,EAChC,OAAO,CAAC,EAAE,wBAAwB,GACjC,iBAAiB;CAGrB"}
@@ -0,0 +1,101 @@
1
+ import { StreamHandlerBase, ProtocolBuilder, } from '@olane/o-core';
2
+ /**
3
+ * o-node specific implementation of StreamHandlerBase.
4
+ * Integrates with libp2p streams and tracks metrics for o-node tools.
5
+ */
6
+ export class NodeStreamHandler extends StreamHandlerBase {
7
+ constructor(transport, options = {}) {
8
+ super(options);
9
+ this.successCount = 0;
10
+ this.errorCount = 0;
11
+ this.transport = transport;
12
+ this.nodeOptions = {
13
+ trackSuccessCount: true,
14
+ trackErrorCount: true,
15
+ ...options,
16
+ };
17
+ }
18
+ /**
19
+ * Get the success count (number of chunks successfully sent)
20
+ */
21
+ getSuccessCount() {
22
+ return this.successCount;
23
+ }
24
+ /**
25
+ * Get the error count
26
+ */
27
+ getErrorCount() {
28
+ return this.errorCount;
29
+ }
30
+ /**
31
+ * Reset metrics
32
+ */
33
+ resetMetrics() {
34
+ this.successCount = 0;
35
+ this.errorCount = 0;
36
+ }
37
+ /**
38
+ * Implementation of sendChunk using libp2p transport and protocol builder
39
+ */
40
+ async sendChunk(chunk, sequence, isLast, request) {
41
+ // Build the JSON-RPC streaming chunk message
42
+ const message = ProtocolBuilder.buildStreamChunkFromRequest(chunk, sequence, isLast, request);
43
+ // Encode the message to bytes
44
+ const encoded = ProtocolBuilder.encodeMessage(message);
45
+ // Send through the transport (handles backpressure)
46
+ await this.transport.send(encoded);
47
+ // Track metrics if enabled
48
+ if (this.nodeOptions.trackSuccessCount) {
49
+ this.successCount++;
50
+ }
51
+ // Close the stream if this is the last chunk
52
+ if (isLast) {
53
+ await this.transport.close();
54
+ }
55
+ }
56
+ /**
57
+ * Hook: Called when streaming starts
58
+ */
59
+ onStreamStart(request) {
60
+ // Reset metrics for this stream
61
+ if (this.nodeOptions.enableMetrics) {
62
+ this.resetMetrics();
63
+ }
64
+ }
65
+ /**
66
+ * Hook: Called when streaming completes successfully
67
+ */
68
+ onStreamComplete(request, totalChunks) {
69
+ // Log completion if metrics enabled
70
+ if (this.nodeOptions.enableMetrics) {
71
+ console.log(`Stream completed for ${request.method}: ${totalChunks} chunks sent`);
72
+ }
73
+ }
74
+ /**
75
+ * Hook: Called when streaming encounters an error
76
+ */
77
+ onStreamError(request, error) {
78
+ // Track error count
79
+ if (this.nodeOptions.trackErrorCount) {
80
+ this.errorCount++;
81
+ }
82
+ // Log error
83
+ console.error(`Stream error for ${request.method}:`, error);
84
+ }
85
+ /**
86
+ * Reset the handler for reuse with a new transport
87
+ */
88
+ reset() {
89
+ // Call parent reset
90
+ this.state = 0; // Reset state (IDLE)
91
+ this.currentSequence = 0;
92
+ this.resetMetrics();
93
+ }
94
+ /**
95
+ * Create a new NodeStreamHandler with a different transport
96
+ * (useful for handling multiple streams)
97
+ */
98
+ static create(transport, options) {
99
+ return new NodeStreamHandler(transport, options);
100
+ }
101
+ }