@olane/o-node 0.7.55 → 0.7.57
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/enums/o-node-message-event.d.ts +14 -0
- package/dist/src/connection/enums/o-node-message-event.d.ts.map +1 -0
- package/dist/src/connection/enums/o-node-message-event.js +5 -0
- package/dist/src/connection/index.d.ts +0 -3
- package/dist/src/connection/index.d.ts.map +1 -1
- package/dist/src/connection/index.js +0 -3
- package/dist/src/connection/interfaces/abort-signal.config.d.ts +5 -0
- package/dist/src/connection/interfaces/abort-signal.config.d.ts.map +1 -0
- package/dist/src/connection/interfaces/o-node-connection-manager.config.d.ts +13 -1
- package/dist/src/connection/interfaces/o-node-connection-manager.config.d.ts.map +1 -1
- package/dist/src/connection/interfaces/o-node-connection.config.d.ts +18 -5
- package/dist/src/connection/interfaces/o-node-connection.config.d.ts.map +1 -1
- package/dist/src/connection/interfaces/o-node-stream.config.d.ts +3 -11
- package/dist/src/connection/interfaces/o-node-stream.config.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.d.ts +29 -53
- package/dist/src/connection/o-node-connection.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.js +102 -149
- package/dist/src/connection/o-node-connection.manager.d.ts +12 -8
- package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.manager.js +49 -35
- package/dist/src/connection/o-node-stream.d.ts +48 -15
- package/dist/src/connection/o-node-stream.d.ts.map +1 -1
- package/dist/src/connection/o-node-stream.js +143 -31
- package/dist/src/connection/stream-handler.config.d.ts +0 -11
- package/dist/src/connection/stream-handler.config.d.ts.map +1 -1
- package/dist/src/lib/interfaces/o-node-request-manager.config.d.ts +9 -0
- package/dist/src/lib/interfaces/o-node-request-manager.config.d.ts.map +1 -0
- package/dist/src/lib/interfaces/o-node-request-manager.config.js +1 -0
- package/dist/src/lib/o-node-request-manager.d.ts +46 -0
- package/dist/src/lib/o-node-request-manager.d.ts.map +1 -0
- package/dist/src/lib/o-node-request-manager.js +173 -0
- package/dist/src/managers/o-reconnection.manager.d.ts.map +1 -1
- package/dist/src/managers/o-reconnection.manager.js +4 -0
- package/dist/src/managers/o-registration.manager.d.ts.map +1 -1
- package/dist/src/managers/o-registration.manager.js +9 -4
- package/dist/src/o-node.d.ts +6 -7
- package/dist/src/o-node.d.ts.map +1 -1
- package/dist/src/o-node.js +22 -37
- package/dist/src/o-node.tool.d.ts +3 -3
- package/dist/src/o-node.tool.d.ts.map +1 -1
- package/dist/src/o-node.tool.js +28 -56
- package/dist/src/router/o-node.router.d.ts.map +1 -1
- package/dist/src/router/o-node.router.js +4 -2
- package/dist/test/connection-management.spec.js +3 -0
- package/package.json +7 -7
- package/dist/src/connection/interfaces/stream-init-message.d.ts +0 -64
- package/dist/src/connection/interfaces/stream-init-message.d.ts.map +0 -1
- package/dist/src/connection/interfaces/stream-init-message.js +0 -18
- package/dist/src/connection/interfaces/stream-manager.config.d.ts +0 -8
- package/dist/src/connection/interfaces/stream-manager.config.d.ts.map +0 -1
- package/dist/src/connection/o-node-stream.manager.d.ts +0 -210
- package/dist/src/connection/o-node-stream.manager.d.ts.map +0 -1
- package/dist/src/connection/o-node-stream.manager.js +0 -696
- /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 streamAddress = oNodeAddress.fromProtocol('o://reuse');
|
|
95
|
+
const oConnection = await this.connectionManager.answer({
|
|
96
|
+
nextHopAddress: streamAddress,
|
|
97
|
+
targetAddress: streamAddress,
|
|
98
|
+
callerAddress: streamAddress,
|
|
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;
|
|
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;
|
|
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
|
-
//
|
|
145
|
-
|
|
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 =
|
|
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 =
|
|
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,
|
package/dist/src/o-node.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
package/dist/src/o-node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-node.d.ts","sourceRoot":"","sources":["../../src/o-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,MAAM,EACN,YAAY,EAEb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"o-node.d.ts","sourceRoot":"","sources":["../../src/o-node.ts"],"names":[],"mappings":"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"}
|
package/dist/src/o-node.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
12
|
+
requestManager: oNodeRequestManager;
|
|
12
13
|
handleProtocol(address: oAddress): Promise<void>;
|
|
13
14
|
initializeProtocols(): Promise<void>;
|
|
14
15
|
initialize(): Promise<void>;
|
|
15
|
-
|
|
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;;
|
|
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;IAYnB,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"}
|
package/dist/src/o-node.tool.js
CHANGED
|
@@ -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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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...');
|
|
@@ -59,48 +62,17 @@ export class oNodeTool extends oTool(oServerNode) {
|
|
|
59
62
|
this.staticAddress?.toString() !== this.address.toString()) {
|
|
60
63
|
await this.handleProtocol(this.staticAddress);
|
|
61
64
|
}
|
|
65
|
+
await this.handleProtocol(new oNodeAddress('o://reuse'));
|
|
62
66
|
}
|
|
63
67
|
async initialize() {
|
|
64
68
|
await super.initialize();
|
|
65
69
|
await this.initializeProtocols();
|
|
66
70
|
}
|
|
67
|
-
async
|
|
68
|
-
return this.
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
}
|
|
71
|
+
async handleStream(stream, connection) {
|
|
72
|
+
return this.requestManager.receiveStream({
|
|
73
|
+
stream,
|
|
74
|
+
connection,
|
|
100
75
|
});
|
|
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
76
|
}
|
|
105
77
|
async _tool_identify() {
|
|
106
78
|
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;
|
|
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
|
-
|
|
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
|
|
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.
|
|
3
|
+
"version": "0.7.57",
|
|
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.
|
|
43
|
+
"@olane/o-test": "0.7.57",
|
|
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.
|
|
64
|
-
"@olane/o-core": "0.7.
|
|
65
|
-
"@olane/o-protocol": "0.7.
|
|
66
|
-
"@olane/o-tool": "0.7.
|
|
63
|
+
"@olane/o-config": "0.7.57",
|
|
64
|
+
"@olane/o-core": "0.7.57",
|
|
65
|
+
"@olane/o-protocol": "0.7.57",
|
|
66
|
+
"@olane/o-tool": "0.7.57",
|
|
67
67
|
"debug": "^4.4.1",
|
|
68
68
|
"dotenv": "^16.5.0",
|
|
69
69
|
"json5": "^2.2.3"
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "2528b14a811472157ca94927ef6f3b39ccd31886"
|
|
72
72
|
}
|