@olane/o-node 0.7.40 → 0.7.41

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 (45) hide show
  1. package/dist/src/connection/index.d.ts +1 -1
  2. package/dist/src/connection/index.d.ts.map +1 -1
  3. package/dist/src/connection/index.js +1 -1
  4. package/dist/src/connection/interfaces/o-node-connection-stream.config.d.ts +8 -0
  5. package/dist/src/connection/interfaces/o-node-connection-stream.config.d.ts.map +1 -0
  6. package/dist/src/connection/interfaces/o-node-connection-stream.config.js +1 -0
  7. package/dist/src/connection/o-node-connection-stream.d.ts +34 -0
  8. package/dist/src/connection/o-node-connection-stream.d.ts.map +1 -0
  9. package/dist/src/connection/o-node-connection-stream.js +68 -0
  10. package/dist/src/connection/o-node-connection.d.ts +10 -4
  11. package/dist/src/connection/o-node-connection.d.ts.map +1 -1
  12. package/dist/src/connection/o-node-connection.js +51 -34
  13. package/dist/src/connection/o-node-connection.manager.d.ts +4 -0
  14. package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
  15. package/dist/src/connection/o-node-connection.manager.js +24 -0
  16. package/dist/src/connection/stream-handler.d.ts +1 -59
  17. package/dist/src/connection/stream-handler.d.ts.map +1 -1
  18. package/dist/src/connection/stream-handler.js +104 -179
  19. package/dist/src/o-node.tool.d.ts +3 -1
  20. package/dist/src/o-node.tool.d.ts.map +1 -1
  21. package/dist/src/o-node.tool.js +44 -11
  22. package/dist/src/router/o-node.address.d.ts +1 -0
  23. package/dist/src/router/o-node.address.d.ts.map +1 -1
  24. package/dist/src/router/o-node.address.js +4 -0
  25. package/dist/src/utils/connection.utils.d.ts +9 -0
  26. package/dist/src/utils/connection.utils.d.ts.map +1 -0
  27. package/dist/src/utils/connection.utils.js +26 -0
  28. package/dist/src/utils/index.d.ts +1 -0
  29. package/dist/src/utils/index.d.ts.map +1 -1
  30. package/dist/src/utils/index.js +1 -0
  31. package/dist/test/astream-reuse.spec.d.ts +2 -0
  32. package/dist/test/astream-reuse.spec.d.ts.map +1 -0
  33. package/dist/test/astream-reuse.spec.js +107 -0
  34. package/dist/test/connection-management.spec.js +1 -0
  35. package/dist/test/helpers/network-builder.d.ts.map +1 -1
  36. package/package.json +7 -7
  37. package/dist/src/connection/o-managed-stream.d.ts +0 -57
  38. package/dist/src/connection/o-managed-stream.d.ts.map +0 -1
  39. package/dist/src/connection/o-managed-stream.js +0 -76
  40. package/dist/test/o-managed-stream.spec.d.ts +0 -2
  41. package/dist/test/o-managed-stream.spec.d.ts.map +0 -1
  42. package/dist/test/o-managed-stream.spec.js +0 -122
  43. package/dist/test/stream-handler-caching.spec.d.ts +0 -2
  44. package/dist/test/stream-handler-caching.spec.d.ts.map +0 -1
  45. package/dist/test/stream-handler-caching.spec.js +0 -261
@@ -2,6 +2,6 @@ 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 './o-managed-stream.js';
5
+ export * from './o-node-connection-stream.js';
6
6
  export * from './stream-handler.config.js';
7
7
  //# 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,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,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,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC"}
@@ -2,5 +2,5 @@ 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 './o-managed-stream.js';
5
+ export * from './o-node-connection-stream.js';
6
6
  export * from './stream-handler.config.js';
@@ -0,0 +1,8 @@
1
+ import { oAddress } from '@olane/o-core';
2
+ import { StreamReusePolicy } from '../stream-handler.config';
3
+ export interface oNodeConnectionStreamConfig {
4
+ direction: 'inbound' | 'outbound';
5
+ reusePolicy: StreamReusePolicy;
6
+ remoteAddress: oAddress;
7
+ }
8
+ //# sourceMappingURL=o-node-connection-stream.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"o-node-connection-stream.config.d.ts","sourceRoot":"","sources":["../../../../src/connection/interfaces/o-node-connection-stream.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,SAAS,GAAG,UAAU,CAAC;IAClC,WAAW,EAAE,iBAAiB,CAAC;IAC/B,aAAa,EAAE,QAAQ,CAAC;CACzB"}
@@ -0,0 +1,34 @@
1
+ import type { Stream } from '@libp2p/interface';
2
+ import { oObject } from '@olane/o-core';
3
+ import { oNodeConnectionStreamConfig } from './interfaces/o-node-connection-stream.config.js';
4
+ /**
5
+ * oNodeConnectionStream wraps a libp2p Stream with caller/receiver address metadata
6
+ * to enable proper stream reuse based on address pairs rather than protocol only.
7
+ *
8
+ * Key features:
9
+ * - Bidirectional cache keys: A↔B === B↔A
10
+ * - Automatic reusability checking
11
+ * - Idle time tracking for cleanup
12
+ */
13
+ export declare class oNodeConnectionStream extends oObject {
14
+ readonly p2pStream: Stream;
15
+ readonly config: oNodeConnectionStreamConfig;
16
+ readonly createdAt: number;
17
+ constructor(p2pStream: Stream, config: oNodeConnectionStreamConfig);
18
+ validate(): void;
19
+ /**
20
+ * Checks if the stream is in a valid state:
21
+ * - Stream status is 'open'
22
+ * - Write status is 'writable'
23
+ * - Remote read status is 'readable'
24
+ *
25
+ * @returns true if stream can be used
26
+ */
27
+ get isValid(): boolean;
28
+ /**
29
+ * Gets the age of the stream in milliseconds
30
+ */
31
+ get age(): number;
32
+ close(): Promise<void>;
33
+ }
34
+ //# sourceMappingURL=o-node-connection-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"o-node-connection-stream.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAuB,OAAO,EAAiB,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,2BAA2B,EAAE,MAAM,iDAAiD,CAAC;AAE9F;;;;;;;;GAQG;AACH,qBAAa,qBAAsB,SAAQ,OAAO;aAI9B,SAAS,EAAE,MAAM;aACjB,MAAM,EAAE,2BAA2B;IAJrD,SAAgB,SAAS,EAAE,MAAM,CAAC;gBAGhB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,2BAA2B;IAOrD,QAAQ;IA6BR;;;;;;;OAOG;IACH,IAAI,OAAO,IAAI,OAAO,CAMrB;IAED;;OAEG;IACH,IAAI,GAAG,IAAI,MAAM,CAEhB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAgB7B"}
@@ -0,0 +1,68 @@
1
+ import { oError, oErrorCodes, oObject } from '@olane/o-core';
2
+ /**
3
+ * oNodeConnectionStream wraps a libp2p Stream with caller/receiver address metadata
4
+ * to enable proper stream reuse based on address pairs rather than protocol only.
5
+ *
6
+ * Key features:
7
+ * - Bidirectional cache keys: A↔B === B↔A
8
+ * - Automatic reusability checking
9
+ * - Idle time tracking for cleanup
10
+ */
11
+ export class oNodeConnectionStream extends oObject {
12
+ constructor(p2pStream, config) {
13
+ super();
14
+ this.p2pStream = p2pStream;
15
+ this.config = config;
16
+ this.createdAt = Date.now();
17
+ }
18
+ // callable pattern to disrupt flow if not in valid state
19
+ validate() {
20
+ // do nothing
21
+ if (!this.p2pStream ||
22
+ (this.p2pStream.status !== 'open' && this.p2pStream.status !== 'reset')) {
23
+ throw new oError(oErrorCodes.FAILED_TO_DIAL_TARGET, 'Failed to dial target');
24
+ }
25
+ if (this.p2pStream.status === 'reset') {
26
+ this.logger.debug('P2P stream failed to create, status:', this.p2pStream.status);
27
+ throw new oError(oErrorCodes.CONNECTION_LIMIT_REACHED, 'Connection limit reached or configuration prevented stream creation');
28
+ }
29
+ if (!this.isValid) {
30
+ throw new oError(oErrorCodes.INVALID_STATE, 'Session is not in a valid state');
31
+ }
32
+ }
33
+ /**
34
+ * Checks if the stream is in a valid state:
35
+ * - Stream status is 'open'
36
+ * - Write status is 'writable'
37
+ * - Remote read status is 'readable'
38
+ *
39
+ * @returns true if stream can be used
40
+ */
41
+ get isValid() {
42
+ return (this.p2pStream.status === 'open' &&
43
+ this.p2pStream.writeStatus === 'writable' &&
44
+ this.p2pStream.remoteReadStatus === 'readable');
45
+ }
46
+ /**
47
+ * Gets the age of the stream in milliseconds
48
+ */
49
+ get age() {
50
+ return Date.now() - this.createdAt;
51
+ }
52
+ async close() {
53
+ // Don't close if reuse policy is enabled
54
+ if (this.config.reusePolicy === 'reuse') {
55
+ this.logger.debug('Stream reuse enabled, not closing stream');
56
+ return;
57
+ }
58
+ if (this.p2pStream.status === 'open') {
59
+ try {
60
+ // force the close for now until we can implement a proper close
61
+ await this.p2pStream.abort(new Error('Stream closed'));
62
+ }
63
+ catch (error) {
64
+ this.logger.debug('Error closing stream:', error.message);
65
+ }
66
+ }
67
+ }
68
+ }
@@ -1,18 +1,24 @@
1
- import { Connection, Stream } from '@olane/o-config';
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
4
  import { StreamHandler } from './stream-handler.js';
5
5
  import type { StreamReusePolicy } from './stream-handler.config.js';
6
+ import { oNodeAddress } from '../router/o-node.address.js';
7
+ import { oNodeConnectionStream } from './o-node-connection-stream.js';
6
8
  export declare class oNodeConnection extends oConnection {
7
9
  protected readonly config: oNodeConnectionConfig;
8
10
  p2pConnection: Connection;
9
11
  protected streamHandler: StreamHandler;
10
12
  protected reusePolicy: StreamReusePolicy;
11
13
  constructor(config: oNodeConnectionConfig);
12
- validate(stream?: Stream): void;
13
- getOrCreateStream(): Promise<Stream>;
14
+ get remotePeerId(): import("@olane/o-config").PeerId;
15
+ get remoteAddr(): import("@olane/o-config").Multiaddr;
16
+ supportsAddress(address: oNodeAddress): boolean;
17
+ getOrCreateStream(): Promise<oNodeConnectionStream>;
18
+ createStream(): Promise<oNodeConnectionStream>;
19
+ get streams(): oNodeConnectionStream[];
14
20
  transmit(request: oRequest): Promise<oResponse>;
15
- postTransmit(stream: Stream): Promise<void>;
21
+ postTransmit(stream: oNodeConnectionStream): Promise<void>;
16
22
  abort(error: Error): Promise<void>;
17
23
  close(): Promise<void>;
18
24
  }
@@ -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,EAAE,MAAM,EAAE,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;AAEpC,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,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IAmBlB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IA6BpC,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IA2C/C,YAAY,CAAC,MAAM,EAAE,MAAM;IAQ3B,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,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,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAMzC,iBAAiB,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAanD,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,5 +1,6 @@
1
1
  import { oConnection, oError, oErrorCodes, } from '@olane/o-core';
2
2
  import { StreamHandler } from './stream-handler.js';
3
+ import { oNodeConnectionStream } from './o-node-connection-stream.js';
3
4
  export class oNodeConnection extends oConnection {
4
5
  constructor(config) {
5
6
  super(config);
@@ -8,45 +9,64 @@ export class oNodeConnection extends oConnection {
8
9
  this.streamHandler = new StreamHandler(this.logger);
9
10
  this.reusePolicy = config.reusePolicy ?? 'none';
10
11
  }
11
- validate(stream) {
12
- if (this.config.p2pConnection.status !== 'open') {
13
- throw new Error('Connection is not valid');
14
- }
15
- // do nothing
16
- if (!stream || (stream.status !== 'open' && stream.status !== 'reset')) {
17
- throw new oError(oErrorCodes.FAILED_TO_DIAL_TARGET, 'Failed to dial target');
18
- }
19
- if (stream.status === 'reset') {
20
- throw new oError(oErrorCodes.CONNECTION_LIMIT_REACHED, 'Connection limit reached');
21
- }
12
+ get remotePeerId() {
13
+ return this.p2pConnection.remotePeer;
14
+ }
15
+ get remoteAddr() {
16
+ return this.p2pConnection.remoteAddr;
17
+ }
18
+ supportsAddress(address) {
19
+ return address.libp2pTransports.some((transport) => {
20
+ return transport.toString() === this.remoteAddr.toString();
21
+ });
22
22
  }
23
23
  async getOrCreateStream() {
24
- const streamConfig = {
24
+ if (this.reusePolicy === 'reuse' && this.streams.length > 0) {
25
+ this.logger.debug('Returning reuse stream: ', this.streams[0].p2pStream.protocol);
26
+ // search for streams that allow re-use
27
+ return this.streams[0];
28
+ }
29
+ return this.createStream();
30
+ }
31
+ async createStream() {
32
+ const protocol = this.nextHopAddress.protocol +
33
+ (this.reusePolicy === 'reuse' ? '/reuse' : ''); // connect specifically to the reuse protocol version if desired
34
+ this.logger.debug('Creating stream for protocol:', protocol);
35
+ const stream = await this.p2pConnection.newStream(protocol, {
25
36
  signal: this.abortSignal,
26
37
  maxOutboundStreams: process.env.MAX_OUTBOUND_STREAMS
27
38
  ? parseInt(process.env.MAX_OUTBOUND_STREAMS)
28
39
  : 1000,
29
40
  runOnLimitedConnection: this.config.runOnLimitedConnection ?? true,
30
- reusePolicy: this.reusePolicy,
31
- drainTimeoutMs: this.config.drainTimeoutMs,
32
- };
33
- // Build stream addresses for address-based caching
34
- const streamAddresses = this.callerAddress && this.nextHopAddress
35
- ? {
36
- callerAddress: this.callerAddress,
37
- receiverAddress: this.nextHopAddress,
38
- direction: 'outbound',
39
- }
40
- : undefined;
41
- return this.streamHandler.getOrCreateStream(this.p2pConnection, this.nextHopAddress.protocol, streamConfig, streamAddresses);
41
+ });
42
+ const managedStream = new oNodeConnectionStream(stream, {
43
+ direction: stream.direction,
44
+ reusePolicy: this.config.reusePolicy ?? 'none', // default to no re-use stream
45
+ remoteAddress: this.nextHopAddress,
46
+ });
47
+ // print the num streams
48
+ const numStreams = this.streams.map((s) => s.isValid).length;
49
+ this.logger.debug(`Connection spawned new stream: ${stream.id}. Connection now has ${numStreams} total streams open`);
50
+ return managedStream;
51
+ }
52
+ get streams() {
53
+ return (this.p2pConnection?.streams
54
+ ?.filter((s) => {
55
+ return s.protocol.includes('/o/');
56
+ })
57
+ .map((s) => {
58
+ return new oNodeConnectionStream(s, {
59
+ direction: s.direction,
60
+ reusePolicy: this.config.reusePolicy ?? 'none', // default to no re-use stream
61
+ remoteAddress: this.nextHopAddress,
62
+ });
63
+ }) || []);
42
64
  }
43
65
  async transmit(request) {
44
66
  try {
45
- // if (this.config.runOnLimitedConnection) {
46
- // this.logger.debug('Running on limited connection...');
47
- // }
48
67
  const stream = await this.getOrCreateStream();
49
- this.validate(stream);
68
+ // ensure stream is valid
69
+ stream.validate();
50
70
  const streamConfig = {
51
71
  signal: this.abortSignal,
52
72
  drainTimeoutMs: this.config.drainTimeoutMs,
@@ -54,11 +74,11 @@ export class oNodeConnection extends oConnection {
54
74
  };
55
75
  // Send the request with backpressure handling
56
76
  const data = new TextEncoder().encode(request.toString());
57
- await this.streamHandler.sendLengthPrefixed(stream, data, streamConfig);
77
+ await this.streamHandler.sendLengthPrefixed(stream.p2pStream, data, streamConfig);
58
78
  // Handle response using StreamHandler
59
79
  // Pass request handler if configured to enable bidirectional stream processing
60
80
  // Pass request ID to enable proper response correlation on shared streams
61
- const response = await this.streamHandler.handleOutgoingStream(stream, this.emitter, streamConfig, this.config.requestHandler, request.id);
81
+ const response = await this.streamHandler.handleOutgoingStream(stream.p2pStream, this.emitter, streamConfig, this.config.requestHandler, request.id);
62
82
  // Handle cleanup of the stream
63
83
  await this.postTransmit(stream);
64
84
  return response;
@@ -71,10 +91,7 @@ export class oNodeConnection extends oConnection {
71
91
  }
72
92
  }
73
93
  async postTransmit(stream) {
74
- const streamConfig = {
75
- reusePolicy: this.reusePolicy,
76
- };
77
- await this.streamHandler.close(stream, streamConfig);
94
+ await stream.close();
78
95
  }
79
96
  async abort(error) {
80
97
  this.logger.debug('Aborting connection');
@@ -30,6 +30,10 @@ export declare class oNodeConnectionManager extends oConnectionManager {
30
30
  private getPeerIdFromAddress;
31
31
  getOrCreateConnection(nextHopAddress: oAddress, address: oAddress): Promise<Connection>;
32
32
  private performDial;
33
+ answer(config: oConnectionConfig & {
34
+ p2pConnection: Connection;
35
+ reuse?: boolean;
36
+ }): Promise<oNodeConnection>;
33
37
  /**
34
38
  * Connect to a given address, reusing libp2p connections when possible
35
39
  * @param config - Connection configuration
@@ -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,EAAU,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAQhD,QAAQ,CAAC,MAAM,EAAE,4BAA4B;IAPzD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAAS;IACvC,OAAO,CAAC,yBAAyB,CAAsC;IACvE,OAAO,CAAC,0BAA0B,CACtB;gBAES,MAAM,EAAE,4BAA4B;IAWzD;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAsBhC;;;;;;OAMG;IACH,OAAO,CAAC,0BAA0B;IAiBlC;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAatB,qBAAqB,CACzB,cAAc,EAAE,QAAQ,EACxB,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,UAAU,CAAC;YA+DR,WAAW;IAwBzB;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IA8BlE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAwCpC;;;;OAIG;IACH,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,UAAU,GAAG,IAAI;IA+C/D;;;OAGG;IACH,aAAa,IAAI;QACf,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,KAAK,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC9D;IAaD;;;OAGG;IACH,uBAAuB,IAAI,MAAM;CAgBlC"}
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,EAAU,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAQhD,QAAQ,CAAC,MAAM,EAAE,4BAA4B;IAPzD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAAS;IACvC,OAAO,CAAC,yBAAyB,CAAsC;IACvE,OAAO,CAAC,0BAA0B,CACtB;gBAES,MAAM,EAAE,4BAA4B;IAWzD;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAsBhC;;;;;;OAMG;IACH,OAAO,CAAC,0BAA0B;IAiBlC;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAatB,qBAAqB,CACzB,cAAc,EAAE,QAAQ,EACxB,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,UAAU,CAAC;YA+DR,WAAW;IAwBnB,MAAM,CACV,MAAM,EAAE,iBAAiB,GAAG;QAAE,aAAa,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GACzE,OAAO,CAAC,eAAe,CAAC;IAmC3B;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IA8BlE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAwCpC;;;;OAIG;IACH,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,UAAU,GAAG,IAAI;IA+C/D;;;OAGG;IACH,aAAa,IAAI;QACf,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,KAAK,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC9D;IAaD;;;OAGG;IACH,uBAAuB,IAAI,MAAM;CAgBlC"}
@@ -130,6 +130,30 @@ export class oNodeConnectionManager extends oConnectionManager {
130
130
  });
131
131
  return connection;
132
132
  }
133
+ async answer(config) {
134
+ const { address, nextHopAddress, callerAddress, readTimeoutMs, drainTimeoutMs, p2pConnection, reuse, } = config;
135
+ const connection = new oNodeConnection({
136
+ nextHopAddress: nextHopAddress,
137
+ address: address,
138
+ p2pConnection: p2pConnection,
139
+ callerAddress: callerAddress,
140
+ readTimeoutMs: readTimeoutMs ?? this.defaultReadTimeoutMs,
141
+ drainTimeoutMs: drainTimeoutMs ?? this.defaultDrainTimeoutMs,
142
+ isStream: config.isStream ?? false,
143
+ abortSignal: config.abortSignal,
144
+ runOnLimitedConnection: this.config.runOnLimitedConnection ?? false,
145
+ requestHandler: config.requestHandler ?? undefined,
146
+ reusePolicy: reuse ? 'reuse' : 'none',
147
+ });
148
+ const transportKey = this.getTransportKeyFromAddress(nextHopAddress);
149
+ if (transportKey) {
150
+ this.connectionsByTransportKey.set(transportKey, p2pConnection);
151
+ }
152
+ else {
153
+ this.logger.error('Should not happen! Failed to generate a transport key for address:', nextHopAddress);
154
+ }
155
+ return connection;
156
+ }
133
157
  /**
134
158
  * Connect to a given address, reusing libp2p connections when possible
135
159
  * @param config - Connection configuration
@@ -4,9 +4,8 @@ import { EventEmitter } from 'events';
4
4
  import { oRequest, oResponse, Logger } from '@olane/o-core';
5
5
  import type { oRouterRequest } from '@olane/o-core';
6
6
  import type { oConnection } from '@olane/o-core';
7
- import type { oAddress } from '@olane/o-core';
8
7
  import type { RunResult } from '@olane/o-tool';
9
- import type { StreamHandlerConfig, StreamReusePolicy } from './stream-handler.config.js';
8
+ import type { StreamHandlerConfig } from './stream-handler.config.js';
10
9
  /**
11
10
  * StreamHandler centralizes all stream-related functionality including:
12
11
  * - Message type detection (request vs response)
@@ -17,7 +16,6 @@ import type { StreamHandlerConfig, StreamReusePolicy } from './stream-handler.co
17
16
  */
18
17
  export declare class StreamHandler {
19
18
  private logger;
20
- private streamCache;
21
19
  constructor(logger?: Logger);
22
20
  /**
23
21
  * Detects if a decoded message is a request
@@ -51,55 +49,6 @@ export declare class StreamHandler {
51
49
  * @returns Cache key string
52
50
  */
53
51
  private buildCacheKey;
54
- /**
55
- * Caches a managed stream for reuse
56
- *
57
- * @param managedStream - The managed stream to cache
58
- */
59
- private cacheStream;
60
- /**
61
- * Removes a stream from the cache
62
- *
63
- * @param stream - The stream to remove
64
- */
65
- private removeStreamFromCache;
66
- /**
67
- * Sets up cleanup listener for stream close events
68
- *
69
- * @param stream - The stream to monitor
70
- */
71
- private setupStreamCleanup;
72
- /**
73
- * Extracts the remote peer's address from a connection
74
- * Falls back to creating an address from the peer ID if no address metadata is available
75
- *
76
- * @param connection - The libp2p connection
77
- * @returns The remote peer's oAddress
78
- */
79
- extractRemotePeerAddress(connection: Connection): oAddress;
80
- /**
81
- * Caches an inbound stream for bidirectional reuse
82
- * This allows the same stream to be reused for responses
83
- *
84
- * @param stream - The inbound stream to cache
85
- * @param callerAddress - The address of the caller
86
- * @param receiverAddress - The address of the receiver (local node)
87
- * @param reusePolicy - Whether to enable caching
88
- */
89
- cacheInboundStream(stream: Stream, callerAddress: oAddress, receiverAddress: oAddress, reusePolicy?: StreamReusePolicy): void;
90
- /**
91
- * Gets an existing open stream or creates a new one based on reuse policy
92
- *
93
- * @param connection - The libp2p connection
94
- * @param protocol - The protocol to use for the stream
95
- * @param config - Stream handler configuration
96
- * @param streamAddresses - Optional addresses for address-based stream reuse
97
- */
98
- getOrCreateStream(connection: Connection, protocol: string, config?: StreamHandlerConfig, streamAddresses?: {
99
- callerAddress: oAddress;
100
- receiverAddress: oAddress;
101
- direction: 'inbound' | 'outbound';
102
- }): Promise<Stream>;
103
52
  /**
104
53
  * Sends data through a stream using length-prefixed encoding (libp2p v3 best practice)
105
54
  * Each message is automatically prefixed with a varint indicating the message length
@@ -110,13 +59,6 @@ export declare class StreamHandler {
110
59
  * @param config - Configuration for timeout and other options
111
60
  */
112
61
  sendLengthPrefixed(stream: Stream, data: Uint8Array, config?: StreamHandlerConfig): Promise<void>;
113
- /**
114
- * Closes a stream safely with error handling
115
- *
116
- * @param stream - The stream to close
117
- * @param config - Configuration including reuse policy
118
- */
119
- close(stream: Stream, config?: StreamHandlerConfig): Promise<void>;
120
62
  /**
121
63
  * Handles an incoming stream on the server side using length-prefixed protocol
122
64
  * Uses async read loops instead of event listeners (libp2p v3 best practice)
@@ -1 +1 @@
1
- {"version":3,"file":"stream-handler.d.ts","sourceRoot":"","sources":["../../../src/connection/stream-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stream-handler.d.ts","sourceRoot":"","sources":["../../../src/connection/stream-handler.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EACL,QAAQ,EACR,SAAS,EAIT,MAAM,EAEP,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EACV,mBAAmB,EAEpB,MAAM,4BAA4B,CAAC;AAKpC;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,CAAC,EAAE,MAAM;IAI3B;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIhC;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO;IAIjC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,mBAAmB;IAqC3B;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IA0HrB;;;;;;;;OAQG;IACG,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,IAAI,CAAC;IAKhB;;;;;;;;OAQG;IACG,oBAAoB,CACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,GACtE,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;;;;OAMG;YACW,oBAAoB;IA6BlC;;;;;;;;;;OAUG;IACG,oBAAoB,CACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,YAAY,EACrB,MAAM,GAAE,mBAAwB,EAChC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,CAAC,EAC1E,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAC1B,OAAO,CAAC,SAAS,CAAC;IAiErB;;;;;;;OAOG;IACG,cAAc,CAClB,OAAO,EAAE,cAAc,EACvB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,GAChD,OAAO,CAAC,IAAI,CAAC;CAyBjB"}