@olane/o-node 0.7.12-alpha.39 → 0.7.12-alpha.40

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 (231) hide show
  1. package/dist/o-core/src/connection/index.d.ts +8 -0
  2. package/dist/o-core/src/connection/index.d.ts.map +1 -0
  3. package/dist/o-core/src/connection/index.js +7 -0
  4. package/dist/o-core/src/connection/interfaces/connection-manager.config.d.ts +15 -0
  5. package/dist/o-core/src/connection/interfaces/connection-manager.config.d.ts.map +1 -0
  6. package/dist/o-core/src/connection/interfaces/connection-manager.config.js +1 -0
  7. package/dist/o-core/src/connection/interfaces/connection-send-params.interface.d.ts +9 -0
  8. package/dist/o-core/src/connection/interfaces/connection-send-params.interface.d.ts.map +1 -0
  9. package/dist/o-core/src/connection/interfaces/connection-send-params.interface.js +1 -0
  10. package/dist/o-core/src/connection/interfaces/connection.config.d.ts +20 -0
  11. package/dist/o-core/src/connection/interfaces/connection.config.d.ts.map +1 -0
  12. package/dist/o-core/src/connection/interfaces/connection.config.js +1 -0
  13. package/dist/o-core/src/connection/interfaces/index.d.ts +5 -0
  14. package/dist/o-core/src/connection/interfaces/index.d.ts.map +1 -0
  15. package/dist/o-core/src/connection/interfaces/index.js +4 -0
  16. package/dist/o-core/src/connection/interfaces/request-state.enum.d.ts +7 -0
  17. package/dist/o-core/src/connection/interfaces/request-state.enum.d.ts.map +1 -0
  18. package/dist/o-core/src/connection/interfaces/request-state.enum.js +7 -0
  19. package/dist/o-core/src/connection/o-connection-manager.d.ts +19 -0
  20. package/dist/o-core/src/connection/o-connection-manager.d.ts.map +1 -0
  21. package/dist/o-core/src/connection/o-connection-manager.js +27 -0
  22. package/dist/o-core/src/connection/o-connection.d.ts +26 -0
  23. package/dist/o-core/src/connection/o-connection.d.ts.map +1 -0
  24. package/dist/o-core/src/connection/o-connection.js +54 -0
  25. package/dist/o-core/src/connection/o-request.d.ts +23 -0
  26. package/dist/o-core/src/connection/o-request.d.ts.map +1 -0
  27. package/dist/o-core/src/connection/o-request.js +42 -0
  28. package/dist/o-core/src/connection/o-response.d.ts +1 -0
  29. package/dist/o-core/src/connection/o-response.d.ts.map +1 -1
  30. package/dist/o-core/src/connection/o-response.js +7 -0
  31. package/dist/o-core/src/core/defaults/config.d.ts +4 -0
  32. package/dist/o-core/src/core/defaults/config.d.ts.map +1 -0
  33. package/dist/o-core/src/core/defaults/config.js +5 -0
  34. package/dist/o-core/src/core/defaults/index.d.ts +2 -0
  35. package/dist/o-core/src/core/defaults/index.d.ts.map +1 -0
  36. package/dist/o-core/src/core/defaults/index.js +1 -0
  37. package/dist/o-core/src/core/graceful-shutdown.d.ts +25 -0
  38. package/dist/o-core/src/core/graceful-shutdown.d.ts.map +1 -0
  39. package/dist/o-core/src/core/graceful-shutdown.js +84 -0
  40. package/dist/o-core/src/core/index.d.ts +9 -0
  41. package/dist/o-core/src/core/index.d.ts.map +1 -0
  42. package/dist/o-core/src/core/index.js +8 -0
  43. package/dist/o-core/src/core/interfaces/index.d.ts +7 -0
  44. package/dist/o-core/src/core/interfaces/index.d.ts.map +1 -0
  45. package/dist/o-core/src/core/interfaces/index.js +6 -0
  46. package/dist/o-core/src/core/interfaces/node-type.enum.d.ts +10 -0
  47. package/dist/o-core/src/core/interfaces/node-type.enum.d.ts.map +1 -0
  48. package/dist/o-core/src/core/interfaces/node-type.enum.js +10 -0
  49. package/dist/o-core/src/core/interfaces/o-core.config.d.ts +23 -0
  50. package/dist/o-core/src/core/interfaces/o-core.config.d.ts.map +1 -0
  51. package/dist/o-core/src/core/interfaces/o-core.config.js +1 -0
  52. package/dist/o-core/src/core/interfaces/o-core.interface.d.ts +18 -0
  53. package/dist/o-core/src/core/interfaces/o-core.interface.d.ts.map +1 -0
  54. package/dist/o-core/src/core/interfaces/o-core.interface.js +1 -0
  55. package/dist/o-core/src/core/interfaces/state.enum.d.ts +8 -0
  56. package/dist/o-core/src/core/interfaces/state.enum.d.ts.map +1 -0
  57. package/dist/o-core/src/core/interfaces/state.enum.js +8 -0
  58. package/dist/o-core/src/core/interfaces/use-options.interface.d.ts +11 -0
  59. package/dist/o-core/src/core/interfaces/use-options.interface.d.ts.map +1 -0
  60. package/dist/o-core/src/core/interfaces/use-options.interface.js +1 -0
  61. package/dist/o-core/src/core/interfaces/use-stream-options.interface.d.ts +4 -0
  62. package/dist/o-core/src/core/interfaces/use-stream-options.interface.d.ts.map +1 -0
  63. package/dist/o-core/src/core/interfaces/use-stream-options.interface.js +1 -0
  64. package/dist/o-core/src/core/lib/events/connection-events.d.ts +31 -0
  65. package/dist/o-core/src/core/lib/events/connection-events.d.ts.map +1 -0
  66. package/dist/o-core/src/core/lib/events/connection-events.js +46 -0
  67. package/dist/o-core/src/core/lib/events/hierarchy-events.d.ts +69 -0
  68. package/dist/o-core/src/core/lib/events/hierarchy-events.d.ts.map +1 -0
  69. package/dist/o-core/src/core/lib/events/hierarchy-events.js +100 -0
  70. package/dist/o-core/src/core/lib/events/index.d.ts +6 -0
  71. package/dist/o-core/src/core/lib/events/index.d.ts.map +1 -0
  72. package/dist/o-core/src/core/lib/events/index.js +5 -0
  73. package/dist/o-core/src/core/lib/events/node-events.d.ts +40 -0
  74. package/dist/o-core/src/core/lib/events/node-events.d.ts.map +1 -0
  75. package/dist/o-core/src/core/lib/events/node-events.js +58 -0
  76. package/dist/o-core/src/core/lib/events/o-notification-event.d.ts +26 -0
  77. package/dist/o-core/src/core/lib/events/o-notification-event.d.ts.map +1 -0
  78. package/dist/o-core/src/core/lib/events/o-notification-event.js +30 -0
  79. package/dist/o-core/src/core/lib/index.d.ts +8 -0
  80. package/dist/o-core/src/core/lib/index.d.ts.map +1 -0
  81. package/dist/o-core/src/core/lib/index.js +7 -0
  82. package/dist/o-core/src/core/lib/interfaces/notification-types.d.ts +49 -0
  83. package/dist/o-core/src/core/lib/interfaces/notification-types.d.ts.map +1 -0
  84. package/dist/o-core/src/core/lib/interfaces/notification-types.js +1 -0
  85. package/dist/o-core/src/core/lib/o-hierarchy.manager.d.ts +24 -0
  86. package/dist/o-core/src/core/lib/o-hierarchy.manager.d.ts.map +1 -0
  87. package/dist/o-core/src/core/lib/o-hierarchy.manager.js +58 -0
  88. package/dist/o-core/src/core/lib/o-metrics.d.ts +5 -0
  89. package/dist/o-core/src/core/lib/o-metrics.d.ts.map +1 -0
  90. package/dist/o-core/src/core/lib/o-metrics.js +6 -0
  91. package/dist/o-core/src/core/lib/o-notification.manager.d.ts +58 -0
  92. package/dist/o-core/src/core/lib/o-notification.manager.d.ts.map +1 -0
  93. package/dist/o-core/src/core/lib/o-notification.manager.js +159 -0
  94. package/dist/o-core/src/core/lib/o-request.manager.d.ts +10 -0
  95. package/dist/o-core/src/core/lib/o-request.manager.d.ts.map +1 -0
  96. package/dist/o-core/src/core/lib/o-request.manager.js +18 -0
  97. package/dist/o-core/src/core/lib/utils/event-filters.d.ts +38 -0
  98. package/dist/o-core/src/core/lib/utils/event-filters.d.ts.map +1 -0
  99. package/dist/o-core/src/core/lib/utils/event-filters.js +159 -0
  100. package/dist/o-core/src/core/o-core.d.ts +240 -0
  101. package/dist/o-core/src/core/o-core.d.ts.map +1 -0
  102. package/dist/o-core/src/core/o-core.js +463 -0
  103. package/dist/o-core/src/core/o-dependency.d.ts +9 -0
  104. package/dist/o-core/src/core/o-dependency.d.ts.map +1 -0
  105. package/dist/o-core/src/core/o-dependency.js +15 -0
  106. package/dist/o-core/src/core/o-object.d.ts +7 -0
  107. package/dist/o-core/src/core/o-object.d.ts.map +1 -0
  108. package/dist/o-core/src/core/o-object.js +10 -0
  109. package/dist/o-core/src/core/o-parameter.d.ts +12 -0
  110. package/dist/o-core/src/core/o-parameter.d.ts.map +1 -0
  111. package/dist/o-core/src/core/o-parameter.js +21 -0
  112. package/dist/o-core/src/error/index.d.ts +3 -0
  113. package/dist/o-core/src/error/index.d.ts.map +1 -0
  114. package/dist/o-core/src/error/index.js +2 -0
  115. package/dist/o-core/src/index.d.ts +8 -0
  116. package/dist/o-core/src/index.d.ts.map +1 -0
  117. package/dist/o-core/src/index.js +7 -0
  118. package/dist/o-core/src/response/index.d.ts +2 -0
  119. package/dist/o-core/src/response/index.d.ts.map +1 -0
  120. package/dist/o-core/src/response/index.js +1 -0
  121. package/dist/o-core/src/response/response-builder.d.ts +140 -0
  122. package/dist/o-core/src/response/response-builder.d.ts.map +1 -0
  123. package/dist/o-core/src/response/response-builder.js +190 -0
  124. package/dist/o-core/src/router/enums/restricted-addresses.enum.d.ts +8 -0
  125. package/dist/o-core/src/router/enums/restricted-addresses.enum.d.ts.map +1 -0
  126. package/dist/o-core/src/router/enums/restricted-addresses.enum.js +13 -0
  127. package/dist/o-core/src/router/index.d.ts +11 -0
  128. package/dist/o-core/src/router/index.d.ts.map +1 -0
  129. package/dist/o-core/src/router/index.js +10 -0
  130. package/dist/o-core/src/router/interfaces/resolve.request.d.ts +10 -0
  131. package/dist/o-core/src/router/interfaces/resolve.request.d.ts.map +1 -0
  132. package/dist/o-core/src/router/interfaces/resolve.request.js +1 -0
  133. package/dist/o-core/src/router/interfaces/route.response.d.ts +8 -0
  134. package/dist/o-core/src/router/interfaces/route.response.d.ts.map +1 -0
  135. package/dist/o-core/src/router/interfaces/route.response.js +1 -0
  136. package/dist/o-core/src/router/o-address-resolver.d.ts +14 -0
  137. package/dist/o-core/src/router/o-address-resolver.d.ts.map +1 -0
  138. package/dist/o-core/src/router/o-address-resolver.js +19 -0
  139. package/dist/o-core/src/router/o-address.d.ts +33 -0
  140. package/dist/o-core/src/router/o-address.d.ts.map +1 -0
  141. package/dist/o-core/src/router/o-address.js +114 -0
  142. package/dist/o-core/src/router/o-request-preparation.d.ts +37 -0
  143. package/dist/o-core/src/router/o-request-preparation.d.ts.map +1 -0
  144. package/dist/o-core/src/router/o-request-preparation.js +75 -0
  145. package/dist/o-core/src/router/o-request.router.d.ts +18 -0
  146. package/dist/o-core/src/router/o-request.router.d.ts.map +1 -0
  147. package/dist/o-core/src/router/o-request.router.js +12 -0
  148. package/dist/o-core/src/router/o-resolver-chain.d.ts +32 -0
  149. package/dist/o-core/src/router/o-resolver-chain.d.ts.map +1 -0
  150. package/dist/o-core/src/router/o-resolver-chain.js +62 -0
  151. package/dist/o-core/src/router/o-router.d.ts +19 -0
  152. package/dist/o-core/src/router/o-router.d.ts.map +1 -0
  153. package/dist/o-core/src/router/o-router.js +14 -0
  154. package/dist/o-core/src/router/o-routing-policy.d.ts +36 -0
  155. package/dist/o-core/src/router/o-routing-policy.d.ts.map +1 -0
  156. package/dist/o-core/src/router/o-routing-policy.js +19 -0
  157. package/dist/o-core/src/transports/custom.transport.d.ts +6 -0
  158. package/dist/o-core/src/transports/custom.transport.d.ts.map +1 -0
  159. package/dist/o-core/src/transports/custom.transport.js +10 -0
  160. package/dist/o-core/src/transports/index.d.ts +4 -0
  161. package/dist/o-core/src/transports/index.d.ts.map +1 -0
  162. package/dist/o-core/src/transports/index.js +3 -0
  163. package/dist/o-core/src/transports/interfaces/transport-type.enum.d.ts +5 -0
  164. package/dist/o-core/src/transports/interfaces/transport-type.enum.d.ts.map +1 -0
  165. package/dist/o-core/src/transports/interfaces/transport-type.enum.js +5 -0
  166. package/dist/o-core/src/transports/o-transport.d.ts +10 -0
  167. package/dist/o-core/src/transports/o-transport.d.ts.map +1 -0
  168. package/dist/o-core/src/transports/o-transport.js +16 -0
  169. package/dist/o-core/src/utils/core.utils.d.ts +34 -0
  170. package/dist/o-core/src/utils/core.utils.d.ts.map +1 -0
  171. package/dist/o-core/src/utils/core.utils.js +123 -0
  172. package/dist/o-core/src/utils/index.d.ts +6 -0
  173. package/dist/o-core/src/utils/index.d.ts.map +1 -0
  174. package/dist/o-core/src/utils/index.js +5 -0
  175. package/dist/o-core/src/utils/logger.d.ts +14 -0
  176. package/dist/o-core/src/utils/logger.d.ts.map +1 -0
  177. package/dist/o-core/src/utils/logger.js +31 -0
  178. package/dist/o-core/src/utils/object.utils.d.ts +5 -0
  179. package/dist/o-core/src/utils/object.utils.d.ts.map +1 -0
  180. package/dist/o-core/src/utils/object.utils.js +23 -0
  181. package/dist/o-core/src/utils/regex.utils.d.ts +4 -0
  182. package/dist/o-core/src/utils/regex.utils.d.ts.map +1 -0
  183. package/dist/o-core/src/utils/regex.utils.js +13 -0
  184. package/dist/o-core/src/utils/remote.utils.d.ts +4 -0
  185. package/dist/o-core/src/utils/remote.utils.d.ts.map +1 -0
  186. package/dist/o-core/src/utils/remote.utils.js +5 -0
  187. package/dist/o-node/src/connection/o-node-connection.d.ts +2 -2
  188. package/dist/o-node/src/connection/o-node-connection.d.ts.map +1 -1
  189. package/dist/o-node/src/connection/o-node-connection.js +36 -23
  190. package/dist/o-node/src/connection/o-node-connection.manager.d.ts.map +1 -1
  191. package/dist/o-node/src/connection/o-node-connection.manager.js +13 -41
  192. package/dist/o-node/src/index.d.ts +1 -0
  193. package/dist/o-node/src/index.d.ts.map +1 -1
  194. package/dist/o-node/src/index.js +1 -0
  195. package/dist/o-node/src/interfaces/o-node.config.d.ts +0 -17
  196. package/dist/o-node/src/interfaces/o-node.config.d.ts.map +1 -1
  197. package/dist/o-node/src/managers/o-connection-heartbeat.manager.d.ts +1 -0
  198. package/dist/o-node/src/managers/o-connection-heartbeat.manager.d.ts.map +1 -1
  199. package/dist/o-node/src/managers/o-connection-heartbeat.manager.js +17 -3
  200. package/dist/o-node/src/o-node.d.ts +11 -12
  201. package/dist/o-node/src/o-node.d.ts.map +1 -1
  202. package/dist/o-node/src/o-node.js +104 -25
  203. package/dist/o-node/src/o-node.notification-manager.js +4 -1
  204. package/dist/o-node/src/o-node.tool.d.ts.map +1 -1
  205. package/dist/o-node/src/o-node.tool.js +16 -23
  206. package/dist/o-node/src/router/o-node.router.d.ts +1 -0
  207. package/dist/o-node/src/router/o-node.router.d.ts.map +1 -1
  208. package/dist/o-node/src/router/o-node.router.js +53 -7
  209. package/dist/o-node/src/router/resolvers/o-node.resolver.d.ts.map +1 -1
  210. package/dist/o-node/src/router/resolvers/o-node.resolver.js +5 -1
  211. package/dist/o-node/src/ui/index.d.ts +3 -0
  212. package/dist/o-node/src/ui/index.d.ts.map +1 -0
  213. package/dist/o-node/src/ui/index.js +2 -0
  214. package/dist/o-node/src/ui/types.d.ts +110 -0
  215. package/dist/o-node/src/ui/types.d.ts.map +1 -0
  216. package/dist/o-node/src/ui/types.js +17 -0
  217. package/dist/o-node/src/ui/ui-graph.manager.d.ts +70 -0
  218. package/dist/o-node/src/ui/ui-graph.manager.d.ts.map +1 -0
  219. package/dist/o-node/src/ui/ui-graph.manager.js +274 -0
  220. package/dist/o-node/src/utils/index.d.ts +0 -2
  221. package/dist/o-node/src/utils/index.d.ts.map +1 -1
  222. package/dist/o-node/src/utils/index.js +0 -2
  223. package/dist/o-node/src/utils/stream.utils.d.ts.map +1 -1
  224. package/dist/o-node/src/utils/stream.utils.js +25 -21
  225. package/dist/o-node/test/helpers/test-node.tool.d.ts +15 -0
  226. package/dist/o-node/test/helpers/test-node.tool.d.ts.map +1 -0
  227. package/dist/o-node/test/helpers/test-node.tool.js +27 -0
  228. package/dist/src/connection/o-node-connection.manager.d.ts +14 -4
  229. package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
  230. package/dist/src/connection/o-node-connection.manager.js +61 -29
  231. package/package.json +6 -6
@@ -0,0 +1,274 @@
1
+ import { oNodeTool } from '../o-node.tool';
2
+ import { oRequest } from '../../../o-core/src';
3
+ import { oAddress } from '../../../o-core/src';
4
+ /**
5
+ * UIGraphManager manages the hierarchical graph of UI components
6
+ * Acts as a centralized registry for all UI elements in the application
7
+ */
8
+ export class UIGraphManager extends oNodeTool {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.componentRegistry = new Map();
12
+ this.methodHandlers = {};
13
+ }
14
+ /**
15
+ * Register a new UI component in the graph
16
+ */
17
+ async _tool_register_component(request) {
18
+ const { id, type, address, props = {}, state = {}, parentId = null, methods = [], metadata = {}, } = request.params;
19
+ this.logger.info(`Registering component: ${id} (${type})`);
20
+ // Check if component already exists
21
+ if (this.componentRegistry.has(id)) {
22
+ this.logger.warn(`Component ${id} already registered, updating instead`);
23
+ const updateRequest = new oRequest({
24
+ method: 'update_component',
25
+ params: { nodeId: id, props, state, metadata },
26
+ id: request.id,
27
+ });
28
+ await this._tool_update_component(updateRequest);
29
+ return {
30
+ success: true,
31
+ nodeId: id,
32
+ address: address,
33
+ message: 'Component already exists, updated instead',
34
+ };
35
+ }
36
+ const now = Date.now();
37
+ // Create component node
38
+ const componentNode = {
39
+ id,
40
+ type,
41
+ address: new oAddress(address),
42
+ props,
43
+ state,
44
+ parentId,
45
+ childIds: [],
46
+ methods,
47
+ registeredAt: now,
48
+ updatedAt: now,
49
+ metadata,
50
+ };
51
+ // Add to registry
52
+ this.componentRegistry.set(id, componentNode);
53
+ // If has parent, add as child to parent
54
+ if (parentId) {
55
+ const parent = this.componentRegistry.get(parentId);
56
+ if (parent) {
57
+ if (!parent.childIds.includes(id)) {
58
+ parent.childIds.push(id);
59
+ parent.updatedAt = now;
60
+ }
61
+ }
62
+ else {
63
+ this.logger.warn(`Parent ${parentId} not found for component ${id}, will register as orphan`);
64
+ }
65
+ }
66
+ this.logger.info(`Component ${id} registered successfully. Total components: ${this.componentRegistry.size}`);
67
+ return {
68
+ success: true,
69
+ nodeId: id,
70
+ address: componentNode.address.toString(),
71
+ message: 'Component registered successfully',
72
+ };
73
+ }
74
+ /**
75
+ * Unregister a UI component from the graph
76
+ */
77
+ async _tool_unregister_component(request) {
78
+ const { nodeId } = request.params;
79
+ this.logger.info(`Unregistering component: ${nodeId}`);
80
+ const component = this.componentRegistry.get(nodeId);
81
+ if (!component) {
82
+ this.logger.warn(`Component ${nodeId} not found`);
83
+ return {
84
+ success: false,
85
+ message: 'Component not found',
86
+ };
87
+ }
88
+ // Remove from parent's children
89
+ if (component.parentId) {
90
+ const parent = this.componentRegistry.get(component.parentId);
91
+ if (parent) {
92
+ parent.childIds = parent.childIds.filter((id) => id !== nodeId);
93
+ parent.updatedAt = Date.now();
94
+ }
95
+ }
96
+ // Recursively unregister all children
97
+ for (const childId of component.childIds) {
98
+ const childRequest = new oRequest({
99
+ method: 'unregister_component',
100
+ params: { nodeId: childId },
101
+ id: request.id,
102
+ });
103
+ await this._tool_unregister_component(childRequest);
104
+ }
105
+ // Remove method handlers
106
+ delete this.methodHandlers[nodeId];
107
+ // Remove from registry
108
+ this.componentRegistry.delete(nodeId);
109
+ this.logger.info(`Component ${nodeId} unregistered. Total components: ${this.componentRegistry.size}`);
110
+ return {
111
+ success: true,
112
+ message: 'Component unregistered successfully',
113
+ };
114
+ }
115
+ /**
116
+ * Update component props, state, or metadata
117
+ */
118
+ async _tool_update_component(request) {
119
+ const { nodeId, props, state, metadata } = request.params;
120
+ const component = this.componentRegistry.get(nodeId);
121
+ if (!component) {
122
+ this.logger.warn(`Component ${nodeId} not found for update`);
123
+ return {
124
+ success: false,
125
+ message: 'Component not found',
126
+ };
127
+ }
128
+ // Update props
129
+ if (props) {
130
+ component.props = { ...component.props, ...props };
131
+ }
132
+ // Update state
133
+ if (state) {
134
+ component.state = { ...component.state, ...state };
135
+ }
136
+ // Update metadata
137
+ if (metadata) {
138
+ component.metadata = { ...component.metadata, ...metadata };
139
+ }
140
+ component.updatedAt = Date.now();
141
+ this.logger.debug(`Component ${nodeId} updated`);
142
+ return {
143
+ success: true,
144
+ message: 'Component updated successfully',
145
+ };
146
+ }
147
+ /**
148
+ * Invoke a method on a component
149
+ */
150
+ async _tool_invoke_action(request) {
151
+ const { nodeId, method, params } = request.params;
152
+ this.logger.info(`Invoking ${method} on component ${nodeId}`);
153
+ const component = this.componentRegistry.get(nodeId);
154
+ if (!component) {
155
+ throw new Error(`Component ${nodeId} not found`);
156
+ }
157
+ if (!component.methods.includes(method)) {
158
+ throw new Error(`Method ${method} not available on component ${nodeId}`);
159
+ }
160
+ // Get method handler
161
+ const handler = this.methodHandlers[nodeId]?.[method];
162
+ if (!handler) {
163
+ throw new Error(`Method handler for ${method} not registered for component ${nodeId}`);
164
+ }
165
+ // Invoke handler
166
+ const result = await handler(params);
167
+ this.logger.debug(`Method ${method} invoked on ${nodeId}`);
168
+ return {
169
+ success: true,
170
+ result,
171
+ };
172
+ }
173
+ /**
174
+ * Query component hierarchy
175
+ */
176
+ async _tool_query_hierarchy(request) {
177
+ const { nodeId } = request.params;
178
+ const component = this.componentRegistry.get(nodeId);
179
+ if (!component) {
180
+ throw new Error(`Component ${nodeId} not found`);
181
+ }
182
+ // Get children
183
+ const children = component.childIds
184
+ .map((id) => this.componentRegistry.get(id))
185
+ .filter((c) => c !== undefined);
186
+ // Get parent
187
+ const parent = component.parentId
188
+ ? this.componentRegistry.get(component.parentId) || null
189
+ : null;
190
+ return {
191
+ node: component,
192
+ children,
193
+ parent,
194
+ };
195
+ }
196
+ /**
197
+ * Get all registered components (for debugging)
198
+ */
199
+ async _tool_list_components(request) {
200
+ const components = Array.from(this.componentRegistry.values());
201
+ return {
202
+ components,
203
+ count: components.length,
204
+ };
205
+ }
206
+ /**
207
+ * Get component tree structure
208
+ */
209
+ async _tool_get_tree(request) {
210
+ // Find root components (those without parents)
211
+ const roots = Array.from(this.componentRegistry.values()).filter((c) => !c.parentId);
212
+ const buildTree = (node) => {
213
+ const children = node.childIds
214
+ .map((id) => this.componentRegistry.get(id))
215
+ .filter((c) => c !== undefined)
216
+ .map((c) => buildTree(c));
217
+ return {
218
+ id: node.id,
219
+ type: node.type,
220
+ address: node.address.toString(),
221
+ props: node.props,
222
+ metadata: node.metadata,
223
+ children,
224
+ };
225
+ };
226
+ return {
227
+ roots: roots.map((r) => buildTree(r)),
228
+ };
229
+ }
230
+ /**
231
+ * Register a method handler for a component
232
+ * This is called from the client side to register callbacks
233
+ */
234
+ registerMethodHandler(nodeId, method, handler) {
235
+ if (!this.methodHandlers[nodeId]) {
236
+ this.methodHandlers[nodeId] = {};
237
+ }
238
+ this.methodHandlers[nodeId][method] = handler;
239
+ this.logger.debug(`Method handler ${method} registered for ${nodeId}`);
240
+ }
241
+ /**
242
+ * Unregister all method handlers for a component
243
+ */
244
+ unregisterMethodHandlers(nodeId) {
245
+ delete this.methodHandlers[nodeId];
246
+ this.logger.debug(`Method handlers unregistered for ${nodeId}`);
247
+ }
248
+ /**
249
+ * Get component by ID
250
+ */
251
+ getComponent(nodeId) {
252
+ return this.componentRegistry.get(nodeId);
253
+ }
254
+ /**
255
+ * Get all children of a component
256
+ */
257
+ getComponentChildren(nodeId) {
258
+ const component = this.componentRegistry.get(nodeId);
259
+ if (!component)
260
+ return [];
261
+ return component.childIds
262
+ .map((id) => this.componentRegistry.get(id))
263
+ .filter((c) => c !== undefined);
264
+ }
265
+ /**
266
+ * Get parent of a component
267
+ */
268
+ getParent(nodeId) {
269
+ const component = this.componentRegistry.get(nodeId);
270
+ if (!component || !component.parentId)
271
+ return null;
272
+ return this.componentRegistry.get(component.parentId) || null;
273
+ }
274
+ }
@@ -1,5 +1,3 @@
1
1
  export * from './stream.utils.js';
2
2
  export * from './network.utils.js';
3
- export * from './circuit-breaker.js';
4
- export * from './leader-request-wrapper.js';
5
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
@@ -1,4 +1,2 @@
1
1
  export * from './stream.utils.js';
2
2
  export * from './network.utils.js';
3
- export * from './circuit-breaker.js';
4
- export * from './leader-request-wrapper.js';
@@ -1 +1 @@
1
- {"version":3,"file":"stream.utils.d.ts","sourceRoot":"","sources":["../../../../src/utils/stream.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAa,OAAO,EAAE,QAAQ,EAAa,MAAM,eAAe,CAAC;AAExE,qBAAa,WAAY,SAAQ,OAAO;WAClB,gBAAgB,CAClC,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,GAAG,CAAC;CA8BhB"}
1
+ {"version":3,"file":"stream.utils.d.ts","sourceRoot":"","sources":["../../../../src/utils/stream.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAEL,OAAO,EACP,QAAQ,EAGT,MAAM,eAAe,CAAC;AAEvB,qBAAa,WAAY,SAAQ,OAAO;WAClB,gBAAgB,CAClC,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,GAAG,CAAC;CA6BhB"}
@@ -1,27 +1,31 @@
1
- import { CoreUtils, oObject, oResponse } from '@olane/o-core';
1
+ import { CoreUtils, oObject, ResponseBuilder, } from '@olane/o-core';
2
2
  export class StreamUtils extends oObject {
3
3
  static async processGenerator(request, generator, stream) {
4
4
  const utils = new StreamUtils();
5
- for await (const result of generator) {
6
- utils.logger.debug('Sending stream response: ', result);
7
- await CoreUtils.sendStreamResponse(new oResponse({
8
- id: request.id,
9
- data: result,
10
- _last: false,
11
- _requestMethod: request.method,
12
- _connectionId: request.params?._connectionId,
13
- }), stream);
5
+ const responseBuilder = ResponseBuilder.create();
6
+ let aggregatedResult = '';
7
+ try {
8
+ // Send each chunk from the generator
9
+ // result should not be an oResponse, but rather a key value pair dict
10
+ for await (const result of generator) {
11
+ if (result.delta) {
12
+ aggregatedResult += result.delta;
13
+ }
14
+ const chunkResponse = await responseBuilder.buildChunk(request, result);
15
+ await CoreUtils.sendStreamResponse(chunkResponse, stream);
16
+ }
17
+ return {
18
+ message: aggregatedResult,
19
+ };
20
+ }
21
+ catch (error) {
22
+ // If error occurs during streaming, send error response
23
+ const errorResponse = await responseBuilder.buildError(request, error, {
24
+ isStream: true,
25
+ isLast: true,
26
+ });
27
+ await CoreUtils.sendStreamResponse(errorResponse, stream);
28
+ throw error;
14
29
  }
15
- await CoreUtils.sendStreamResponse(new oResponse({
16
- id: request.id,
17
- data: 'Stream completed',
18
- _last: true,
19
- _requestMethod: request.method,
20
- _connectionId: request.params?._connectionId,
21
- }), stream);
22
- return Promise.resolve({
23
- success: true,
24
- response: 'Stream started',
25
- });
26
30
  }
27
31
  }
@@ -0,0 +1,15 @@
1
+ import { oNodeTool } from '../../src/o-node.tool.js';
2
+ /**
3
+ * Test-only extension of oNodeTool that adds streaming test methods.
4
+ * This class should only be used in test files and is not part of the production code.
5
+ */
6
+ export declare class TestNodeTool extends oNodeTool {
7
+ /**
8
+ * Test method that emits chunks for 10 seconds at 100ms intervals.
9
+ * Used for testing streaming functionality across hierarchical networks.
10
+ *
11
+ * @returns AsyncGenerator that yields 100 chunks over 10 seconds
12
+ */
13
+ _tool_test_stream(): AsyncGenerator<any>;
14
+ }
15
+ //# sourceMappingURL=test-node.tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-node.tool.d.ts","sourceRoot":"","sources":["../../../../test/helpers/test-node.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD;;;GAGG;AACH,qBAAa,YAAa,SAAQ,SAAS;IACzC;;;;;OAKG;IACI,iBAAiB,IAAI,cAAc,CAAC,GAAG,CAAC;CAehD"}
@@ -0,0 +1,27 @@
1
+ import { oNodeTool } from '../../src/o-node.tool.js';
2
+ /**
3
+ * Test-only extension of oNodeTool that adds streaming test methods.
4
+ * This class should only be used in test files and is not part of the production code.
5
+ */
6
+ export class TestNodeTool extends oNodeTool {
7
+ /**
8
+ * Test method that emits chunks for 10 seconds at 100ms intervals.
9
+ * Used for testing streaming functionality across hierarchical networks.
10
+ *
11
+ * @returns AsyncGenerator that yields 100 chunks over 10 seconds
12
+ */
13
+ async *_tool_test_stream() {
14
+ const totalDuration = 10000; // 10 seconds
15
+ const intervalMs = 100; // 100ms between chunks
16
+ const totalChunks = totalDuration / intervalMs; // 100 chunks
17
+ for (let i = 0; i < totalChunks; i++) {
18
+ yield {
19
+ chunk: i + 1,
20
+ timestamp: new Date().toISOString(),
21
+ nodeAddress: this.address.toString(),
22
+ message: `Chunk ${i + 1} of ${totalChunks}`,
23
+ };
24
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
25
+ }
26
+ }
27
+ }
@@ -1,5 +1,5 @@
1
1
  import { oAddress, oConnectionConfig, oConnectionManager } from '@olane/o-core';
2
- import { oConnection } from '@olane/o-core';
2
+ import { Connection } from '@olane/o-config';
3
3
  import { oNodeConnectionManagerConfig } from './interfaces/o-node-connection-manager.config.js';
4
4
  import { oNodeConnection } from './o-node-connection.js';
5
5
  export declare class oNodeConnectionManager extends oConnectionManager {
@@ -8,12 +8,22 @@ export declare class oNodeConnectionManager extends oConnectionManager {
8
8
  private defaultDrainTimeoutMs?;
9
9
  constructor(config: oNodeConnectionManagerConfig);
10
10
  /**
11
- * Connect to a given address with exponential backoff retry
12
- * @param address - The address to connect to
11
+ * Connect to a given address, reusing libp2p connections when possible
12
+ * @param config - Connection configuration
13
13
  * @returns The connection object
14
14
  */
15
15
  connect(config: oConnectionConfig): Promise<oNodeConnection>;
16
+ /**
17
+ * Check if libp2p has an active connection to the target peer
18
+ * @param address - The address to check
19
+ * @returns true if an active connection exists
20
+ */
16
21
  isCached(address: oAddress): boolean;
17
- getCachedConnection(address: oAddress): oConnection | null;
22
+ /**
23
+ * Get an existing libp2p connection to the target peer
24
+ * @param address - The address to get a connection for
25
+ * @returns The libp2p Connection object or null if not found
26
+ */
27
+ getCachedLibp2pConnection(address: oAddress): Connection | null;
18
28
  }
19
29
  //# sourceMappingURL=o-node-connection.manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"o-node-connection.manager.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAC5D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAAS;gBAE3B,MAAM,EAAE,4BAA4B;IAOhD;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAmDlE,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAIpC,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,WAAW,GAAG,IAAI;CAe3D"}
1
+ {"version":3,"file":"o-node-connection.manager.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAU,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAC5D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAAS;gBAE3B,MAAM,EAAE,4BAA4B;IAOhD;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IA+ClE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IA2BpC;;;;OAIG;IACH,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,UAAU,GAAG,IAAI;CA2BhE"}
@@ -1,4 +1,5 @@
1
1
  import { oConnectionManager } from '@olane/o-core';
2
+ import { peerIdFromString } from '@libp2p/peer-id';
2
3
  import { oNodeConnection } from './o-node-connection.js';
3
4
  export class oNodeConnectionManager extends oConnectionManager {
4
5
  constructor(config) {
@@ -8,28 +9,24 @@ export class oNodeConnectionManager extends oConnectionManager {
8
9
  this.defaultDrainTimeoutMs = config.defaultDrainTimeoutMs;
9
10
  }
10
11
  /**
11
- * Connect to a given address with exponential backoff retry
12
- * @param address - The address to connect to
12
+ * Connect to a given address, reusing libp2p connections when possible
13
+ * @param config - Connection configuration
13
14
  * @returns The connection object
14
15
  */
15
16
  async connect(config) {
16
17
  const { address, nextHopAddress, callerAddress, readTimeoutMs, drainTimeoutMs, } = config;
17
- // check if we already have a connection to this address
18
- // TODO: how can we enable caching of connections & connection lifecycles
19
- if (this.isCached(nextHopAddress)) {
20
- const cachedConnection = this.getCachedConnection(nextHopAddress);
21
- if (cachedConnection &&
22
- cachedConnection.p2pConnection.status === 'open') {
23
- this.logger.debug('Using cached connection for address: ' + address.toString());
24
- return cachedConnection;
25
- }
26
- else {
27
- // cached item is not valid, remove it
28
- this.cache.delete(nextHopAddress.toString());
29
- }
18
+ // Check if libp2p already has an active connection to this peer
19
+ const existingConnection = this.getCachedLibp2pConnection(nextHopAddress);
20
+ let p2pConnection;
21
+ if (existingConnection && existingConnection.status === 'open') {
22
+ this.logger.debug('Reusing existing libp2p connection for address: ' + address.toString());
23
+ p2pConnection = existingConnection;
24
+ }
25
+ else {
26
+ // No existing connection or connection is closed, dial a new one
27
+ this.logger.debug('Dialing new connection for address: ' + address.toString());
28
+ p2pConnection = await this.p2pNode.dial(nextHopAddress.libp2pTransports.map((ma) => ma.toMultiaddr()));
30
29
  }
31
- // Retry configuration for handling transient connection failures
32
- const p2pConnection = await this.p2pNode.dial(nextHopAddress.libp2pTransports.map((ma) => ma.toMultiaddr()));
33
30
  const connection = new oNodeConnection({
34
31
  nextHopAddress: nextHopAddress,
35
32
  address: address,
@@ -40,26 +37,61 @@ export class oNodeConnectionManager extends oConnectionManager {
40
37
  isStream: config.isStream ?? false,
41
38
  abortSignal: config.abortSignal,
42
39
  });
43
- // this.cache.set(nextHopAddress.toString(), connection);
44
40
  return connection;
45
41
  }
42
+ /**
43
+ * Check if libp2p has an active connection to the target peer
44
+ * @param address - The address to check
45
+ * @returns true if an active connection exists
46
+ */
46
47
  isCached(address) {
47
- return this.cache.has(address.toString());
48
+ try {
49
+ const nodeAddress = address;
50
+ if (!nodeAddress.libp2pTransports ||
51
+ nodeAddress.libp2pTransports.length === 0) {
52
+ return false;
53
+ }
54
+ // Extract peer ID from the first transport
55
+ const peerIdString = nodeAddress.libp2pTransports[0].toPeerId();
56
+ if (!peerIdString) {
57
+ return false;
58
+ }
59
+ const peerId = peerIdFromString(peerIdString);
60
+ const connections = this.p2pNode.getConnections(peerId);
61
+ // Check if we have at least one open connection
62
+ return connections.some((conn) => conn.status === 'open');
63
+ }
64
+ catch (error) {
65
+ this.logger.debug('Error checking cached connection:', error);
66
+ return false;
67
+ }
48
68
  }
49
- getCachedConnection(address) {
50
- const key = address.toString();
69
+ /**
70
+ * Get an existing libp2p connection to the target peer
71
+ * @param address - The address to get a connection for
72
+ * @returns The libp2p Connection object or null if not found
73
+ */
74
+ getCachedLibp2pConnection(address) {
51
75
  try {
52
- const connection = this.cache.get(key);
53
- if (!connection) {
54
- throw new Error('Connection not found in cache');
76
+ const nodeAddress = address;
77
+ if (!nodeAddress.libp2pTransports ||
78
+ nodeAddress.libp2pTransports.length === 0) {
79
+ return null;
80
+ }
81
+ // Extract peer ID from the first transport
82
+ const peerIdString = nodeAddress.libp2pTransports[0].toPeerId();
83
+ if (!peerIdString) {
84
+ return null;
55
85
  }
56
- connection.validate();
57
- return connection;
86
+ const peerId = peerIdFromString(peerIdString);
87
+ const connections = this.p2pNode.getConnections(peerId);
88
+ // Return the first open connection, or null if none exist
89
+ const openConnection = connections.find((conn) => conn.status === 'open');
90
+ return openConnection || null;
58
91
  }
59
92
  catch (error) {
60
- this.cache.delete(key);
61
- this.logger.error('Error getting cached connection:', error);
93
+ this.logger.debug('Error getting cached connection:', error);
94
+ return null;
62
95
  }
63
- return null;
64
96
  }
65
97
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-node",
3
- "version": "0.7.12-alpha.39",
3
+ "version": "0.7.12-alpha.40",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -54,12 +54,12 @@
54
54
  "typescript": "5.4.5"
55
55
  },
56
56
  "dependencies": {
57
- "@olane/o-config": "0.7.12-alpha.39",
58
- "@olane/o-core": "0.7.12-alpha.39",
59
- "@olane/o-protocol": "0.7.12-alpha.39",
60
- "@olane/o-tool": "0.7.12-alpha.39",
57
+ "@olane/o-config": "0.7.12-alpha.40",
58
+ "@olane/o-core": "0.7.12-alpha.40",
59
+ "@olane/o-protocol": "0.7.12-alpha.40",
60
+ "@olane/o-tool": "0.7.12-alpha.40",
61
61
  "debug": "^4.4.1",
62
62
  "dotenv": "^16.5.0"
63
63
  },
64
- "gitHead": "794416f70451282e59b498e969c6597896abec29"
64
+ "gitHead": "c17794cf9be8ca5cdeec0cc5d6a3c680065b3b93"
65
65
  }