@olane/o-node 0.7.12-alpha.50 → 0.7.12-alpha.51
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.
- package/dist/src/connection/o-node-connection.d.ts +4 -2
- package/dist/src/connection/o-node-connection.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.js +39 -19
- package/dist/src/connection/o-node-connection.manager.d.ts +1 -0
- package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.manager.js +11 -7
- package/dist/src/o-node.tool.d.ts.map +1 -1
- package/dist/src/o-node.tool.js +6 -0
- package/package.json +6 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Connection } from '@olane/o-config';
|
|
1
|
+
import { Connection, Stream } 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
|
export declare class oNodeConnection extends oConnection {
|
|
@@ -6,8 +6,10 @@ export declare class oNodeConnection extends oConnection {
|
|
|
6
6
|
p2pConnection: Connection;
|
|
7
7
|
constructor(config: oNodeConnectionConfig);
|
|
8
8
|
setupConnectionListeners(): void;
|
|
9
|
-
validate(): void;
|
|
9
|
+
validate(stream?: Stream): void;
|
|
10
|
+
getOrCreateStream(): Promise<Stream>;
|
|
10
11
|
transmit(request: oRequest): Promise<oResponse>;
|
|
12
|
+
postTransmit(stream: Stream): Promise<void>;
|
|
11
13
|
abort(error: Error): Promise<void>;
|
|
12
14
|
close(): Promise<void>;
|
|
13
15
|
}
|
|
@@ -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,iBAAiB,CAAC;
|
|
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;AAEjF,qBAAa,eAAgB,SAAQ,WAAW;IAGlC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB;IAFrD,aAAa,EAAE,UAAU,CAAC;gBAEF,MAAM,EAAE,qBAAqB;IAM5D,wBAAwB;IAYxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IAmBlB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAcpC,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IA2E/C,YAAY,CAAC,MAAM,EAAE,MAAM;IAU3B,KAAK,CAAC,KAAK,EAAE,KAAK;IAMlB,KAAK;CAKZ"}
|
|
@@ -13,30 +13,37 @@ export class oNodeConnection extends oConnection {
|
|
|
13
13
|
this.logger.debug('Connection closed for address: ' + this.nextHopAddress.toString());
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
|
-
validate() {
|
|
16
|
+
validate(stream) {
|
|
17
17
|
if (this.config.p2pConnection.status !== 'open') {
|
|
18
18
|
throw new Error('Connection is not valid');
|
|
19
19
|
}
|
|
20
20
|
// do nothing
|
|
21
|
+
if (!stream || (stream.status !== 'open' && stream.status !== 'reset')) {
|
|
22
|
+
throw new oError(oErrorCodes.FAILED_TO_DIAL_TARGET, 'Failed to dial target');
|
|
23
|
+
}
|
|
24
|
+
if (stream.status === 'reset') {
|
|
25
|
+
throw new oError(oErrorCodes.CONNECTION_LIMIT_REACHED, 'Connection limit reached');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async getOrCreateStream() {
|
|
29
|
+
if (this.p2pConnection.status !== 'open') {
|
|
30
|
+
throw new oError(oErrorCodes.INVALID_STATE, 'Connection not open');
|
|
31
|
+
}
|
|
32
|
+
return this.p2pConnection.newStream(this.nextHopAddress.protocol, {
|
|
33
|
+
signal: this.abortSignal,
|
|
34
|
+
maxOutboundStreams: process.env.MAX_OUTBOUND_STREAMS
|
|
35
|
+
? parseInt(process.env.MAX_OUTBOUND_STREAMS)
|
|
36
|
+
: 1000,
|
|
37
|
+
runOnLimitedConnection: this.config.runOnLimitedConnection ?? false,
|
|
38
|
+
});
|
|
21
39
|
}
|
|
22
40
|
async transmit(request) {
|
|
23
41
|
try {
|
|
24
42
|
if (this.config.runOnLimitedConnection) {
|
|
25
43
|
this.logger.debug('Running on limited connection...');
|
|
26
44
|
}
|
|
27
|
-
const stream = await this.
|
|
28
|
-
|
|
29
|
-
maxOutboundStreams: process.env.MAX_OUTBOUND_STREAMS
|
|
30
|
-
? parseInt(process.env.MAX_OUTBOUND_STREAMS)
|
|
31
|
-
: 1000,
|
|
32
|
-
runOnLimitedConnection: this.config.runOnLimitedConnection ?? false,
|
|
33
|
-
});
|
|
34
|
-
if (!stream || (stream.status !== 'open' && stream.status !== 'reset')) {
|
|
35
|
-
throw new oError(oErrorCodes.FAILED_TO_DIAL_TARGET, 'Failed to dial target');
|
|
36
|
-
}
|
|
37
|
-
if (stream.status === 'reset') {
|
|
38
|
-
throw new oError(oErrorCodes.CONNECTION_LIMIT_REACHED, 'Connection limit reached');
|
|
39
|
-
}
|
|
45
|
+
const stream = await this.getOrCreateStream();
|
|
46
|
+
this.validate(stream);
|
|
40
47
|
// Send the data with backpressure handling (libp2p v3 best practice)
|
|
41
48
|
const data = new TextEncoder().encode(request.toString());
|
|
42
49
|
const sent = stream.send(data);
|
|
@@ -60,17 +67,21 @@ export class oNodeConnection extends oConnection {
|
|
|
60
67
|
this.emitter.emit('chunk', response);
|
|
61
68
|
// marked as the last chunk let's close
|
|
62
69
|
if (response.result._last || !response.result._isStreaming) {
|
|
63
|
-
// this.logger.debug('Last chunk received...');
|
|
64
70
|
lastResponse = response;
|
|
65
71
|
// Clean up abort listener before closing
|
|
66
72
|
if (this.abortSignal) {
|
|
67
73
|
this.abortSignal.removeEventListener('abort', abortHandler);
|
|
68
74
|
}
|
|
69
|
-
await stream.close();
|
|
70
75
|
resolve(true);
|
|
71
76
|
}
|
|
72
77
|
});
|
|
73
78
|
});
|
|
79
|
+
stream.addEventListener('close', async () => {
|
|
80
|
+
this.logger.debug('Stream closed by remote peer, closing connection...');
|
|
81
|
+
stream.close().catch((error) => {
|
|
82
|
+
this.logger.error('Error closing stream: ', error);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
74
85
|
// If send() returns false, wait for the stream to drain before continuing
|
|
75
86
|
if (!sent) {
|
|
76
87
|
this.logger.debug('Stream buffer full, waiting for drain...');
|
|
@@ -78,9 +89,8 @@ export class oNodeConnection extends oConnection {
|
|
|
78
89
|
signal: AbortSignal.timeout(this.config.drainTimeoutMs ?? 30000),
|
|
79
90
|
}); // Default: 30 second timeout
|
|
80
91
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
92
|
+
// handle cleanup of the stream
|
|
93
|
+
await this.postTransmit(stream);
|
|
84
94
|
const response = oResponse.fromJSON(lastResponse);
|
|
85
95
|
return response;
|
|
86
96
|
}
|
|
@@ -91,6 +101,16 @@ export class oNodeConnection extends oConnection {
|
|
|
91
101
|
throw error;
|
|
92
102
|
}
|
|
93
103
|
}
|
|
104
|
+
async postTransmit(stream) {
|
|
105
|
+
if (stream.status === 'open') {
|
|
106
|
+
stream.close().catch((error) => {
|
|
107
|
+
this.logger.error('Error closing stream after transmission: ', error);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this.logger.debug('Stream is not open, skipping cleanup');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
94
114
|
async abort(error) {
|
|
95
115
|
this.logger.debug('Aborting connection');
|
|
96
116
|
await this.p2pConnection.abort(error);
|
|
@@ -8,6 +8,7 @@ export declare class oNodeConnectionManager extends oConnectionManager {
|
|
|
8
8
|
private defaultReadTimeoutMs?;
|
|
9
9
|
private defaultDrainTimeoutMs?;
|
|
10
10
|
constructor(config: oNodeConnectionManagerConfig);
|
|
11
|
+
getOrCreateConnection(nextHopAddress: oAddress, address: oAddress): Promise<Connection>;
|
|
11
12
|
/**
|
|
12
13
|
* Connect to a given address, reusing libp2p connections when possible
|
|
13
14
|
* @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,EAAU,UAAU,EAAU,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAKhD,QAAQ,CAAC,MAAM,EAAE,4BAA4B;IAJzD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAAS;gBAElB,MAAM,EAAE,4BAA4B;
|
|
1
|
+
{"version":3,"file":"o-node-connection.manager.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAU,UAAU,EAAU,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAKhD,QAAQ,CAAC,MAAM,EAAE,4BAA4B;IAJzD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAAS;gBAElB,MAAM,EAAE,4BAA4B;IAOnD,qBAAqB,CACzB,cAAc,EAAE,QAAQ,EACxB,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,UAAU,CAAC;IA2BtB;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IA6BlE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IA4BpC;;;;OAIG;IACH,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,UAAU,GAAG,IAAI;CA0BhE"}
|
|
@@ -8,13 +8,7 @@ export class oNodeConnectionManager extends oConnectionManager {
|
|
|
8
8
|
this.defaultReadTimeoutMs = config.defaultReadTimeoutMs;
|
|
9
9
|
this.defaultDrainTimeoutMs = config.defaultDrainTimeoutMs;
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
* Connect to a given address, reusing libp2p connections when possible
|
|
13
|
-
* @param config - Connection configuration
|
|
14
|
-
* @returns The connection object
|
|
15
|
-
*/
|
|
16
|
-
async connect(config) {
|
|
17
|
-
const { address, nextHopAddress, callerAddress, readTimeoutMs, drainTimeoutMs, } = config;
|
|
11
|
+
async getOrCreateConnection(nextHopAddress, address) {
|
|
18
12
|
// Check if libp2p already has an active connection to this peer
|
|
19
13
|
const existingConnection = this.getCachedLibp2pConnection(nextHopAddress);
|
|
20
14
|
let p2pConnection;
|
|
@@ -27,6 +21,16 @@ export class oNodeConnectionManager extends oConnectionManager {
|
|
|
27
21
|
this.logger.debug('Dialing new connection for address: ' + address.toString());
|
|
28
22
|
p2pConnection = await this.p2pNode.dial(nextHopAddress.libp2pTransports.map((ma) => ma.toMultiaddr()));
|
|
29
23
|
}
|
|
24
|
+
return p2pConnection;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Connect to a given address, reusing libp2p connections when possible
|
|
28
|
+
* @param config - Connection configuration
|
|
29
|
+
* @returns The connection object
|
|
30
|
+
*/
|
|
31
|
+
async connect(config) {
|
|
32
|
+
const { address, nextHopAddress, callerAddress, readTimeoutMs, drainTimeoutMs, } = config;
|
|
33
|
+
const p2pConnection = await this.getOrCreateConnection(nextHopAddress, address);
|
|
30
34
|
const connection = new oNodeConnection({
|
|
31
35
|
nextHopAddress: nextHopAddress,
|
|
32
36
|
address: address,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-node.tool.d.ts","sourceRoot":"","sources":["../../src/o-node.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAGR,QAAQ,EAIT,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;;AAIrD;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAAkB;IACzC,cAAc,CAAC,OAAO,EAAE,QAAQ;IAUhC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"o-node.tool.d.ts","sourceRoot":"","sources":["../../src/o-node.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAGR,QAAQ,EAIT,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;;AAIrD;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAAkB;IACzC,cAAc,CAAC,OAAO,EAAE,QAAQ;IAUhC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA+CnE,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAQ9B,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CA2B5D"}
|
package/dist/src/o-node.tool.js
CHANGED
|
@@ -54,6 +54,12 @@ export class oNodeTool extends oTool(oServerNode) {
|
|
|
54
54
|
};
|
|
55
55
|
// Attach listener synchronously before any async operations
|
|
56
56
|
stream.addEventListener('message', messageHandler);
|
|
57
|
+
stream.addEventListener('close', () => {
|
|
58
|
+
this.logger.debug('Stream closed by remote peer');
|
|
59
|
+
stream.close().catch((error) => {
|
|
60
|
+
this.logger.error('Error closing stream: ', error);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
57
63
|
}
|
|
58
64
|
async _tool_identify() {
|
|
59
65
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olane/o-node",
|
|
3
|
-
"version": "0.7.12-alpha.
|
|
3
|
+
"version": "0.7.12-alpha.51",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -54,12 +54,12 @@
|
|
|
54
54
|
"typescript": "5.4.5"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@olane/o-config": "0.7.12-alpha.
|
|
58
|
-
"@olane/o-core": "0.7.12-alpha.
|
|
59
|
-
"@olane/o-protocol": "0.7.12-alpha.
|
|
60
|
-
"@olane/o-tool": "0.7.12-alpha.
|
|
57
|
+
"@olane/o-config": "0.7.12-alpha.51",
|
|
58
|
+
"@olane/o-core": "0.7.12-alpha.51",
|
|
59
|
+
"@olane/o-protocol": "0.7.12-alpha.51",
|
|
60
|
+
"@olane/o-tool": "0.7.12-alpha.51",
|
|
61
61
|
"debug": "^4.4.1",
|
|
62
62
|
"dotenv": "^16.5.0"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "b877e1e95a2bf32845ec30072eb72422fd25aba7"
|
|
65
65
|
}
|