@olane/o-node 0.7.55 → 0.7.56

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 (54) hide show
  1. package/dist/src/connection/enums/o-node-message-event.d.ts +14 -0
  2. package/dist/src/connection/enums/o-node-message-event.d.ts.map +1 -0
  3. package/dist/src/connection/enums/o-node-message-event.js +5 -0
  4. package/dist/src/connection/index.d.ts +0 -3
  5. package/dist/src/connection/index.d.ts.map +1 -1
  6. package/dist/src/connection/index.js +0 -3
  7. package/dist/src/connection/interfaces/abort-signal.config.d.ts +5 -0
  8. package/dist/src/connection/interfaces/abort-signal.config.d.ts.map +1 -0
  9. package/dist/src/connection/interfaces/o-node-connection-manager.config.d.ts +13 -1
  10. package/dist/src/connection/interfaces/o-node-connection-manager.config.d.ts.map +1 -1
  11. package/dist/src/connection/interfaces/o-node-connection.config.d.ts +18 -5
  12. package/dist/src/connection/interfaces/o-node-connection.config.d.ts.map +1 -1
  13. package/dist/src/connection/interfaces/o-node-stream.config.d.ts +3 -11
  14. package/dist/src/connection/interfaces/o-node-stream.config.d.ts.map +1 -1
  15. package/dist/src/connection/o-node-connection.d.ts +29 -53
  16. package/dist/src/connection/o-node-connection.d.ts.map +1 -1
  17. package/dist/src/connection/o-node-connection.js +102 -146
  18. package/dist/src/connection/o-node-connection.manager.d.ts +12 -8
  19. package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
  20. package/dist/src/connection/o-node-connection.manager.js +46 -34
  21. package/dist/src/connection/o-node-stream.d.ts +48 -15
  22. package/dist/src/connection/o-node-stream.d.ts.map +1 -1
  23. package/dist/src/connection/o-node-stream.js +143 -31
  24. package/dist/src/connection/stream-handler.config.d.ts +0 -11
  25. package/dist/src/connection/stream-handler.config.d.ts.map +1 -1
  26. package/dist/src/lib/interfaces/o-node-request-manager.config.d.ts +9 -0
  27. package/dist/src/lib/interfaces/o-node-request-manager.config.d.ts.map +1 -0
  28. package/dist/src/lib/interfaces/o-node-request-manager.config.js +1 -0
  29. package/dist/src/lib/o-node-request-manager.d.ts +46 -0
  30. package/dist/src/lib/o-node-request-manager.d.ts.map +1 -0
  31. package/dist/src/lib/o-node-request-manager.js +173 -0
  32. package/dist/src/managers/o-reconnection.manager.d.ts.map +1 -1
  33. package/dist/src/managers/o-reconnection.manager.js +4 -0
  34. package/dist/src/managers/o-registration.manager.d.ts.map +1 -1
  35. package/dist/src/managers/o-registration.manager.js +9 -4
  36. package/dist/src/o-node.d.ts +6 -7
  37. package/dist/src/o-node.d.ts.map +1 -1
  38. package/dist/src/o-node.js +22 -37
  39. package/dist/src/o-node.tool.d.ts +3 -3
  40. package/dist/src/o-node.tool.d.ts.map +1 -1
  41. package/dist/src/o-node.tool.js +27 -56
  42. package/dist/src/router/o-node.router.d.ts.map +1 -1
  43. package/dist/src/router/o-node.router.js +4 -2
  44. package/dist/test/connection-management.spec.js +3 -0
  45. package/package.json +7 -7
  46. package/dist/src/connection/interfaces/stream-init-message.d.ts +0 -64
  47. package/dist/src/connection/interfaces/stream-init-message.d.ts.map +0 -1
  48. package/dist/src/connection/interfaces/stream-init-message.js +0 -18
  49. package/dist/src/connection/interfaces/stream-manager.config.d.ts +0 -8
  50. package/dist/src/connection/interfaces/stream-manager.config.d.ts.map +0 -1
  51. package/dist/src/connection/o-node-stream.manager.d.ts +0 -210
  52. package/dist/src/connection/o-node-stream.manager.d.ts.map +0 -1
  53. package/dist/src/connection/o-node-stream.manager.js +0 -696
  54. /package/dist/src/connection/interfaces/{stream-manager.config.js → abort-signal.config.js} +0 -0
@@ -0,0 +1,173 @@
1
+ import { CoreUtils, oError, oErrorCodes, oRequestManager, ResponseBuilder, } from '@olane/o-core';
2
+ import { oNodeAddress } from '../router/o-node.address.js';
3
+ import { oNodeMessageEvent, } from '../connection/enums/o-node-message-event.js';
4
+ import { EventEmitter } from 'events';
5
+ import { v4 } from 'uuid';
6
+ export class oNodeRequestManager extends oRequestManager {
7
+ constructor(config) {
8
+ super();
9
+ this.config = config;
10
+ this.eventEmitter = new EventEmitter();
11
+ this.router = config.router;
12
+ this.connectionManager = config.connectionManager;
13
+ }
14
+ async translateAddress(address, options, nodeRef) {
15
+ if (!nodeRef) {
16
+ throw new Error('Failed to translate address due to invalid node reference');
17
+ }
18
+ const { nextHopAddress, targetAddress } = options?.noRouting
19
+ ? { nextHopAddress: address, targetAddress: address }
20
+ : await this.router.translate(address, nodeRef);
21
+ return {
22
+ nextHopAddress: nextHopAddress,
23
+ targetAddress: targetAddress,
24
+ };
25
+ }
26
+ async connectToNode(nextHopAddress, options) {
27
+ if (!this.connectionManager) {
28
+ this.logger.error('Connection manager not initialized');
29
+ throw new Error('Node is not ready to connect to other nodes');
30
+ }
31
+ const connection = await this.connectionManager
32
+ .connect({
33
+ nextHopAddress: nextHopAddress,
34
+ ...options,
35
+ })
36
+ .catch((error) => {
37
+ // TODO: we need to handle this better and document
38
+ if (error.message === 'Can not dial self') {
39
+ this.logger.error('Make sure you are entering the network not directly through the leader node.');
40
+ }
41
+ throw error;
42
+ });
43
+ if (!connection) {
44
+ throw new Error('Connection failed');
45
+ }
46
+ return connection;
47
+ }
48
+ async send(address, data, options, nodeRef) {
49
+ if (!address.validate()) {
50
+ throw new Error('Invalid address');
51
+ }
52
+ this.logger.debug('Using address: ', address.toString());
53
+ // check for static match
54
+ // TODO
55
+ // if (address.toStaticAddress().equals(this.config.callerAddress.toStaticAddress())) {
56
+ // return this.useSelf(data);
57
+ // }
58
+ // if no routing is requested, use the address as is
59
+ if (options?.noRouting) {
60
+ this.logger.debug('No routing requested, using address as is', address.toString());
61
+ }
62
+ const { nextHopAddress, targetAddress } = await this.translateAddress(address, options, nodeRef);
63
+ const connection = await this.connectToNode(nextHopAddress, {
64
+ targetAddress: targetAddress,
65
+ callerAddress: this.config.callerAddress,
66
+ readTimeoutMs: options?.readTimeoutMs,
67
+ drainTimeoutMs: options?.drainTimeoutMs,
68
+ isStream: options?.isStream,
69
+ abortSignal: options?.abortSignal,
70
+ });
71
+ if (options?.isStream) {
72
+ connection.onChunk((response) => {
73
+ options.onChunk?.(response);
74
+ });
75
+ }
76
+ // communicate the payload to the target node
77
+ const requestId = data?.id || v4();
78
+ const stream = await connection.send({
79
+ address: targetAddress?.toString() || '',
80
+ payload: data || {},
81
+ id: requestId,
82
+ }, options);
83
+ const response = await stream.waitForResponse(requestId);
84
+ stream.close();
85
+ // we handle streaming response differently
86
+ if (options?.isStream) {
87
+ return response;
88
+ }
89
+ // if there is an error, throw it to continue to bubble up
90
+ this.handleResponseError(response);
91
+ return response;
92
+ }
93
+ async receiveStream({ connection, stream, }) {
94
+ const unknown = new oNodeAddress('o://unknown', []);
95
+ const oConnection = await this.connectionManager.answer({
96
+ nextHopAddress: unknown,
97
+ targetAddress: unknown,
98
+ callerAddress: unknown,
99
+ p2pConnection: connection,
100
+ }, stream);
101
+ // Get the oNodeConnection for this libp2p connection
102
+ if (!oConnection) {
103
+ this.logger.error('Failed to process inbound connection');
104
+ throw new Error('Failed to process inbound connection');
105
+ }
106
+ // listen for requests
107
+ this.listenForMessages(oConnection, {});
108
+ }
109
+ async sendResponse(request, result) {
110
+ const responseBuilder = ResponseBuilder.create();
111
+ const responseStream = request.stream;
112
+ try {
113
+ // Emit InboundRequest event and wait for handler to process
114
+ const response = await responseBuilder.build(request, result, null);
115
+ await CoreUtils.sendResponse(response, request.stream);
116
+ this.logger.debug(`Successfully processed request: method=${request.method}, id=${request.id}`);
117
+ }
118
+ catch (error) {
119
+ this.logger.error(`Error processing request: method=${request.method}, id=${request.id}`, error);
120
+ const errorResponse = await responseBuilder.buildError(request, error);
121
+ await CoreUtils.sendResponse(errorResponse, responseStream);
122
+ }
123
+ }
124
+ // bubble up the messages to the request handler
125
+ async listenForMessages(connection, options) {
126
+ if (connection.eventEmitter.listenerCount(oNodeMessageEvent.request) > 0) {
127
+ this.logger.warn('Already listening for this event on connection id:', connection.id);
128
+ return;
129
+ }
130
+ connection.on(oNodeMessageEvent.request, async (data) => {
131
+ try {
132
+ const result = await this.emitAsync(oNodeMessageEvent.request, data);
133
+ this.sendResponse(data, result);
134
+ }
135
+ catch (err) {
136
+ this.logger.error('Error with request:', err);
137
+ const responseBuilder = ResponseBuilder.create();
138
+ const errorResponse = await responseBuilder.buildError(data, err);
139
+ await CoreUtils.sendResponse(errorResponse, data.stream);
140
+ }
141
+ });
142
+ }
143
+ /**
144
+ * Add event listener
145
+ */
146
+ on(event, listener) {
147
+ this.eventEmitter.on(event, listener);
148
+ }
149
+ /**
150
+ * Remove event listener
151
+ */
152
+ off(event, listener) {
153
+ this.eventEmitter.off(event, listener);
154
+ }
155
+ /**
156
+ * Emit event
157
+ */
158
+ // private emit<K extends oNodeMessageEvent>(
159
+ // event: K,
160
+ // data?: oNodeMessageEventData[K],
161
+ // ): void {
162
+ // this.eventEmitter.emit(event, data);
163
+ // }
164
+ async emitAsync(event, data) {
165
+ const listeners = this.eventEmitter.listeners(event);
166
+ if (listeners.length === 0) {
167
+ throw new oError(oErrorCodes.INTERNAL_ERROR, `No listener registered for event: ${event}`);
168
+ }
169
+ // Call the first listener and await its response
170
+ const listener = listeners[0];
171
+ return await listener(data);
172
+ }
173
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"o-reconnection.manager.d.ts","sourceRoot":"","sources":["../../../src/managers/o-reconnection.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EASR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAI3E,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,yBAAyB,EAAE,MAAM,CAAC;IAClC,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,oBAAqB,SAAQ,OAAO;IAI7C,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IAJhB,OAAO,CAAC,YAAY,CAAS;gBAGnB,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,kBAAkB;IAMpC,OAAO,CAAC,mBAAmB;IAyBrB,mBAAmB,CAAC,KAAK,EAAE,GAAG;YAmCtB,wBAAwB;YAaxB,wBAAwB;YAexB,wBAAwB;IAehC,mBAAmB;YAgDX,2BAA2B;YAiB3B,iBAAiB;IAkB/B;;;OAGG;YACW,yBAAyB;IAyFvC;;OAEG;IACG,yBAAyB;IAoH/B,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,KAAK;CAGd"}
1
+ {"version":3,"file":"o-reconnection.manager.d.ts","sourceRoot":"","sources":["../../../src/managers/o-reconnection.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EASR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAI3E,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,yBAAyB,EAAE,MAAM,CAAC;IAClC,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,oBAAqB,SAAQ,OAAO;IAI7C,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IAJhB,OAAO,CAAC,YAAY,CAAS;gBAGnB,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,kBAAkB;IAMpC,OAAO,CAAC,mBAAmB;IAyBrB,mBAAmB,CAAC,KAAK,EAAE,GAAG;YAwCtB,wBAAwB;YAaxB,wBAAwB;YAexB,wBAAwB;IAehC,mBAAmB;YAgDX,2BAA2B;YAiB3B,iBAAiB;IAkB/B;;;OAGG;YACW,yBAAyB;IAyFvC;;OAEG;IACG,yBAAyB;IAoH/B,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,KAAK;CAGd"}
@@ -33,6 +33,10 @@ export class oReconnectionManager extends oObject {
33
33
  async handleNodeConnected(event) {
34
34
  const connectedEvent = event;
35
35
  const nodeAddress = connectedEvent.nodeAddress;
36
+ if (this.node.state !== NodeState.RUNNING) {
37
+ this.logger.warn('Ignoring node connection events during startup');
38
+ return;
39
+ }
36
40
  // if leader is back online re-register
37
41
  if (nodeAddress.toString() === oAddress.leader().toString()) {
38
42
  // Check if we can register with leader (not already registering or registered)
@@ -1 +1 @@
1
- {"version":3,"file":"o-registration.manager.d.ts","sourceRoot":"","sources":["../../../src/managers/o-registration.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAIR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAGvE,MAAM,MAAM,iBAAiB,GACzB,gBAAgB,GAChB,aAAa,GACb,YAAY,GACZ,QAAQ,CAAC;AAEb,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAqB,SAAQ,OAAO;IAMnC,OAAO,CAAC,IAAI;IALxB,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,WAAW,CAAC,CAAQ;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAQ;gBAER,IAAI,EAAE,gBAAgB;IAI1C;;;OAGG;IACH,iBAAiB,IAAI,OAAO;IAM5B;;;OAGG;IACH,iBAAiB,IAAI,OAAO;IAM5B;;OAEG;IACH,kBAAkB,IAAI,OAAO;IAI7B;;OAEG;IACH,kBAAkB,IAAI,OAAO;IAI7B;;OAEG;IACH,iBAAiB,IAAI,OAAO;IAe5B;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAMxB;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAMxB;;OAEG;IACH,QAAQ,IAAI,IAAI;IAKhB;;OAEG;IACH,SAAS,IAAI,kBAAkB;IAS/B;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAsFrC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAwDtC"}
1
+ {"version":3,"file":"o-registration.manager.d.ts","sourceRoot":"","sources":["../../../src/managers/o-registration.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAIR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAGvE,MAAM,MAAM,iBAAiB,GACzB,gBAAgB,GAChB,aAAa,GACb,YAAY,GACZ,QAAQ,CAAC;AAEb,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAqB,SAAQ,OAAO;IAMnC,OAAO,CAAC,IAAI;IALxB,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,WAAW,CAAC,CAAQ;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAQ;gBAER,IAAI,EAAE,gBAAgB;IAI1C;;;OAGG;IACH,iBAAiB,IAAI,OAAO;IAM5B;;;OAGG;IACH,iBAAiB,IAAI,OAAO;IAM5B;;OAEG;IACH,kBAAkB,IAAI,OAAO;IAI7B;;OAEG;IACH,kBAAkB,IAAI,OAAO;IAI7B;;OAEG;IACH,iBAAiB,IAAI,OAAO;IAe5B;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAMxB;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAMxB;;OAEG;IACH,QAAQ,IAAI,IAAI;IAKhB;;OAEG;IACH,SAAS,IAAI,kBAAkB;IAS/B;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAgGrC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAyDtC"}
@@ -141,8 +141,11 @@ export class oRegistrationManager extends oObject {
141
141
  return;
142
142
  }
143
143
  }
144
- // Register with parent via child_register call
145
- await this.node.use(new oNodeAddress(this.node.config.parent.value), {
144
+ // necessary hack to ensure that registry node and other leader->child relationships build accurately
145
+ const isParentLeader = this.node?.config?.parent?.value === oAddress.leader().value;
146
+ await this.node.use(isParentLeader
147
+ ? this.node.config.parent
148
+ : new oNodeAddress(this.node.config.parent.value), {
146
149
  method: 'child_register',
147
150
  params: {
148
151
  address: this.node.address.toString(),
@@ -164,7 +167,8 @@ export class oRegistrationManager extends oObject {
164
167
  catch (error) {
165
168
  // Failure - transition to failed state
166
169
  this.parentState = 'failed';
167
- this.parentError = error instanceof Error ? error : new Error(String(error));
170
+ this.parentError =
171
+ error instanceof Error ? error : new Error(String(error));
168
172
  this.logger.error('Failed to register with parent:', {
169
173
  parent: this.node.parent?.toString(),
170
174
  error: this.parentError.message,
@@ -215,7 +219,8 @@ export class oRegistrationManager extends oObject {
215
219
  catch (error) {
216
220
  // Failure - transition to failed state
217
221
  this.leaderState = 'failed';
218
- this.leaderError = error instanceof Error ? error : new Error(String(error));
222
+ this.leaderError =
223
+ error instanceof Error ? error : new Error(String(error));
219
224
  this.logger.error('Failed to register with leader:', {
220
225
  leader: this.node.leader?.toString(),
221
226
  error: this.leaderError.message,
@@ -1,26 +1,28 @@
1
1
  import { Libp2p, Libp2pConfig } from '@olane/o-config';
2
2
  import { PeerId } from '@olane/o-config';
3
+ import { oNodeRouter } from './router/o-node.router.js';
3
4
  import { oNodeHierarchyManager } from './o-node.hierarchy-manager.js';
4
5
  import { oNodeConfig } from './interfaces/o-node.config.js';
5
6
  import { oNodeTransport } from './router/o-node.transport.js';
6
7
  import { oRequest, oNotificationManager } from '@olane/o-core';
7
8
  import { oNodeAddress } from './router/o-node.address.js';
8
- import { oNodeConnection } from './connection/o-node-connection.js';
9
9
  import { oNodeConnectionManager } from './connection/o-node-connection.manager.js';
10
10
  import { oToolBase } from '@olane/o-tool';
11
11
  import { oConnectionHeartbeatManager } from './managers/o-connection-heartbeat.manager.js';
12
- import { oNodeConnectionConfig } from './connection/index.js';
13
12
  import { oReconnectionManager } from './managers/o-reconnection.manager.js';
14
13
  import { oRegistrationManager } from './managers/o-registration.manager.js';
15
14
  import { LockManager } from './utils/lock-manager.js';
15
+ import { oNodeRequestManager } from './lib/o-node-request-manager.js';
16
16
  export declare class oNode extends oToolBase {
17
17
  peerId: PeerId;
18
18
  p2pNode: Libp2p;
19
19
  address: oNodeAddress;
20
20
  config: oNodeConfig;
21
- connectionManager: oNodeConnectionManager;
21
+ router: oNodeRouter;
22
22
  hierarchyManager: oNodeHierarchyManager;
23
23
  connectionHeartbeatManager?: oConnectionHeartbeatManager;
24
+ connectionManager: oNodeConnectionManager;
25
+ requestManager: oNodeRequestManager;
24
26
  protected reconnectionManager?: oReconnectionManager;
25
27
  registrationManager: oRegistrationManager;
26
28
  protected hooksStartFinished: any[];
@@ -44,6 +46,7 @@ export declare class oNode extends oToolBase {
44
46
  register(): Promise<void>;
45
47
  extractMethod(address: oNodeAddress): string;
46
48
  start(): Promise<void>;
49
+ initRequestManager(): void;
47
50
  validateJoinRequest(request: oRequest): Promise<any>;
48
51
  /**
49
52
  * Configure the libp2p node
@@ -51,7 +54,6 @@ export declare class oNode extends oToolBase {
51
54
  */
52
55
  configure(): Promise<Libp2pConfig>;
53
56
  protected createNode(): Promise<Libp2p>;
54
- connect(config: oNodeConnectionConfig): Promise<oNodeConnection>;
55
57
  initConnectionManager(): Promise<void>;
56
58
  protected hookInitializeFinished(): Promise<void>;
57
59
  onInitFinished(cb: Function): void;
@@ -72,9 +74,6 @@ export declare class oNode extends oToolBase {
72
74
  */
73
75
  protected validate(): Promise<void>;
74
76
  initialize(): Promise<void>;
75
- /**
76
- * Override use() to wrap leader/registry requests with retry logic
77
- */
78
77
  teardown(): Promise<void>;
79
78
  /**
80
79
  * Reset node state to allow restart after stop
@@ -1 +1 @@
1
- {"version":3,"file":"o-node.d.ts","sourceRoot":"","sources":["../../src/o-node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"o-node.d.ts","sourceRoot":"","sources":["../../src/o-node.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,8 @@ import { oNodeNotificationManager } from './o-node.notification-manager.js';
13
13
  import { oReconnectionManager } from './managers/o-reconnection.manager.js';
14
14
  import { oRegistrationManager } from './managers/o-registration.manager.js';
15
15
  import { LockManager } from './utils/lock-manager.js';
16
+ import { oNodeRequestManager } from './lib/o-node-request-manager.js';
17
+ import { oNodeMessageEvent } from './connection/enums/o-node-message-event.js';
16
18
  export class oNode extends oToolBase {
17
19
  constructor(config) {
18
20
  super(config);
@@ -174,6 +176,23 @@ export class oNode extends oToolBase {
174
176
  await this.connectionHeartbeatManager.start();
175
177
  }
176
178
  }
179
+ initRequestManager() {
180
+ this.requestManager = new oNodeRequestManager({
181
+ callerAddress: this.address,
182
+ connectionManager: this.connectionManager,
183
+ router: this.router,
184
+ });
185
+ this.requestManager.on(oNodeMessageEvent.request, async (data) => {
186
+ try {
187
+ const result = await this.execute(data, data.stream);
188
+ return result;
189
+ }
190
+ catch (error) {
191
+ this.logger.error('Error executing tool: ', data.toString(), error, typeof error);
192
+ throw error; // StreamManager will handle error response building
193
+ }
194
+ });
195
+ }
177
196
  async validateJoinRequest(request) {
178
197
  return true;
179
198
  }
@@ -280,32 +299,13 @@ export class oNode extends oToolBase {
280
299
  this.p2pNode = await createNode(params);
281
300
  return this.p2pNode;
282
301
  }
283
- async connect(config) {
284
- if (!this.connectionManager) {
285
- this.logger.error('Connection manager not initialized');
286
- throw new Error('Node is not ready to connect to other nodes');
287
- }
288
- const connection = await this.connectionManager
289
- .connect(config)
290
- .catch((error) => {
291
- // TODO: we need to handle this better and document
292
- if (error.message === 'Can not dial self') {
293
- this.logger.error('Make sure you are entering the network not directly through the leader node.');
294
- }
295
- throw error;
296
- });
297
- if (!connection) {
298
- throw new Error('Connection failed');
299
- }
300
- return connection;
301
- }
302
302
  async initConnectionManager() {
303
303
  this.connectionManager = new oNodeConnectionManager({
304
304
  p2pNode: this.p2pNode,
305
305
  defaultReadTimeoutMs: this.config.connectionTimeouts?.readTimeoutMs,
306
306
  defaultDrainTimeoutMs: this.config.connectionTimeouts?.drainTimeoutMs,
307
307
  runOnLimitedConnection: this.config.runOnLimitedConnection ?? false,
308
- originAddress: this.address?.value,
308
+ callerAddress: this.address?.value,
309
309
  });
310
310
  }
311
311
  async hookInitializeFinished() {
@@ -429,6 +429,8 @@ export class oNode extends oToolBase {
429
429
  this.peerId = this.p2pNode.peerId;
430
430
  // initialize connection manager
431
431
  await this.initConnectionManager();
432
+ // must come after connection manager
433
+ await this.initRequestManager();
432
434
  // initialize address resolution
433
435
  this.router.addResolver(new oMethodResolver(this.address));
434
436
  this.router.addResolver(new oNodeResolver(this.address));
@@ -439,23 +441,6 @@ export class oNode extends oToolBase {
439
441
  }
440
442
  await this.hookInitializeFinished();
441
443
  }
442
- /**
443
- * Override use() to wrap leader/registry requests with retry logic
444
- */
445
- // async use(
446
- // address: oAddress,
447
- // data?: {
448
- // method?: string;
449
- // params?: { [key: string]: any };
450
- // id?: string;
451
- // },
452
- // options?: UseOptions,
453
- // ): Promise<any> {
454
- // // Wrap leader/registry requests with retry logic
455
- // return super.use(address, data, options),
456
- // address,
457
- // data?.method,
458
- // }
459
444
  async teardown() {
460
445
  // Stop heartbeat before parent teardown
461
446
  if (this.connectionHeartbeatManager) {
@@ -1,6 +1,7 @@
1
1
  import { oAddress, oRequest } from '@olane/o-core';
2
2
  import { oServerNode } from './nodes/server.node.js';
3
3
  import { Connection, Stream } from '@olane/o-config';
4
+ import { oNodeRequestManager } from './lib/o-node-request-manager.js';
4
5
  declare const oNodeTool_base: typeof oServerNode;
5
6
  /**
6
7
  * oTool is a mixin that extends the base class and implements the oTool interface
@@ -8,12 +9,11 @@ declare const oNodeTool_base: typeof oServerNode;
8
9
  * @returns A new class that extends the base class and implements the oTool interface
9
10
  */
10
11
  export declare class oNodeTool extends oNodeTool_base {
11
- handleProtocolReuse(address: oAddress): Promise<void>;
12
+ requestManager: oNodeRequestManager;
12
13
  handleProtocol(address: oAddress): Promise<void>;
13
14
  initializeProtocols(): Promise<void>;
14
15
  initialize(): Promise<void>;
15
- handleStreamReuse(stream: Stream, connection: Connection): Promise<void>;
16
- handleStream(stream: Stream, connection: Connection, reuse?: boolean): Promise<void>;
16
+ handleStream(stream: Stream, connection: Connection): Promise<void>;
17
17
  _tool_identify(): Promise<any>;
18
18
  _tool_child_register(request: oRequest): Promise<any>;
19
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"o-node.tool.d.ts","sourceRoot":"","sources":["../../src/o-node.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAoB,MAAM,eAAe,CAAC;AAErE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;;AAOrD;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAAkB;IACzC,mBAAmB,CAAC,OAAO,EAAE,QAAQ;IAuBrC,cAAc,CAAC,OAAO,EAAE,QAAQ;IAyBhC,mBAAmB;IAWnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,IAAI,CAAC;IAIV,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,IAAI,CAAC;IA+CV,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAQ9B,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAiC5D"}
1
+ {"version":3,"file":"o-node.tool.d.ts","sourceRoot":"","sources":["../../src/o-node.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAoB,MAAM,eAAe,CAAC;AAErE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAQrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;;AAEtE;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAAkB;IACxC,cAAc,EAAG,mBAAmB,CAAC;IAyBtC,cAAc,CAAC,OAAO,EAAE,QAAQ;IAyBhC,mBAAmB;IAWnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnE,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAQ9B,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAiC5D"}
@@ -3,31 +3,34 @@ import { oTool } from '@olane/o-tool';
3
3
  import { oServerNode } from './nodes/server.node.js';
4
4
  import { oNodeTransport } from './router/o-node.transport.js';
5
5
  import { oNodeAddress } from './router/o-node.address.js';
6
- import { StreamManagerEvent } from './connection/stream-manager.events.js';
7
6
  /**
8
7
  * oTool is a mixin that extends the base class and implements the oTool interface
9
8
  * @param Base - The base class to extend
10
9
  * @returns A new class that extends the base class and implements the oTool interface
11
10
  */
12
11
  export class oNodeTool extends oTool(oServerNode) {
13
- async handleProtocolReuse(address) {
14
- const reuseProtocol = address.protocol + '/reuse';
15
- this.logger.debug('Handling protocol reuse: ' + reuseProtocol);
16
- const protocols = this.p2pNode.getProtocols();
17
- if (protocols.find((p) => p === reuseProtocol)) {
18
- // already handling
19
- return;
20
- }
21
- const maxOutboundsStreams = process.env.MAX_OUTBOUND_STREAMS
22
- ? parseInt(process.env.MAX_OUTBOUND_STREAMS)
23
- : 1000;
24
- await this.p2pNode.handle(reuseProtocol, this.handleStreamReuse.bind(this), {
25
- maxInboundStreams: 10000,
26
- maxOutboundStreams: maxOutboundsStreams,
27
- runOnLimitedConnection: true, // reuse is always on limited connections
28
- });
29
- this.logger.debug('Handled protocol reuse: ' + reuseProtocol);
30
- }
12
+ // async handleProtocolReuse(address: oAddress) {
13
+ // const reuseProtocol = address.protocol + '/reuse';
14
+ // this.logger.debug('Handling protocol reuse: ' + reuseProtocol);
15
+ // const protocols = this.p2pNode.getProtocols();
16
+ // if (protocols.find((p) => p === reuseProtocol)) {
17
+ // // already handling
18
+ // return;
19
+ // }
20
+ // const maxOutboundsStreams = process.env.MAX_OUTBOUND_STREAMS
21
+ // ? parseInt(process.env.MAX_OUTBOUND_STREAMS)
22
+ // : 1000;
23
+ // await this.p2pNode.handle(
24
+ // reuseProtocol,
25
+ // this.handleStreamReuse.bind(this),
26
+ // {
27
+ // maxInboundStreams: 10_000,
28
+ // maxOutboundStreams: maxOutboundsStreams,
29
+ // runOnLimitedConnection: true, // reuse is always on limited connections
30
+ // },
31
+ // );
32
+ // this.logger.debug('Handled protocol reuse: ' + reuseProtocol);
33
+ // }
31
34
  async handleProtocol(address) {
32
35
  if (!address || !address.protocol) {
33
36
  throw new Error('Invalid address passed: ' + address);
@@ -50,7 +53,7 @@ export class oNodeTool extends oTool(oServerNode) {
50
53
  maxOutboundStreams: maxOutboundsStreams,
51
54
  runOnLimitedConnection: this.config.runOnLimitedConnection,
52
55
  });
53
- await this.handleProtocolReuse(address);
56
+ // await this.handleProtocolReuse(address);
54
57
  }
55
58
  async initializeProtocols() {
56
59
  this.logger.info('Initializing custom protocols for node...');
@@ -64,43 +67,11 @@ export class oNodeTool extends oTool(oServerNode) {
64
67
  await super.initialize();
65
68
  await this.initializeProtocols();
66
69
  }
67
- async handleStreamReuse(stream, connection) {
68
- return this.handleStream(stream, connection, true);
69
- }
70
- async handleStream(stream, connection, reuse) {
71
- this.logger.debug('Handling incoming stream on connection:', {
72
- connectionId: connection.id,
73
- direction: connection.direction,
74
- });
75
- const unknown = new oNodeAddress('o://unknown', []);
76
- const oConnection = await this.connectionManager.answer({
77
- nextHopAddress: unknown,
78
- address: unknown,
79
- callerAddress: this.address,
80
- p2pConnection: connection,
81
- reuse,
82
- });
83
- // Get the oNodeConnection for this libp2p connection
84
- if (!oConnection) {
85
- this.logger.error('Failed to process inbound connection');
86
- throw new Error('Failed to process inbound connection');
87
- }
88
- // Subscribe to InboundRequest events from the stream manager
89
- // This follows an event-driven pattern for handling incoming requests
90
- oConnection.streamManager.on(StreamManagerEvent.InboundRequest, async (data) => {
91
- try {
92
- const result = await this.execute(data.request, data.stream);
93
- // Return the raw result - StreamManager will build and send the response
94
- return result;
95
- }
96
- catch (error) {
97
- this.logger.error('Error executing tool: ', data.request.toString(), error, typeof error);
98
- throw error; // StreamManager will handle error response building
99
- }
70
+ async handleStream(stream, connection) {
71
+ return this.requestManager.receiveStream({
72
+ stream,
73
+ connection,
100
74
  });
101
- // Use the connection's StreamManager for consistent stream handling
102
- // This follows libp2p v3 best practices for length-prefixed streaming
103
- await oConnection.streamManager.handleIncomingStream(stream, connection);
104
75
  }
105
76
  async _tool_identify() {
106
77
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"o-node.router.d.ts","sourceRoot":"","sources":["../../../src/router/o-node.router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAML,cAAc,EAGd,aAAa,EACd,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAM5C,qBAAa,WAAY,SAAQ,WAAW;IAC1C,OAAO,CAAC,aAAa,CAAqB;;IAO1C;;;;;;;;OAQG;cACa,OAAO,CACrB,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,KAAK,GACV,OAAO,CAAC,GAAG,CAAC;IA6Bf;;;OAGG;YACW,kBAAkB;IA8DhC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAWhC;;OAEG;YACW,eAAe;IA4C7B;;;OAGG;IACG,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC;IA+B3E;;;OAGG;IACH,UAAU,CAAC,qBAAqB,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO;CAGtE"}
1
+ {"version":3,"file":"o-node.router.d.ts","sourceRoot":"","sources":["../../../src/router/o-node.router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAML,cAAc,EAGd,aAAa,EACd,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAM5C,qBAAa,WAAY,SAAQ,WAAW;IAC1C,OAAO,CAAC,aAAa,CAAqB;;IAO1C;;;;;;;;OAQG;cACa,OAAO,CACrB,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,KAAK,GACV,OAAO,CAAC,GAAG,CAAC;IA6Bf;;;OAGG;YACW,kBAAkB;IA8DhC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAWhC;;OAEG;YACW,eAAe;IA+C7B;;;OAGG;IACG,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC;IA+B3E;;;OAGG;IACH,UAAU,CAAC,qBAAqB,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO;CAGtE"}
@@ -122,7 +122,7 @@ export class oNodeRouter extends oToolRouter {
122
122
  request.params.payload?.params?._isStreaming;
123
123
  const nodeConnection = await node.connectionManager.connect({
124
124
  nextHopAddress: address,
125
- address: node.address,
125
+ targetAddress: node.address,
126
126
  callerAddress: node.address,
127
127
  isStream: isStream,
128
128
  });
@@ -136,7 +136,9 @@ export class oNodeRouter extends oToolRouter {
136
136
  });
137
137
  // allow this to continue as we will tell the transmitter to stream the response and we will intercept via the above listener
138
138
  }
139
- const response = await nodeConnection.transmit(request);
139
+ const stream = await nodeConnection.transmit(request, {});
140
+ const response = await stream.waitForResponse(String(request.id));
141
+ stream.close();
140
142
  return response.result.data;
141
143
  }
142
144
  catch (error) {
@@ -14,11 +14,14 @@ describe('Connection Management', () => {
14
14
  await env.cleanup();
15
15
  });
16
16
  describe('Connection Pooling', () => {
17
+ // TODO: add more concurrency tests for first connection to a node since there is a race condition issue with 2 connections being possible (discovered when reviewing the event response mechanism for parent connection detected = retry register. Bandaid workaround currently working where we simply prevent trying in the reconnection manager)
17
18
  it('should cache and reuse connections', async () => {
18
19
  builder = await NetworkTopologies.twoNode();
19
20
  console.log('Built the 2 node network, starting test');
20
21
  const leader = builder.getNode('o://leader');
21
22
  const child = builder.getNode('o://child');
23
+ // at most there should only be 1 connection (the parent / leader shared)
24
+ expect(child.requestManager.connectionManager.connectionCount).to.equal(1);
22
25
  const spy = createConnectionSpy(leader);
23
26
  spy.start();
24
27
  // Make first request (establishes connection)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-node",
3
- "version": "0.7.55",
3
+ "version": "0.7.56",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -40,7 +40,7 @@
40
40
  "devDependencies": {
41
41
  "@eslint/eslintrc": "^3.3.1",
42
42
  "@eslint/js": "^9.29.0",
43
- "@olane/o-test": "0.7.55",
43
+ "@olane/o-test": "0.7.56",
44
44
  "@tsconfig/node20": "^20.1.6",
45
45
  "@types/jest": "^30.0.0",
46
46
  "@types/json5": "^2.2.0",
@@ -60,13 +60,13 @@
60
60
  "typescript": "5.4.5"
61
61
  },
62
62
  "dependencies": {
63
- "@olane/o-config": "0.7.55",
64
- "@olane/o-core": "0.7.55",
65
- "@olane/o-protocol": "0.7.55",
66
- "@olane/o-tool": "0.7.55",
63
+ "@olane/o-config": "0.7.56",
64
+ "@olane/o-core": "0.7.56",
65
+ "@olane/o-protocol": "0.7.56",
66
+ "@olane/o-tool": "0.7.56",
67
67
  "debug": "^4.4.1",
68
68
  "dotenv": "^16.5.0",
69
69
  "json5": "^2.2.3"
70
70
  },
71
- "gitHead": "f7d02a1ecfb0d28b7b1009a7c3eb6d0d4863adc2"
71
+ "gitHead": "f1dadd9c39f33d1279345546df8e1bf63481e5e1"
72
72
  }