@olane/o-node 0.7.51 → 0.7.53

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 (48) hide show
  1. package/dist/src/connection/index.d.ts +6 -5
  2. package/dist/src/connection/index.d.ts.map +1 -1
  3. package/dist/src/connection/index.js +6 -5
  4. package/dist/src/connection/interfaces/{o-node-connection-stream.config.d.ts → o-node-stream.config.d.ts} +2 -2
  5. package/dist/src/connection/interfaces/o-node-stream.config.d.ts.map +1 -0
  6. package/dist/src/connection/interfaces/stream-init-message.d.ts +29 -0
  7. package/dist/src/connection/interfaces/stream-init-message.d.ts.map +1 -0
  8. package/dist/src/connection/interfaces/stream-init-message.js +8 -0
  9. package/dist/src/connection/interfaces/stream-manager.config.d.ts +8 -0
  10. package/dist/src/connection/interfaces/stream-manager.config.d.ts.map +1 -0
  11. package/dist/src/connection/o-node-connection.d.ts +5 -7
  12. package/dist/src/connection/o-node-connection.d.ts.map +1 -1
  13. package/dist/src/connection/o-node-connection.js +26 -56
  14. package/dist/src/connection/o-node-connection.manager.d.ts +7 -0
  15. package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
  16. package/dist/src/connection/o-node-connection.manager.js +23 -5
  17. package/dist/src/connection/{o-node-connection-stream.d.ts → o-node-stream.d.ts} +6 -6
  18. package/dist/src/connection/o-node-stream.d.ts.map +1 -0
  19. package/dist/src/connection/{o-node-connection-stream.js → o-node-stream.js} +2 -2
  20. package/dist/src/connection/o-node-stream.manager.d.ts +181 -0
  21. package/dist/src/connection/o-node-stream.manager.d.ts.map +1 -0
  22. package/dist/src/connection/o-node-stream.manager.js +526 -0
  23. package/dist/src/connection/stream-manager.events.d.ts +83 -0
  24. package/dist/src/connection/stream-manager.events.d.ts.map +1 -0
  25. package/dist/src/connection/stream-manager.events.js +18 -0
  26. package/dist/src/o-node.tool.d.ts +0 -1
  27. package/dist/src/o-node.tool.d.ts.map +1 -1
  28. package/dist/src/o-node.tool.js +30 -20
  29. package/dist/test/helpers/stream-pool-test-helpers.d.ts +0 -75
  30. package/dist/test/helpers/stream-pool-test-helpers.d.ts.map +1 -1
  31. package/dist/test/helpers/stream-pool-test-helpers.js +262 -229
  32. package/dist/test/parent-child-registration.spec.js +2 -1
  33. package/package.json +7 -7
  34. package/dist/src/connection/interfaces/o-node-connection-stream.config.d.ts.map +0 -1
  35. package/dist/src/connection/interfaces/stream-pool-manager.config.d.ts +0 -41
  36. package/dist/src/connection/interfaces/stream-pool-manager.config.d.ts.map +0 -1
  37. package/dist/src/connection/o-node-connection-stream.d.ts.map +0 -1
  38. package/dist/src/connection/stream-handler.d.ts +0 -102
  39. package/dist/src/connection/stream-handler.d.ts.map +0 -1
  40. package/dist/src/connection/stream-handler.js +0 -357
  41. package/dist/src/connection/stream-pool-manager.d.ts +0 -86
  42. package/dist/src/connection/stream-pool-manager.d.ts.map +0 -1
  43. package/dist/src/connection/stream-pool-manager.events.d.ts +0 -57
  44. package/dist/src/connection/stream-pool-manager.events.d.ts.map +0 -1
  45. package/dist/src/connection/stream-pool-manager.events.js +0 -14
  46. package/dist/src/connection/stream-pool-manager.js +0 -356
  47. /package/dist/src/connection/interfaces/{o-node-connection-stream.config.js → o-node-stream.config.js} +0 -0
  48. /package/dist/src/connection/interfaces/{stream-pool-manager.config.js → stream-manager.config.js} +0 -0
@@ -2,10 +2,11 @@ export * from './o-node-connection.js';
2
2
  export * from './o-node-connection.manager.js';
3
3
  export * from './interfaces/o-node-connection.config.js';
4
4
  export * from './interfaces/o-node-connection-manager.config.js';
5
- export * from './interfaces/o-node-connection-stream.config.js';
6
- export * from './interfaces/stream-pool-manager.config.js';
7
- export * from './o-node-connection-stream.js';
5
+ export * from './interfaces/o-node-stream.config.js';
6
+ export * from './interfaces/stream-manager.config.js';
7
+ export * from './interfaces/stream-init-message.js';
8
+ export * from './o-node-stream.js';
8
9
  export * from './stream-handler.config.js';
9
- export * from './stream-pool-manager.js';
10
- export * from './stream-pool-manager.events.js';
10
+ export * from './o-node-stream.manager.js';
11
+ export * from './stream-manager.events.js';
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/connection/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,iDAAiD,CAAC;AAChE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/connection/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,qCAAqC,CAAC;AACpD,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC"}
@@ -2,9 +2,10 @@ export * from './o-node-connection.js';
2
2
  export * from './o-node-connection.manager.js';
3
3
  export * from './interfaces/o-node-connection.config.js';
4
4
  export * from './interfaces/o-node-connection-manager.config.js';
5
- export * from './interfaces/o-node-connection-stream.config.js';
6
- export * from './interfaces/stream-pool-manager.config.js';
7
- export * from './o-node-connection-stream.js';
5
+ export * from './interfaces/o-node-stream.config.js';
6
+ export * from './interfaces/stream-manager.config.js';
7
+ export * from './interfaces/stream-init-message.js';
8
+ export * from './o-node-stream.js';
8
9
  export * from './stream-handler.config.js';
9
- export * from './stream-pool-manager.js';
10
- export * from './stream-pool-manager.events.js';
10
+ export * from './o-node-stream.manager.js';
11
+ export * from './stream-manager.events.js';
@@ -7,10 +7,10 @@ import { StreamReusePolicy } from '../stream-handler.config';
7
7
  * - 'general': Stream with no specific role (default, backward compatible)
8
8
  */
9
9
  export type StreamType = 'dedicated-reader' | 'request-response' | 'general';
10
- export interface oNodeConnectionStreamConfig {
10
+ export interface oNodeStreamConfig {
11
11
  direction: 'inbound' | 'outbound';
12
12
  reusePolicy: StreamReusePolicy;
13
13
  remoteAddress: oAddress;
14
14
  streamType?: StreamType;
15
15
  }
16
- //# sourceMappingURL=o-node-connection-stream.config.d.ts.map
16
+ //# sourceMappingURL=o-node-stream.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"o-node-stream.config.d.ts","sourceRoot":"","sources":["../../../../src/connection/interfaces/o-node-stream.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG,kBAAkB,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,SAAS,GAAG,UAAU,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;IAC/B,aAAa,EAAE,QAAQ,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Message sent by limited connection clients to identify their dedicated reader stream
3
+ * This allows the receiver to identify which stream to use for sending requests back to the caller
4
+ */
5
+ export interface StreamInitMessage {
6
+ /**
7
+ * Message type identifier
8
+ */
9
+ type: 'stream-init';
10
+ /**
11
+ * Role of this stream
12
+ * - 'reader': Dedicated reader stream for receiving requests
13
+ * - 'standard': Standard request-response stream
14
+ */
15
+ role: 'reader' | 'standard';
16
+ /**
17
+ * Timestamp when the stream was created
18
+ */
19
+ timestamp: number;
20
+ /**
21
+ * Optional connection identifier for correlation
22
+ */
23
+ connectionId?: string;
24
+ }
25
+ /**
26
+ * Type guard to check if a message is a StreamInitMessage
27
+ */
28
+ export declare function isStreamInitMessage(message: any): message is StreamInitMessage;
29
+ //# sourceMappingURL=stream-init-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-init-message.d.ts","sourceRoot":"","sources":["../../../../src/connection/interfaces/stream-init-message.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,IAAI,EAAE,aAAa,CAAC;IAEpB;;;;OAIG;IACH,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAE5B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,IAAI,iBAAiB,CAM9E"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Type guard to check if a message is a StreamInitMessage
3
+ */
4
+ export function isStreamInitMessage(message) {
5
+ return (message?.type === 'stream-init' &&
6
+ (message.role === 'reader' || message.role === 'standard') &&
7
+ typeof message.timestamp === 'number');
8
+ }
@@ -0,0 +1,8 @@
1
+ import type { Connection } from '@libp2p/interface';
2
+ export interface StreamManagerConfig {
3
+ /**
4
+ * The libp2p connection this manager handles streams for
5
+ */
6
+ p2pConnection: Connection;
7
+ }
8
+ //# sourceMappingURL=stream-manager.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-manager.config.d.ts","sourceRoot":"","sources":["../../../../src/connection/interfaces/stream-manager.config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,aAAa,EAAE,UAAU,CAAC;CAC3B"}
@@ -1,15 +1,15 @@
1
1
  import { Connection } from '@olane/o-config';
2
2
  import { oConnection, oRequest, oResponse } from '@olane/o-core';
3
3
  import { oNodeConnectionConfig } from './interfaces/o-node-connection.config.js';
4
- import { StreamHandler } from './stream-handler.js';
5
4
  import type { StreamReusePolicy } from './stream-handler.config.js';
6
5
  import { oNodeAddress } from '../router/o-node.address.js';
7
- import { oNodeConnectionStream } from './o-node-connection-stream.js';
6
+ import { oNodeStream } from './o-node-stream.js';
7
+ import { oNodeStreamManager } from './o-node-stream.manager.js';
8
8
  export declare class oNodeConnection extends oConnection {
9
9
  protected readonly config: oNodeConnectionConfig;
10
10
  p2pConnection: Connection;
11
- protected streamHandler: StreamHandler;
12
11
  protected reusePolicy: StreamReusePolicy;
12
+ streamManager: oNodeStreamManager;
13
13
  constructor(config: oNodeConnectionConfig);
14
14
  get remotePeerId(): import("@olane/o-config").PeerId;
15
15
  get remoteAddr(): import("@olane/o-config").Multiaddr;
@@ -18,11 +18,9 @@ export declare class oNodeConnection extends oConnection {
18
18
  */
19
19
  get connectionConfig(): oNodeConnectionConfig;
20
20
  supportsAddress(address: oNodeAddress): boolean;
21
- getOrCreateStream(): Promise<oNodeConnectionStream>;
22
- createStream(): Promise<oNodeConnectionStream>;
23
- get streams(): oNodeConnectionStream[];
21
+ get streams(): oNodeStream[];
24
22
  transmit(request: oRequest): Promise<oResponse>;
25
- postTransmit(stream: oNodeConnectionStream): Promise<void>;
23
+ postTransmit(stream: oNodeStream): Promise<void>;
26
24
  abort(error: Error): Promise<void>;
27
25
  close(): Promise<void>;
28
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"o-node-connection.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAU,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAEL,WAAW,EAGX,QAAQ,EACR,SAAS,EACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAGtE,qBAAa,eAAgB,SAAQ,WAAW;IAKlC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB;IAJrD,aAAa,EAAE,UAAU,CAAC;IACjC,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IACvC,SAAS,CAAC,WAAW,EAAE,iBAAiB,CAAC;gBAEV,MAAM,EAAE,qBAAqB;IAO5D,IAAI,YAAY,qCAEf;IAED,IAAI,UAAU,wCAEb;IAED;;OAEG;IACH,IAAI,gBAAgB,IAAI,qBAAqB,CAE5C;IAED,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAMzC,iBAAiB,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAiBnD,YAAY,IAAI,OAAO,CAAC,qBAAqB,CAAC;IA6BpD,IAAI,OAAO,IAAI,qBAAqB,EAAE,CAcrC;IAEK,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IA6C/C,YAAY,CAAC,MAAM,EAAE,qBAAqB;IAI1C,KAAK,CAAC,KAAK,EAAE,KAAK;IAMlB,KAAK;CAKZ"}
1
+ {"version":3,"file":"o-node-connection.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAU,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAEL,WAAW,EAGX,QAAQ,EACR,SAAS,EACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,qBAAa,eAAgB,SAAQ,WAAW;IAKlC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB;IAJrD,aAAa,EAAE,UAAU,CAAC;IACjC,SAAS,CAAC,WAAW,EAAE,iBAAiB,CAAC;IAClC,aAAa,EAAE,kBAAkB,CAAC;gBAEV,MAAM,EAAE,qBAAqB;IAW5D,IAAI,YAAY,qCAEf;IAED,IAAI,UAAU,wCAEb;IAED;;OAEG;IACH,IAAI,gBAAgB,IAAI,qBAAqB,CAE5C;IAED,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAM/C,IAAI,OAAO,IAAI,WAAW,EAAE,CAE3B;IAEK,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IA2D/C,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhD,KAAK,CAAC,KAAK,EAAE,KAAK;IAMlB,KAAK;CASZ"}
@@ -1,13 +1,15 @@
1
1
  import { oConnection, oError, oErrorCodes, } from '@olane/o-core';
2
- import { StreamHandler } from './stream-handler.js';
3
- import { oNodeConnectionStream } from './o-node-connection-stream.js';
2
+ import { oNodeStreamManager } from './o-node-stream.manager.js';
4
3
  export class oNodeConnection extends oConnection {
5
4
  constructor(config) {
6
5
  super(config);
7
6
  this.config = config;
8
7
  this.p2pConnection = config.p2pConnection;
9
- this.streamHandler = new StreamHandler(this.logger);
10
8
  this.reusePolicy = config.reusePolicy ?? 'none';
9
+ // Initialize oNodeStreamManager (stream lifecycle and protocol management)
10
+ this.streamManager = new oNodeStreamManager({
11
+ p2pConnection: this.p2pConnection,
12
+ });
11
13
  }
12
14
  get remotePeerId() {
13
15
  return this.p2pConnection.remotePeer;
@@ -26,71 +28,36 @@ export class oNodeConnection extends oConnection {
26
28
  return transport.toString() === this.remoteAddr.toString();
27
29
  });
28
30
  }
29
- async getOrCreateStream() {
30
- if (this.reusePolicy === 'reuse') {
31
- this.logger.debug('Reusing stream...');
32
- // search for streams that allow re-use
33
- if (this.streams.length > 0) {
34
- this.logger.debug('Returning reuse stream: ', this.streams[0].p2pStream.protocol);
35
- // search for streams that allow re-use
36
- return this.streams[0];
37
- }
38
- }
39
- return this.createStream();
40
- }
41
- async createStream() {
42
- const protocol = this.nextHopAddress.protocol +
43
- (this.reusePolicy === 'reuse' ? '/reuse' : ''); // connect specifically to the reuse protocol version if desired
44
- this.logger.debug('Creating stream for protocol:', protocol);
45
- const stream = await this.p2pConnection.newStream(protocol, {
46
- signal: this.abortSignal,
47
- maxOutboundStreams: process.env.MAX_OUTBOUND_STREAMS
48
- ? parseInt(process.env.MAX_OUTBOUND_STREAMS)
49
- : 1000,
50
- runOnLimitedConnection: this.config.runOnLimitedConnection ?? true,
51
- });
52
- const managedStream = new oNodeConnectionStream(stream, {
53
- direction: stream.direction,
54
- reusePolicy: this.config.reusePolicy ?? 'none', // default to no re-use stream
55
- remoteAddress: this.nextHopAddress,
56
- });
57
- // print the num streams
58
- const numStreams = this.streams.map((s) => s.isValid).length;
59
- this.logger.debug(`Connection spawned new stream: ${stream.id}. Connection now has ${numStreams} total streams open`);
60
- return managedStream;
61
- }
62
31
  get streams() {
63
- return (this.p2pConnection?.streams
64
- ?.filter((s) => {
65
- return s.protocol.includes('/o/');
66
- })
67
- .map((s) => {
68
- return new oNodeConnectionStream(s, {
69
- direction: s.direction,
70
- reusePolicy: this.config.reusePolicy ?? 'none', // default to no re-use stream
71
- remoteAddress: this.nextHopAddress,
72
- });
73
- }) || []);
32
+ return this.streamManager.getAllStreams();
74
33
  }
75
34
  async transmit(request) {
76
35
  try {
77
- const stream = await this.getOrCreateStream();
78
- // ensure stream is valid
79
- stream.validate();
36
+ // Build protocol string
37
+ const protocol = this.nextHopAddress.protocol +
38
+ (this.reusePolicy === 'reuse' ? '/reuse' : '');
80
39
  const streamConfig = {
81
40
  signal: this.abortSignal,
82
41
  drainTimeoutMs: this.config.drainTimeoutMs,
83
42
  reusePolicy: this.reusePolicy,
43
+ maxOutboundStreams: process.env.MAX_OUTBOUND_STREAMS
44
+ ? parseInt(process.env.MAX_OUTBOUND_STREAMS)
45
+ : 1000,
46
+ runOnLimitedConnection: this.config.runOnLimitedConnection ?? true,
84
47
  };
48
+ // Get stream from StreamManager
49
+ const wrappedStream = await this.streamManager.getOrCreateStream(protocol, this.nextHopAddress, streamConfig);
50
+ // Ensure stream is valid
51
+ wrappedStream.validate();
52
+ const stream = wrappedStream.p2pStream;
85
53
  // Send the request with backpressure handling
86
54
  const data = new TextEncoder().encode(request.toString());
87
- await this.streamHandler.sendLengthPrefixed(stream.p2pStream, data, streamConfig);
88
- // Handle response using StreamHandler
89
- // Pass request handler if configured to enable bidirectional stream processing
55
+ await this.streamManager.sendLengthPrefixed(stream, data, streamConfig);
56
+ // Handle response using StreamManager
90
57
  // Pass request ID to enable proper response correlation on shared streams
91
- const response = await this.streamHandler.handleOutgoingStream(stream.p2pStream, this.emitter, streamConfig, this.config.requestHandler, request.id);
58
+ const response = await this.streamManager.handleOutgoingStream(stream, this.emitter, streamConfig, request.id);
92
59
  // Handle cleanup of the stream
93
- await this.postTransmit(stream);
60
+ await this.postTransmit(wrappedStream);
94
61
  return response;
95
62
  }
96
63
  catch (error) {
@@ -101,7 +68,8 @@ export class oNodeConnection extends oConnection {
101
68
  }
102
69
  }
103
70
  async postTransmit(stream) {
104
- await stream.close();
71
+ // Always cleanup streams (no reuse at base layer)
72
+ await this.streamManager.releaseStream(stream.p2pStream.id);
105
73
  }
106
74
  async abort(error) {
107
75
  this.logger.debug('Aborting connection');
@@ -110,6 +78,8 @@ export class oNodeConnection extends oConnection {
110
78
  }
111
79
  async close() {
112
80
  this.logger.debug('Closing connection');
81
+ // Close stream manager (handles all stream cleanup)
82
+ await this.streamManager.close();
113
83
  await this.p2pConnection.close();
114
84
  this.logger.debug('Connection closed');
115
85
  }
@@ -42,6 +42,13 @@ export declare class oNodeConnectionManager extends oConnectionManager {
42
42
  * @param addressKey - The address key to cache under
43
43
  */
44
44
  protected cacheConnection(conn: oNodeConnection, addressKey: string): void;
45
+ /**
46
+ * Get oNodeConnection by libp2p Connection reference
47
+ * Used to find the correct oNodeConnection for incoming streams
48
+ * @param p2pConnection - The libp2p connection to search for
49
+ * @returns The oNodeConnection or undefined if not found
50
+ */
51
+ getConnectionByP2pConnection(p2pConnection: Connection): oNodeConnection | undefined;
45
52
  /**
46
53
  * Get or create a raw p2p connection to the given address.
47
54
  * Subclasses can override connect() and use this method to get the underlying p2p connection.
@@ -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,MAAM,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAQhD,QAAQ,CAAC,MAAM,EAAE,4BAA4B;IAPzD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACxC,SAAS,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACzC,iEAAiE;IACjE,SAAS,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAa;IACxE,SAAS,CAAC,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAa;gBAEzD,MAAM,EAAE,4BAA4B;IAWzD;;OAEG;IACH,SAAS,CAAC,wBAAwB,IAAI,IAAI;IA+B1C;;;;;OAKG;IACH,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI;IASzD;;;;OAIG;IACH,SAAS,CAAC,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI;IAahE;;;;;;OAMG;IACH,SAAS,CAAC,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAkBxE;;;;OAIG;IACH,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAY1E;;;OAGG;cACa,wBAAwB,CACtC,cAAc,EAAE,QAAQ,EACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC;cAoCN,WAAW,CACzB,cAAc,EAAE,QAAQ,EACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC;IAqBhB,MAAM,CACV,MAAM,EAAE,iBAAiB,GAAG;QAAE,aAAa,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GACzE,OAAO,CAAC,eAAe,CAAC;IAqD3B;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAyDlE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAcpC;;;;OAIG;IACH,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,eAAe,GAAG,IAAI;IAc9D;;;OAGG;IACH,aAAa,IAAI;QACf,eAAe,EAAE,MAAM,CAAC;QACxB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,KAAK,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,EAAE,MAAM,CAAC;YACf,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC,CAAC;KACJ;IAyBD;;;OAGG;IACH,uBAAuB,IAAI,MAAM;CAuBlC"}
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,MAAM,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAQhD,QAAQ,CAAC,MAAM,EAAE,4BAA4B;IAPzD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACxC,SAAS,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACzC,iEAAiE;IACjE,SAAS,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAa;IACxE,SAAS,CAAC,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAa;gBAEzD,MAAM,EAAE,4BAA4B;IAWzD;;OAEG;IACH,SAAS,CAAC,wBAAwB,IAAI,IAAI;IA+B1C;;;;;OAKG;IACH,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI;IASzD;;;;OAIG;IACH,SAAS,CAAC,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI;IAahE;;;;;;OAMG;IACH,SAAS,CAAC,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAkBxE;;;;OAIG;IACH,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAY1E;;;;;OAKG;IACH,4BAA4B,CAC1B,aAAa,EAAE,UAAU,GACxB,eAAe,GAAG,SAAS;IAa9B;;;OAGG;cACa,wBAAwB,CACtC,cAAc,EAAE,QAAQ,EACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC;cAoCN,WAAW,CACzB,cAAc,EAAE,QAAQ,EACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC;IAqBhB,MAAM,CACV,MAAM,EAAE,iBAAiB,GAAG;QAAE,aAAa,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GACzE,OAAO,CAAC,eAAe,CAAC;IA4D3B;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAwDlE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAcpC;;;;OAIG;IACH,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,eAAe,GAAG,IAAI;IAc9D;;;OAGG;IACH,aAAa,IAAI;QACf,eAAe,EAAE,MAAM,CAAC;QACxB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,KAAK,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,EAAE,MAAM,CAAC;YACf,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC,CAAC;KACJ;IAyBD;;;OAGG;IACH,uBAAuB,IAAI,MAAM;CAuBlC"}
@@ -104,6 +104,22 @@ export class oNodeConnectionManager extends oConnectionManager {
104
104
  existing.push(conn);
105
105
  this.cachedConnections.set(addressKey, existing);
106
106
  }
107
+ /**
108
+ * Get oNodeConnection by libp2p Connection reference
109
+ * Used to find the correct oNodeConnection for incoming streams
110
+ * @param p2pConnection - The libp2p connection to search for
111
+ * @returns The oNodeConnection or undefined if not found
112
+ */
113
+ getConnectionByP2pConnection(p2pConnection) {
114
+ // Search through all cached connections
115
+ for (const connections of this.cachedConnections.values()) {
116
+ const found = connections.find((conn) => conn.p2pConnection.id === p2pConnection.id);
117
+ if (found) {
118
+ return found;
119
+ }
120
+ }
121
+ return undefined;
122
+ }
107
123
  /**
108
124
  * Get or create a raw p2p connection to the given address.
109
125
  * Subclasses can override connect() and use this method to get the underlying p2p connection.
@@ -155,9 +171,13 @@ export class oNodeConnectionManager extends oConnectionManager {
155
171
  this.logger.error('Failed to generate an address key for address:', nextHopAddress);
156
172
  throw new Error(`Unable to extract address key from address: ${nextHopAddress.toString()}`);
157
173
  }
158
- // Check if we already have a cached connection for this address
159
- const existingConnection = this.getValidConnection(addressKey);
160
- if (existingConnection) {
174
+ // Check if we already have a cached connection for this address with the same connection id
175
+ const connections = this.cachedConnections.get(addressKey) || [];
176
+ // Filter to open connections
177
+ const validConnections = connections.filter((c) => c.p2pConnection?.id === p2pConnection.id &&
178
+ c.p2pConnection?.status === 'open');
179
+ if (validConnections.length > 0) {
180
+ const existingConnection = validConnections[0];
161
181
  this.logger.debug('Reusing cached connection for answer:', addressKey, existingConnection.p2pConnection.id);
162
182
  return existingConnection;
163
183
  }
@@ -171,7 +191,6 @@ export class oNodeConnectionManager extends oConnectionManager {
171
191
  isStream: config.isStream ?? false,
172
192
  abortSignal: config.abortSignal,
173
193
  runOnLimitedConnection: this.config.runOnLimitedConnection ?? false,
174
- requestHandler: config.requestHandler ?? undefined,
175
194
  reusePolicy: reuse ? 'reuse' : 'none',
176
195
  });
177
196
  // Cache the new connection
@@ -211,7 +230,6 @@ export class oNodeConnectionManager extends oConnectionManager {
211
230
  isStream: config.isStream ?? false,
212
231
  abortSignal: config.abortSignal,
213
232
  runOnLimitedConnection: this.config.runOnLimitedConnection ?? false,
214
- requestHandler: config.requestHandler ?? undefined,
215
233
  });
216
234
  // Cache the new connection
217
235
  this.cacheConnection(connection, addressKey);
@@ -1,8 +1,8 @@
1
1
  import type { Stream } from '@libp2p/interface';
2
2
  import { oObject } from '@olane/o-core';
3
- import { oNodeConnectionStreamConfig } from './interfaces/o-node-connection-stream.config.js';
3
+ import { oNodeStreamConfig } from './interfaces/o-node-stream.config.js';
4
4
  /**
5
- * oNodeConnectionStream wraps a libp2p Stream with caller/receiver address metadata
5
+ * oNodeStream wraps a libp2p Stream with caller/receiver address metadata
6
6
  * to enable proper stream reuse based on address pairs rather than protocol only.
7
7
  *
8
8
  * Key features:
@@ -10,11 +10,11 @@ import { oNodeConnectionStreamConfig } from './interfaces/o-node-connection-stre
10
10
  * - Automatic reusability checking
11
11
  * - Idle time tracking for cleanup
12
12
  */
13
- export declare class oNodeConnectionStream extends oObject {
13
+ export declare class oNodeStream extends oObject {
14
14
  readonly p2pStream: Stream;
15
- readonly config: oNodeConnectionStreamConfig;
15
+ readonly config: oNodeStreamConfig;
16
16
  readonly createdAt: number;
17
- constructor(p2pStream: Stream, config: oNodeConnectionStreamConfig);
17
+ constructor(p2pStream: Stream, config: oNodeStreamConfig);
18
18
  validate(): void;
19
19
  /**
20
20
  * Checks if the stream is in a valid state:
@@ -43,4 +43,4 @@ export declare class oNodeConnectionStream extends oObject {
43
43
  get isRequestResponse(): boolean;
44
44
  close(): Promise<void>;
45
45
  }
46
- //# sourceMappingURL=o-node-connection-stream.d.ts.map
46
+ //# sourceMappingURL=o-node-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"o-node-stream.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAuB,OAAO,EAAiB,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE;;;;;;;;GAQG;AACH,qBAAa,WAAY,SAAQ,OAAO;aAIpB,SAAS,EAAE,MAAM;aACjB,MAAM,EAAE,iBAAiB;IAJ3C,SAAgB,SAAS,EAAE,MAAM,CAAC;gBAGhB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,iBAAiB;IAO3C,QAAQ;IA6BR;;;;;;;OAOG;IACH,IAAI,OAAO,IAAI,OAAO,CAMrB;IAED;;OAEG;IACH,IAAI,GAAG,IAAI,MAAM,CAEhB;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;OAEG;IACH,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED;;OAEG;IACH,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAgB7B"}
@@ -1,6 +1,6 @@
1
1
  import { oError, oErrorCodes, oObject } from '@olane/o-core';
2
2
  /**
3
- * oNodeConnectionStream wraps a libp2p Stream with caller/receiver address metadata
3
+ * oNodeStream wraps a libp2p Stream with caller/receiver address metadata
4
4
  * to enable proper stream reuse based on address pairs rather than protocol only.
5
5
  *
6
6
  * Key features:
@@ -8,7 +8,7 @@ import { oError, oErrorCodes, oObject } from '@olane/o-core';
8
8
  * - Automatic reusability checking
9
9
  * - Idle time tracking for cleanup
10
10
  */
11
- export class oNodeConnectionStream extends oObject {
11
+ export class oNodeStream extends oObject {
12
12
  constructor(p2pStream, config) {
13
13
  super();
14
14
  this.p2pStream = p2pStream;
@@ -0,0 +1,181 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from 'events';
3
+ import type { Connection, Stream } from '@libp2p/interface';
4
+ import { oObject, oResponse } from '@olane/o-core';
5
+ import type { oRouterRequest, oConnection } from '@olane/o-core';
6
+ import { oNodeStream } from './o-node-stream.js';
7
+ import { StreamManagerConfig } from './interfaces/stream-manager.config.js';
8
+ import type { StreamHandlerConfig } from './stream-handler.config.js';
9
+ import { StreamManagerEvent, StreamManagerEventData } from './stream-manager.events.js';
10
+ import { StreamInitMessage } from './interfaces/stream-init-message.js';
11
+ /**
12
+ * oNodeStreamManager handles the lifecycle and tracking of streams for a single connection.
13
+ * Features:
14
+ * - Tracks all streams by ID
15
+ * - Creates new streams on demand
16
+ * - Manages stream lifecycle (cleanup after use)
17
+ * - Provides events for monitoring
18
+ * - No reuse at base layer (extensible in subclasses)
19
+ */
20
+ export declare class oNodeStreamManager extends oObject {
21
+ readonly config: StreamManagerConfig;
22
+ private streams;
23
+ protected eventEmitter: EventEmitter;
24
+ protected isInitialized: boolean;
25
+ private p2pConnection;
26
+ private activeStreamHandlers;
27
+ protected callerReaderStream?: Stream;
28
+ constructor(config: StreamManagerConfig);
29
+ /**
30
+ * Initialize the stream manager
31
+ */
32
+ initialize(): Promise<void>;
33
+ /**
34
+ * Gets or creates a stream for the connection
35
+ * Always creates a new stream (no reuse at base layer)
36
+ *
37
+ * For limited connections (where caller has identified a reader stream):
38
+ * - If callerReaderStream exists, wrap and return it for sending requests
39
+ * - Otherwise, create new stream as normal
40
+ *
41
+ * @param protocol - The protocol string for the stream
42
+ * @param remoteAddress - The remote address for the stream
43
+ * @param config - Stream handler configuration
44
+ * @returns Wrapped stream
45
+ */
46
+ getOrCreateStream(protocol: string, remoteAddress: any, config?: StreamHandlerConfig): Promise<oNodeStream>;
47
+ /**
48
+ * Creates a new stream from the connection
49
+ *
50
+ * @param protocol - The protocol string for the stream
51
+ * @param remoteAddress - The remote address for the stream
52
+ * @param config - Stream handler configuration
53
+ * @returns Wrapped stream
54
+ */
55
+ createStream(protocol: string, remoteAddress: any, config?: StreamHandlerConfig): Promise<oNodeStream>;
56
+ /**
57
+ * Releases and cleans up a stream
58
+ *
59
+ * @param streamId - The ID of the stream to release
60
+ */
61
+ releaseStream(streamId: string): Promise<void>;
62
+ /**
63
+ * Gets all tracked streams
64
+ *
65
+ * @returns Array of wrapped streams
66
+ */
67
+ getAllStreams(): oNodeStream[];
68
+ /**
69
+ * Emits an async event and waits for the first listener to return a result
70
+ * This enables event-based request handling with async responses
71
+ */
72
+ private emitAsync;
73
+ /**
74
+ * Detects if a decoded message is a request
75
+ * Requests have a 'method' field and no 'result' field
76
+ */
77
+ isRequest(message: any): boolean;
78
+ /**
79
+ * Detects if a decoded message is a response
80
+ * Responses have a 'result' field and no 'method' field
81
+ */
82
+ isResponse(message: any): boolean;
83
+ /**
84
+ * Detects if a decoded message is a stream initialization message
85
+ * Uses the imported type guard from stream-init-message.ts
86
+ */
87
+ isStreamInit(message: any): message is StreamInitMessage;
88
+ /**
89
+ * Handles a stream initialization message
90
+ * Stores reference to caller's reader stream for bidirectional communication
91
+ *
92
+ * @param message - The decoded stream init message
93
+ * @param stream - The stream that sent the message
94
+ */
95
+ protected handleStreamInitMessage(message: StreamInitMessage, stream: Stream): void;
96
+ /**
97
+ * Extracts and parses JSON from various formats including:
98
+ * - Already parsed objects
99
+ * - Plain JSON
100
+ * - Markdown code blocks (```json ... ``` or ``` ... ```)
101
+ * - Mixed content with explanatory text
102
+ * - JSON5 format (trailing commas, comments, unquoted keys, etc.)
103
+ *
104
+ * @param decoded - The decoded string that may contain JSON, or an already parsed object
105
+ * @returns Parsed JSON object
106
+ * @throws Error if JSON parsing fails even with JSON5 fallback
107
+ */
108
+ private extractAndParseJSON;
109
+ /**
110
+ * Sends data through a stream using length-prefixed encoding (libp2p v3 best practice)
111
+ * Each message is automatically prefixed with a varint indicating the message length
112
+ * This ensures proper message boundaries and eliminates concatenation issues
113
+ *
114
+ * @param stream - The stream to send data through
115
+ * @param data - The data to send
116
+ * @param config - Configuration for timeout and other options
117
+ */
118
+ sendLengthPrefixed(stream: Stream, data: Uint8Array, config?: StreamHandlerConfig): Promise<void>;
119
+ /**
120
+ * Tracks an active stream handler
121
+ */
122
+ private trackStreamHandler;
123
+ /**
124
+ * Untracks a stream handler
125
+ */
126
+ private untrackStreamHandler;
127
+ /**
128
+ * Handles an incoming stream on the server side using length-prefixed protocol
129
+ * Uses async read loops instead of event listeners (libp2p v3 best practice)
130
+ * Processes complete messages with proper boundaries
131
+ *
132
+ * @param stream - The incoming stream
133
+ * @param connection - The connection the stream belongs to
134
+ */
135
+ handleIncomingStream(stream: Stream, connection: Connection): Promise<void>;
136
+ /**
137
+ * Handles a request message by emitting an event and sending response
138
+ *
139
+ * @param message - The decoded request message
140
+ * @param stream - The stream to send the response on
141
+ * @param connection - The connection the stream belongs to
142
+ */
143
+ private handleRequestMessage;
144
+ /**
145
+ * Handles an outgoing stream on the client side using length-prefixed protocol
146
+ * Uses async read loops to process responses with proper message boundaries
147
+ *
148
+ * @param stream - The outgoing stream
149
+ * @param emitter - Event emitter for chunk events
150
+ * @param config - Configuration including abort signal
151
+ * @param requestId - Optional request ID to filter responses (for stream reuse scenarios)
152
+ * @returns Promise that resolves with the final response
153
+ */
154
+ handleOutgoingStream(stream: Stream, emitter: EventEmitter, config?: StreamHandlerConfig, requestId?: string | number): Promise<oResponse>;
155
+ /**
156
+ * Forwards a request to the next hop and relays response chunks back
157
+ * This implements the middleware/proxy pattern for intermediate nodes
158
+ *
159
+ * @param request - The router request to forward
160
+ * @param incomingStream - The stream to send responses back on
161
+ * @param dialFn - Function to dial the next hop connection
162
+ */
163
+ forwardRequest(request: oRouterRequest, incomingStream: Stream, dialFn: (address: string) => Promise<oConnection>): Promise<void>;
164
+ /**
165
+ * Close the stream manager and cleanup resources
166
+ */
167
+ close(): Promise<void>;
168
+ /**
169
+ * Add event listener
170
+ */
171
+ on<K extends StreamManagerEvent>(event: K | string, listener: (data: StreamManagerEventData[K]) => void): void;
172
+ /**
173
+ * Remove event listener
174
+ */
175
+ off<K extends StreamManagerEvent>(event: K | string, listener: (data: StreamManagerEventData[K]) => void): void;
176
+ /**
177
+ * Emit event
178
+ */
179
+ private emit;
180
+ }
181
+ //# sourceMappingURL=o-node-stream.manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"o-node-stream.manager.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-stream.manager.ts"],"names":[],"mappings":"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"}