@olane/o-node 0.7.48 → 0.7.50

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.
@@ -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;IAQ5D,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;IAkBnD,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,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"}
@@ -8,7 +8,6 @@ export class oNodeConnection extends oConnection {
8
8
  this.p2pConnection = config.p2pConnection;
9
9
  this.streamHandler = new StreamHandler(this.logger);
10
10
  this.reusePolicy = config.reusePolicy ?? 'none';
11
- console.log('oNodeConnection constructor', this.reusePolicy);
12
11
  }
13
12
  get remotePeerId() {
14
13
  return this.p2pConnection.remotePeer;
@@ -28,7 +27,6 @@ export class oNodeConnection extends oConnection {
28
27
  });
29
28
  }
30
29
  async getOrCreateStream() {
31
- console.log('getOrCreateStream', this.reusePolicy);
32
30
  if (this.reusePolicy === 'reuse') {
33
31
  this.logger.debug('Reusing stream...');
34
32
  // search for streams that allow re-use
@@ -1,6 +1,7 @@
1
1
  import { oAddress, NodeState, oNotificationManager } from '@olane/o-core';
2
2
  import { oNodeAddress } from '../router/o-node.address.js';
3
3
  import { oNodeConfig } from './o-node.config.js';
4
+ import { oRegistrationManager } from '../managers/o-registration.manager.js';
4
5
  /**
5
6
  * Interface for nodes that support reconnection management.
6
7
  * This interface defines the contract that oReconnectionManager needs
@@ -23,10 +24,18 @@ export interface IReconnectableNode {
23
24
  * The notification manager for subscribing to events
24
25
  */
25
26
  notificationManager: oNotificationManager;
27
+ /**
28
+ * The registration manager for tracking registration state
29
+ */
30
+ registrationManager: oRegistrationManager;
26
31
  /**
27
32
  * Register with the parent node
28
33
  */
29
34
  registerParent(): Promise<void>;
35
+ /**
36
+ * Register with the leader's global registry
37
+ */
38
+ registerLeader(): Promise<void>;
30
39
  /**
31
40
  * Register with the leader's global registry
32
41
  */
@@ -1 +1 @@
1
- {"version":3,"file":"i-reconnectable-node.d.ts","sourceRoot":"","sources":["../../../src/interfaces/i-reconnectable-node.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,SAAS,EACT,oBAAoB,EAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IAEtB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,mBAAmB,EAAE,oBAAoB,CAAC;IAE1C;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAErC;;OAEG;IACH,GAAG,CACD,OAAO,EAAE,QAAQ,EACjB,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;SAAE,CAAC;QAChC,EAAE,CAAC,EAAE,MAAM,CAAC;KACb,GACA,OAAO,CAAC,GAAG,CAAC,CAAC;CACjB"}
1
+ {"version":3,"file":"i-reconnectable-node.d.ts","sourceRoot":"","sources":["../../../src/interfaces/i-reconnectable-node.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,SAAS,EACT,oBAAoB,EAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAE7E;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IAEtB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,mBAAmB,EAAE,oBAAoB,CAAC;IAE1C;;OAEG;IACH,mBAAmB,EAAE,oBAAoB,CAAC;IAE1C;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAErC;;OAEG;IACH,GAAG,CACD,OAAO,EAAE,QAAQ,EACjB,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;SAAE,CAAC;QAChC,EAAE,CAAC,EAAE,MAAM,CAAC;KACb,GACA,OAAO,CAAC,GAAG,CAAC,CAAC;CACjB"}
@@ -0,0 +1,75 @@
1
+ import { oAddress, NodeType } from '@olane/o-core';
2
+ import { PeerId } from '@olane/o-config';
3
+ import { oNodeAddress } from '../router/o-node.address.js';
4
+ import { oNodeConfig } from './o-node.config.js';
5
+ import { oNodeTransport } from '../router/o-node.transport.js';
6
+ import { oNodeHierarchyManager } from '../o-node.hierarchy-manager.js';
7
+ export interface IReconnectionManager {
8
+ waitForParentAndReconnect(): Promise<void>;
9
+ }
10
+ /**
11
+ * Interface for nodes that support registration management.
12
+ * This interface defines the contract that oRegistrationManager needs
13
+ * to perform registration operations.
14
+ */
15
+ export interface IRegistrableNode {
16
+ /**
17
+ * The node's configuration
18
+ */
19
+ config: oNodeConfig;
20
+ /**
21
+ * The node's current address
22
+ */
23
+ address: oNodeAddress;
24
+ /**
25
+ * The node's static address (without dynamic transports)
26
+ */
27
+ staticAddress: oNodeAddress;
28
+ /**
29
+ * The leader address (null for leader nodes)
30
+ */
31
+ leader: oNodeAddress | null;
32
+ /**
33
+ * The parent address (null for root nodes)
34
+ */
35
+ parent: oNodeAddress | null;
36
+ /**
37
+ * The node type (LEADER, CLIENT, etc.)
38
+ */
39
+ type: NodeType;
40
+ /**
41
+ * The node's peer ID
42
+ */
43
+ peerId: PeerId;
44
+ /**
45
+ * The node's current transports
46
+ */
47
+ transports: oNodeTransport[];
48
+ /**
49
+ * The node's protocols
50
+ */
51
+ protocols: string[];
52
+ /**
53
+ * Hierarchy manager for tracking parent/child/leader relationships
54
+ */
55
+ hierarchyManager: oNodeHierarchyManager;
56
+ /**
57
+ * Reconnection manager for handling parent discovery
58
+ */
59
+ reconnectionManager?: IReconnectionManager;
60
+ /**
61
+ * Execute a method on another node
62
+ */
63
+ use(address: oAddress, data?: {
64
+ method?: string;
65
+ params?: {
66
+ [key: string]: any;
67
+ };
68
+ id?: string;
69
+ }): Promise<any>;
70
+ /**
71
+ * Set keep-alive tag for a peer connection
72
+ */
73
+ setKeepAliveTag(address: oNodeAddress): Promise<void>;
74
+ }
75
+ //# sourceMappingURL=i-registrable-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i-registrable-node.d.ts","sourceRoot":"","sources":["../../../src/interfaces/i-registrable-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAGvE,MAAM,WAAW,oBAAoB;IACnC,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IAEtB;;OAEG;IACH,aAAa,EAAE,YAAY,CAAC;IAE5B;;OAEG;IACH,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAE5B;;OAEG;IACH,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAE5B;;OAEG;IACH,IAAI,EAAE,QAAQ,CAAC;IAEf;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,UAAU,EAAE,cAAc,EAAE,CAAC;IAE7B;;OAEG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB;;OAEG;IACH,gBAAgB,EAAE,qBAAqB,CAAC;IAExC;;OAEG;IACH,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAE3C;;OAEG;IACH,GAAG,CACD,OAAO,EAAE,QAAQ,EACjB,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;SAAE,CAAC;QAChC,EAAE,CAAC,EAAE,MAAM,CAAC;KACb,GACA,OAAO,CAAC,GAAG,CAAC,CAAC;IAEhB;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD"}
@@ -0,0 +1 @@
1
+ export {};
@@ -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;YAoBtB,wBAAwB;YAaxB,wBAAwB;YAexB,wBAAwB;IAehC,mBAAmB;YAgDX,2BAA2B;YAiB3B,iBAAiB;IAkB/B;;;OAGG;YACW,yBAAyB;IAiFvC;;OAEG;IACG,yBAAyB;IA4G/B,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,KAAK;CAGd"}
1
+ {"version":3,"file":"o-reconnection.manager.d.ts","sourceRoot":"","sources":["../../../src/managers/o-reconnection.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EASR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAI3E,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,yBAAyB,EAAE,MAAM,CAAC;IAClC,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,oBAAqB,SAAQ,OAAO;IAI7C,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IAJhB,OAAO,CAAC,YAAY,CAAS;gBAGnB,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,kBAAkB;IAMpC,OAAO,CAAC,mBAAmB;IAyBrB,mBAAmB,CAAC,KAAK,EAAE,GAAG;YAmCtB,wBAAwB;YAaxB,wBAAwB;YAexB,wBAAwB;IAehC,mBAAmB;YAgDX,2BAA2B;YAiB3B,iBAAiB;IAkB/B;;;OAGG;YACW,yBAAyB;IAyFvC;;OAEG;IACG,yBAAyB;IAoH/B,OAAO,CAAC,yBAAyB;IAajC,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,KAAK;CAGd"}
@@ -32,17 +32,32 @@ export class oReconnectionManager extends oObject {
32
32
  }
33
33
  async handleNodeConnected(event) {
34
34
  const connectedEvent = event;
35
+ const nodeAddress = connectedEvent.nodeAddress;
35
36
  // if leader is back online re-register
36
- if (connectedEvent.nodeAddress.toString() === oAddress.leader().toString()) {
37
- // the leader is back online, let's re-register & tell sub-graphs to re-register
38
- await this.node.useSelf({
39
- method: 'register_leader',
40
- params: {},
41
- });
37
+ if (nodeAddress.toString() === oAddress.leader().toString()) {
38
+ // Check if we can register with leader (not already registering or registered)
39
+ if (this.node.registrationManager.canRegisterLeader()) {
40
+ this.logger.info('Leader connected - registering with registry');
41
+ // the leader is back online, let's re-register & tell sub-graphs to re-register
42
+ await this.node.useSelf({
43
+ method: 'register_leader',
44
+ params: {},
45
+ });
46
+ }
47
+ else {
48
+ this.logger.debug(`Leader already ${this.node.registrationManager.getStatus().leader} - skipping re-registration`);
49
+ }
42
50
  }
43
- if (connectedEvent.nodeAddress.toString() === this.node.config.parent?.value) {
44
- // connect to the parent and register
45
- await this.node.registerParent();
51
+ if (nodeAddress.toString() === this.node.config.parent?.value) {
52
+ // Check if we can register with parent (not already registering or registered)
53
+ if (this.node.registrationManager.canRegisterParent()) {
54
+ this.logger.info('Parent connected - registering with parent');
55
+ // connect to the parent and register
56
+ await this.node.registerParent();
57
+ }
58
+ else {
59
+ this.logger.debug(`Parent already ${this.node.registrationManager.getStatus().parent} - skipping re-registration`);
60
+ }
46
61
  }
47
62
  }
48
63
  async handleConnectionDegraded(event) {
@@ -160,11 +175,17 @@ export class oReconnectionManager extends oObject {
160
175
  // Leader is back! Now re-register with parent and registry
161
176
  this.logger.info(`Leader is back online after ${elapsedMinutes}m, re-registering...`);
162
177
  try {
178
+ // Reset registration states before re-registering
179
+ this.node.registrationManager.resetParentState();
180
+ this.node.registrationManager.resetLeaderState();
163
181
  // Register with parent (leader)
164
182
  await this.node.registerParent();
165
- // Force re-registration with registry by resetting the flag
166
- this.node.didRegister = false;
167
- await this.node.register();
183
+ // Register with registry
184
+ await this.node.registerLeader();
185
+ // Verify registration was successful
186
+ if (!this.node.registrationManager.isFullyRegistered()) {
187
+ throw new Error('Registration incomplete after reconnection');
188
+ }
168
189
  // Success!
169
190
  this.reconnecting = false;
170
191
  this.logger.info(`Successfully reconnected to leader and re-registered after ${elapsedMinutes}m`);
@@ -228,10 +249,16 @@ export class oReconnectionManager extends oObject {
228
249
  this.node.config.parent = new oNodeAddress(parentAddress, parentTransports.map((value) => new oNodeTransport(value)));
229
250
  // Attempt to register with parent and re-register with registry
230
251
  try {
252
+ // Reset registration states before re-registering
253
+ this.node.registrationManager.resetParentState();
254
+ this.node.registrationManager.resetLeaderState();
231
255
  await this.tryDirectParentReconnection();
232
- // Force re-registration with registry by resetting the flag
233
- this.node.didRegister = false;
234
- await this.node.register();
256
+ // Register with registry
257
+ await this.node.registerLeader();
258
+ // Verify registration was successful
259
+ if (!this.node.registrationManager.isFullyRegistered()) {
260
+ throw new Error('Registration incomplete after reconnection');
261
+ }
235
262
  // Success!
236
263
  this.reconnecting = false;
237
264
  this.logger.info(`Successfully reconnected to parent and re-registered after ${elapsedMinutes}m of discovery attempts`);
@@ -0,0 +1,79 @@
1
+ import { oObject } from '@olane/o-core';
2
+ import { IRegistrableNode } from '../interfaces/i-registrable-node.js';
3
+ export type RegistrationState = 'not_registered' | 'registering' | 'registered' | 'failed';
4
+ export interface RegistrationStatus {
5
+ parent: RegistrationState;
6
+ leader: RegistrationState;
7
+ parentError?: string;
8
+ leaderError?: string;
9
+ }
10
+ /**
11
+ * Registration Manager
12
+ *
13
+ * Manages the registration state for parent and leader connections.
14
+ * Provides stateful tracking and prevents concurrent registration attempts.
15
+ *
16
+ * State Transitions:
17
+ * - not_registered → registering (when starting registration)
18
+ * - registering → registered (on success)
19
+ * - registering → failed (on error)
20
+ * - failed → registering (on retry)
21
+ * - registered → not_registered (on explicit reset)
22
+ */
23
+ export declare class oRegistrationManager extends oObject {
24
+ private node;
25
+ private parentState;
26
+ private leaderState;
27
+ private parentError?;
28
+ private leaderError?;
29
+ constructor(node: IRegistrableNode);
30
+ /**
31
+ * Check if parent registration can be attempted
32
+ * Returns false if already registering or registered
33
+ */
34
+ canRegisterParent(): boolean;
35
+ /**
36
+ * Check if leader registration can be attempted
37
+ * Returns false if already registering or registered
38
+ */
39
+ canRegisterLeader(): boolean;
40
+ /**
41
+ * Check if parent is currently registered
42
+ */
43
+ isParentRegistered(): boolean;
44
+ /**
45
+ * Check if leader is currently registered
46
+ */
47
+ isLeaderRegistered(): boolean;
48
+ /**
49
+ * Check if both parent and leader are registered
50
+ */
51
+ isFullyRegistered(): boolean;
52
+ /**
53
+ * Reset parent registration state to not_registered
54
+ */
55
+ resetParentState(): void;
56
+ /**
57
+ * Reset leader registration state to not_registered
58
+ */
59
+ resetLeaderState(): void;
60
+ /**
61
+ * Reset all registration states
62
+ */
63
+ resetAll(): void;
64
+ /**
65
+ * Get current registration status
66
+ */
67
+ getStatus(): RegistrationStatus;
68
+ /**
69
+ * Register with parent node
70
+ * Manages state transitions and prevents concurrent attempts
71
+ */
72
+ registerParent(): Promise<void>;
73
+ /**
74
+ * Register with leader's global registry
75
+ * Manages state transitions and prevents concurrent attempts
76
+ */
77
+ registerLeader(): Promise<void>;
78
+ }
79
+ //# sourceMappingURL=o-registration.manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"o-registration.manager.d.ts","sourceRoot":"","sources":["../../../src/managers/o-registration.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAIR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAGvE,MAAM,MAAM,iBAAiB,GACzB,gBAAgB,GAChB,aAAa,GACb,YAAY,GACZ,QAAQ,CAAC;AAEb,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAqB,SAAQ,OAAO;IAMnC,OAAO,CAAC,IAAI;IALxB,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,WAAW,CAAC,CAAQ;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAQ;gBAER,IAAI,EAAE,gBAAgB;IAI1C;;;OAGG;IACH,iBAAiB,IAAI,OAAO;IAM5B;;;OAGG;IACH,iBAAiB,IAAI,OAAO;IAM5B;;OAEG;IACH,kBAAkB,IAAI,OAAO;IAI7B;;OAEG;IACH,kBAAkB,IAAI,OAAO;IAI7B;;OAEG;IACH,iBAAiB,IAAI,OAAO;IAe5B;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAMxB;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAMxB;;OAEG;IACH,QAAQ,IAAI,IAAI;IAKhB;;OAEG;IACH,SAAS,IAAI,kBAAkB;IAS/B;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAsFrC;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAwDtC"}
@@ -0,0 +1,226 @@
1
+ import { oObject, oAddress, NodeType, } from '@olane/o-core';
2
+ import { oNodeAddress } from '../router/o-node.address.js';
3
+ /**
4
+ * Registration Manager
5
+ *
6
+ * Manages the registration state for parent and leader connections.
7
+ * Provides stateful tracking and prevents concurrent registration attempts.
8
+ *
9
+ * State Transitions:
10
+ * - not_registered → registering (when starting registration)
11
+ * - registering → registered (on success)
12
+ * - registering → failed (on error)
13
+ * - failed → registering (on retry)
14
+ * - registered → not_registered (on explicit reset)
15
+ */
16
+ export class oRegistrationManager extends oObject {
17
+ constructor(node) {
18
+ super();
19
+ this.node = node;
20
+ this.parentState = 'not_registered';
21
+ this.leaderState = 'not_registered';
22
+ }
23
+ /**
24
+ * Check if parent registration can be attempted
25
+ * Returns false if already registering or registered
26
+ */
27
+ canRegisterParent() {
28
+ return (this.parentState !== 'registering' && this.parentState !== 'registered');
29
+ }
30
+ /**
31
+ * Check if leader registration can be attempted
32
+ * Returns false if already registering or registered
33
+ */
34
+ canRegisterLeader() {
35
+ return (this.leaderState !== 'registering' && this.leaderState !== 'registered');
36
+ }
37
+ /**
38
+ * Check if parent is currently registered
39
+ */
40
+ isParentRegistered() {
41
+ return this.parentState === 'registered';
42
+ }
43
+ /**
44
+ * Check if leader is currently registered
45
+ */
46
+ isLeaderRegistered() {
47
+ return this.leaderState === 'registered';
48
+ }
49
+ /**
50
+ * Check if both parent and leader are registered
51
+ */
52
+ isFullyRegistered() {
53
+ // For leader nodes, only check leader state
54
+ if (this.node.type === NodeType.LEADER) {
55
+ return true;
56
+ }
57
+ // For nodes without parent, only check leader
58
+ if (!this.node.config.parent) {
59
+ return this.isLeaderRegistered();
60
+ }
61
+ // For regular nodes, check both
62
+ return this.isParentRegistered() && this.isLeaderRegistered();
63
+ }
64
+ /**
65
+ * Reset parent registration state to not_registered
66
+ */
67
+ resetParentState() {
68
+ this.logger.debug('Resetting parent registration state');
69
+ this.parentState = 'not_registered';
70
+ this.parentError = undefined;
71
+ }
72
+ /**
73
+ * Reset leader registration state to not_registered
74
+ */
75
+ resetLeaderState() {
76
+ this.logger.debug('Resetting leader registration state');
77
+ this.leaderState = 'not_registered';
78
+ this.leaderError = undefined;
79
+ }
80
+ /**
81
+ * Reset all registration states
82
+ */
83
+ resetAll() {
84
+ this.resetParentState();
85
+ this.resetLeaderState();
86
+ }
87
+ /**
88
+ * Get current registration status
89
+ */
90
+ getStatus() {
91
+ return {
92
+ parent: this.parentState,
93
+ leader: this.leaderState,
94
+ parentError: this.parentError?.message,
95
+ leaderError: this.leaderError?.message,
96
+ };
97
+ }
98
+ /**
99
+ * Register with parent node
100
+ * Manages state transitions and prevents concurrent attempts
101
+ */
102
+ async registerParent() {
103
+ if (this.node.type === NodeType.LEADER) {
104
+ this.logger.debug('Skipping parent registration, node is leader');
105
+ return;
106
+ }
107
+ if (!this.node.parent) {
108
+ this.logger.warn('No parent configured, skipping registration');
109
+ return;
110
+ }
111
+ // Check if we can register (not already registering or registered)
112
+ if (!this.canRegisterParent()) {
113
+ this.logger.debug(`Cannot register parent, current state: ${this.parentState}`);
114
+ return;
115
+ }
116
+ this.logger.info('Registering with parent...', {
117
+ parent: this.node.parent.toString(),
118
+ currentState: this.parentState,
119
+ });
120
+ // Transition to registering state
121
+ this.parentState = 'registering';
122
+ this.parentError = undefined;
123
+ try {
124
+ // Check if parent has transports
125
+ if (!this.node.parent?.libp2pTransports?.length) {
126
+ this.logger.debug('Parent has no transports, waiting for reconnection & leader ack');
127
+ if (this.node.parent?.toString() === oAddress.leader().toString()) {
128
+ this.node.parent.setTransports(this.node.leader?.libp2pTransports || []);
129
+ }
130
+ else {
131
+ this.logger.debug('Waiting for parent and reconnecting...');
132
+ // Reset state since we're delegating to reconnection manager
133
+ this.parentState = 'not_registered';
134
+ if (this.node.reconnectionManager) {
135
+ await this.node.reconnectionManager.waitForParentAndReconnect();
136
+ }
137
+ else {
138
+ throw new Error('Parent has no transports and no reconnection manager available');
139
+ }
140
+ // If we get here, reconnection was successful and registration is complete
141
+ return;
142
+ }
143
+ }
144
+ // Register with parent via child_register call
145
+ await this.node.use(new oNodeAddress(this.node.config.parent.value), {
146
+ method: 'child_register',
147
+ params: {
148
+ address: this.node.address.toString(),
149
+ transports: this.node.transports.map((t) => t.toString()),
150
+ peerId: this.node.peerId.toString(),
151
+ _token: this.node.config.joinToken,
152
+ },
153
+ });
154
+ // Set keep-alive tag for parent connection
155
+ await this.node.setKeepAliveTag(this.node.parent);
156
+ // Add parent to hierarchy manager
157
+ this.node.hierarchyManager.addParent(this.node.parent);
158
+ // Success - transition to registered state
159
+ this.parentState = 'registered';
160
+ this.logger.info('Successfully registered with parent', {
161
+ parent: this.node.parent.toString(),
162
+ });
163
+ }
164
+ catch (error) {
165
+ // Failure - transition to failed state
166
+ this.parentState = 'failed';
167
+ this.parentError = error instanceof Error ? error : new Error(String(error));
168
+ this.logger.error('Failed to register with parent:', {
169
+ parent: this.node.parent?.toString(),
170
+ error: this.parentError.message,
171
+ });
172
+ throw error;
173
+ }
174
+ }
175
+ /**
176
+ * Register with leader's global registry
177
+ * Manages state transitions and prevents concurrent attempts
178
+ */
179
+ async registerLeader() {
180
+ if (!this.node.leader) {
181
+ this.logger.warn('No leader defined, skipping registration');
182
+ return;
183
+ }
184
+ // Check if we can register (not already registering or registered)
185
+ if (!this.canRegisterLeader()) {
186
+ this.logger.debug(`Cannot register leader, current state: ${this.leaderState}`);
187
+ return;
188
+ }
189
+ this.logger.info('Registering with leader registry...', {
190
+ leader: this.node.leader.toString(),
191
+ currentState: this.leaderState,
192
+ });
193
+ // Transition to registering state
194
+ this.leaderState = 'registering';
195
+ this.leaderError = undefined;
196
+ try {
197
+ const address = oAddress.registry();
198
+ const params = {
199
+ method: 'commit',
200
+ params: {
201
+ peerId: this.node.peerId.toString(),
202
+ address: this.node.address.toString(),
203
+ protocols: this.node.protocols,
204
+ transports: this.node.transports,
205
+ staticAddress: this.node.staticAddress.toString(),
206
+ },
207
+ };
208
+ await this.node.use(address, params);
209
+ // Set keep-alive tag for leader connection
210
+ await this.node.setKeepAliveTag(this.node.leader);
211
+ // Success - transition to registered state
212
+ this.leaderState = 'registered';
213
+ this.logger.info('Successfully registered with leader registry');
214
+ }
215
+ catch (error) {
216
+ // Failure - transition to failed state
217
+ this.leaderState = 'failed';
218
+ this.leaderError = error instanceof Error ? error : new Error(String(error));
219
+ this.logger.error('Failed to register with leader:', {
220
+ leader: this.node.leader?.toString(),
221
+ error: this.leaderError.message,
222
+ });
223
+ throw error;
224
+ }
225
+ }
226
+ }
@@ -11,6 +11,7 @@ import { oToolBase } from '@olane/o-tool';
11
11
  import { oConnectionHeartbeatManager } from './managers/o-connection-heartbeat.manager.js';
12
12
  import { oNodeConnectionConfig } from './connection/index.js';
13
13
  import { oReconnectionManager } from './managers/o-reconnection.manager.js';
14
+ import { oRegistrationManager } from './managers/o-registration.manager.js';
14
15
  import { LockManager } from './utils/lock-manager.js';
15
16
  export declare class oNode extends oToolBase {
16
17
  peerId: PeerId;
@@ -21,7 +22,7 @@ export declare class oNode extends oToolBase {
21
22
  hierarchyManager: oNodeHierarchyManager;
22
23
  connectionHeartbeatManager?: oConnectionHeartbeatManager;
23
24
  protected reconnectionManager?: oReconnectionManager;
24
- protected didRegister: boolean;
25
+ registrationManager: oRegistrationManager;
25
26
  protected hooksStartFinished: any[];
26
27
  protected hooksInitFinished: any[];
27
28
  protected lockManager: LockManager;
@@ -35,6 +36,7 @@ export declare class oNode extends oToolBase {
35
36
  get staticAddress(): oNodeAddress;
36
37
  get parentTransports(): oNodeTransport[];
37
38
  get transports(): oNodeTransport[];
39
+ get protocols(): string[];
38
40
  unregister(): Promise<void>;
39
41
  setKeepAliveTag(address: oNodeAddress): Promise<void>;
40
42
  registerParent(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"o-node.d.ts","sourceRoot":"","sources":["../../src/o-node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"o-node.d.ts","sourceRoot":"","sources":["../../src/o-node.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { v4 as uuidv4 } from 'uuid';
3
3
  import { oNodeRouter } from './router/o-node.router.js';
4
4
  import { oNodeHierarchyManager } from './o-node.hierarchy-manager.js';
5
5
  import { oNodeTransport } from './router/o-node.transport.js';
6
- import { CoreUtils, NodeState, NodeType, oAddress, RestrictedAddresses, } from '@olane/o-core';
6
+ import { CoreUtils, NodeState, NodeType, RestrictedAddresses, } from '@olane/o-core';
7
7
  import { oNodeAddress } from './router/o-node.address.js';
8
8
  import { oNodeConnectionManager } from './connection/o-node-connection.manager.js';
9
9
  import { oNodeResolver } from './router/resolvers/o-node.resolver.js';
@@ -11,11 +11,11 @@ import { oMethodResolver, oToolBase } from '@olane/o-tool';
11
11
  import { oLeaderResolverFallback } from './router/index.js';
12
12
  import { oNodeNotificationManager } from './o-node.notification-manager.js';
13
13
  import { oReconnectionManager } from './managers/o-reconnection.manager.js';
14
+ import { oRegistrationManager } from './managers/o-registration.manager.js';
14
15
  import { LockManager } from './utils/lock-manager.js';
15
16
  export class oNode extends oToolBase {
16
17
  constructor(config) {
17
18
  super(config);
18
- this.didRegister = false;
19
19
  this.hooksStartFinished = [];
20
20
  this.hooksInitFinished = [];
21
21
  this.lockManager = new LockManager();
@@ -58,6 +58,9 @@ export class oNode extends oToolBase {
58
58
  .getMultiaddrs()
59
59
  .map((multiaddr) => new oNodeTransport(multiaddr.toString()));
60
60
  }
61
+ get protocols() {
62
+ return this.p2pNode ? this.p2pNode.getProtocols() : [];
63
+ }
61
64
  async unregister() {
62
65
  this.logger.debug('Unregistering node...');
63
66
  if (this.type === NodeType.LEADER) {
@@ -134,72 +137,20 @@ export class oNode extends oToolBase {
134
137
  }
135
138
  }
136
139
  async registerParent() {
137
- if (this.type === NodeType.LEADER) {
138
- this.logger.debug('Skipping parent registration, node is leader');
139
- return;
140
- }
141
- if (!this.parent) {
142
- this.logger.warn('no parent, skipping registration');
143
- return;
144
- }
145
- if (!this.parent?.libp2pTransports?.length) {
146
- this.logger.debug('Parent has no transports, waiting for reconnection & leader ack');
147
- if (this.parent?.toString() === oAddress.leader().toString()) {
148
- this.parent.setTransports(this.leader?.libp2pTransports || []);
149
- }
150
- else {
151
- this.logger.debug('Waiting for parent and reconnecting... hello');
152
- await this.reconnectionManager?.waitForParentAndReconnect();
153
- }
154
- }
155
- // if no parent transports, register with the parent to get them
156
- // TODO: should we remove the transports check to make this more consistent?
157
- if (this.config.parent) {
158
- this.logger.debug('Registering node with parent...', this.config.parent?.toString());
159
- // avoid transports to ensure we do not try direct connection, we need to route via the leader for proper access controls
160
- await this.use(new oNodeAddress(this.config.parent.value), {
161
- method: 'child_register',
162
- params: {
163
- address: this.address.toString(),
164
- transports: this.transports.map((t) => t.toString()),
165
- peerId: this.peerId.toString(),
166
- _token: this.config.joinToken,
167
- },
168
- });
169
- this.setKeepAliveTag(this.parent);
170
- this.hierarchyManager.addParent(this.parent);
171
- }
140
+ return await this.registrationManager.registerParent();
172
141
  }
173
142
  async registerLeader() {
174
- this.logger.info('Register leader called...');
175
- if (!this.leader) {
176
- this.logger.warn('No leader defined, skipping registration');
177
- return;
178
- }
179
- const address = oAddress.registry();
180
- const params = {
181
- method: 'commit',
182
- params: {
183
- peerId: this.peerId.toString(),
184
- address: this.address.toString(),
185
- protocols: this.p2pNode.getProtocols(),
186
- transports: this.transports,
187
- staticAddress: this.staticAddress.toString(),
188
- },
189
- };
190
- await this.use(address, params);
191
- this.setKeepAliveTag(this.leader);
143
+ return await this.registrationManager.registerLeader();
192
144
  }
193
145
  async register() {
194
146
  if (this.type === NodeType.LEADER) {
195
147
  this.logger.debug('Skipping registration, node is leader');
196
148
  return;
197
149
  }
198
- if (this.didRegister) {
150
+ if (this.registrationManager.isFullyRegistered()) {
199
151
  this.logger.debug('Node already registered, skipping registration');
200
152
  return;
201
153
  }
202
- this.didRegister = true;
203
154
  this.logger.debug('Registering node...');
204
155
  await this.registerParent();
205
156
  // register with the leader global registry
@@ -470,6 +421,7 @@ export class oNode extends oToolBase {
470
421
  parentDiscoveryIntervalMs: 5000,
471
422
  parentDiscoveryMaxDelayMs: 20000,
472
423
  });
424
+ this.registrationManager = new oRegistrationManager(this);
473
425
  // need to wait until our libpp2 node is initialized before calling super.initialize
474
426
  await super.initialize();
475
427
  this.logger.debug('Node initialized!', this.transports.map((t) => t.toString()));
@@ -522,8 +474,10 @@ export class oNode extends oToolBase {
522
474
  * Called at the end of teardown()
523
475
  */
524
476
  resetState() {
525
- // Reset registration flag
526
- this.didRegister = false;
477
+ // Reset registration states
478
+ if (this.registrationManager) {
479
+ this.registrationManager.resetAll();
480
+ }
527
481
  // Clear all locks
528
482
  this.lockManager.clearAll();
529
483
  // Clear peer references
@@ -533,6 +487,7 @@ export class oNode extends oToolBase {
533
487
  this.connectionManager = undefined;
534
488
  this.connectionHeartbeatManager = undefined;
535
489
  this.reconnectionManager = undefined;
490
+ this.registrationManager = undefined;
536
491
  // Reset address to staticAddress with no transports
537
492
  this.address = new oNodeAddress(this.staticAddress.value, []);
538
493
  // Reset hierarchy manager
@@ -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;;AAMrD;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAAkB;IAC/C,OAAO,CAAC,aAAa,CAAiB;IAEhC,mBAAmB,CAAC,OAAO,EAAE,QAAQ;IAsBrC,cAAc,CAAC,OAAO,EAAE,QAAQ;IAoBhC,mBAAmB;IAWnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,IAAI,CAAC;IAIV,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,IAAI,CAAC;IAyCV,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAQ9B,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAiC5D"}
1
+ {"version":3,"file":"o-node.tool.d.ts","sourceRoot":"","sources":["../../src/o-node.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAoB,MAAM,eAAe,CAAC;AAErE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;;AAMrD;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cAAkB;IAC/C,OAAO,CAAC,aAAa,CAAiB;IAEhC,mBAAmB,CAAC,OAAO,EAAE,QAAQ;IAuBrC,cAAc,CAAC,OAAO,EAAE,QAAQ;IAsBhC,mBAAmB;IAWnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,IAAI,CAAC;IAIV,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU,EACtB,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,IAAI,CAAC;IAyCV,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;IAQ9B,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAiC5D"}
@@ -25,6 +25,7 @@ export class oNodeTool extends oTool(oServerNode) {
25
25
  await this.p2pNode.handle(reuseProtocol, this.handleStreamReuse.bind(this), {
26
26
  maxInboundStreams: 10000,
27
27
  maxOutboundStreams: maxOutboundsStreams,
28
+ runOnLimitedConnection: this.config.runOnLimitedConnection,
28
29
  });
29
30
  this.logger.debug('Handled protocol reuse: ' + reuseProtocol);
30
31
  }
@@ -40,10 +41,12 @@ export class oNodeTool extends oTool(oServerNode) {
40
41
  this.logger.debug('Handling protocol: ' + address.protocol, {
41
42
  maxInboundStreams: 10000,
42
43
  maxOutboundStreams: maxOutboundsStreams,
44
+ runOnLimitedConnection: this.config.runOnLimitedConnection,
43
45
  });
44
46
  await this.p2pNode.handle(address.protocol, this.handleStream.bind(this), {
45
47
  maxInboundStreams: 10000,
46
48
  maxOutboundStreams: maxOutboundsStreams,
49
+ runOnLimitedConnection: this.config.runOnLimitedConnection,
47
50
  });
48
51
  await this.handleProtocolReuse(address);
49
52
  }
@@ -66,20 +69,20 @@ export class oNodeTool extends oTool(oServerNode) {
66
69
  async handleStream(stream, connection, reuse) {
67
70
  if (reuse) {
68
71
  this.logger.debug('Handle stream with reuse = true');
72
+ // record inbound connection to manager
73
+ const remoteAddress = await ConnectionUtils.addressFromConnection({
74
+ currentNode: this,
75
+ connection: connection,
76
+ });
77
+ this.connectionManager.answer({
78
+ nextHopAddress: remoteAddress,
79
+ address: remoteAddress,
80
+ callerAddress: this.address,
81
+ p2pConnection: connection,
82
+ reuse,
83
+ // requestHandler: this.execute.bind(this), TODO: do we need this?
84
+ });
69
85
  }
70
- // record inbound connection to manager
71
- const remoteAddress = await ConnectionUtils.addressFromConnection({
72
- currentNode: this,
73
- connection: connection,
74
- });
75
- this.connectionManager.answer({
76
- nextHopAddress: remoteAddress,
77
- address: remoteAddress,
78
- callerAddress: this.address,
79
- p2pConnection: connection,
80
- reuse,
81
- // requestHandler: this.execute.bind(this), TODO: do we need this?
82
- });
83
86
  // Use StreamHandler for consistent stream handling
84
87
  // This follows libp2p v3 best practices for length-prefixed streaming
85
88
  await this.streamHandler.handleIncomingStream(stream, connection, async (request, stream) => {
@@ -1 +1 @@
1
- {"version":3,"file":"connection.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/connection.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAuB,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7D,qBAAa,eAAgB,SAAQ,OAAO;IAC1C;;;OAGG;mBACkB,kBAAkB;WAmCnB,qBAAqB,CAAC,OAAO,EAAE;QACjD,WAAW,EAAE,GAAG,CAAC;QACjB,UAAU,EAAE,UAAU,CAAC;KACxB;CA8DF"}
1
+ {"version":3,"file":"connection.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/connection.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAuB,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7D,qBAAa,eAAgB,SAAQ,OAAO;IAC1C;;;OAGG;mBACkB,kBAAkB;WAgCnB,qBAAqB,CAAC,OAAO,EAAE;QACjD,WAAW,EAAE,GAAG,CAAC;QACjB,UAAU,EAAE,UAAU,CAAC;KACxB;CA0DF"}
@@ -17,7 +17,6 @@ export class ConnectionUtils extends oObject {
17
17
  });
18
18
  // Check if peer exists and has sufficient protocol information
19
19
  if (remotePeer && remotePeer.protocols.length > MIN_PROTOCOLS) {
20
- console.log(`Peer found in store after ${attempt} attempts (${attempt * RETRY_DELAY_MS}ms)`);
21
20
  return remotePeer;
22
21
  }
23
22
  // Wait before next retry
@@ -41,7 +40,6 @@ export class ConnectionUtils extends oObject {
41
40
  if (!originAddress) {
42
41
  throw new Error('Origin address is not configured');
43
42
  }
44
- console.log('Deriving address from connection protocols:', remotePeer.protocols);
45
43
  const oProtocol = remotePeer.protocols.find((p) => p.startsWith('/o/') &&
46
44
  p.includes(currentNode?.address?.protocol) === false);
47
45
  if (!oProtocol) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-node",
3
- "version": "0.7.48",
3
+ "version": "0.7.50",
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.48",
43
+ "@olane/o-test": "0.7.50",
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.48",
64
- "@olane/o-core": "0.7.48",
65
- "@olane/o-protocol": "0.7.48",
66
- "@olane/o-tool": "0.7.48",
63
+ "@olane/o-config": "0.7.50",
64
+ "@olane/o-core": "0.7.50",
65
+ "@olane/o-protocol": "0.7.50",
66
+ "@olane/o-tool": "0.7.50",
67
67
  "debug": "^4.4.1",
68
68
  "dotenv": "^16.5.0",
69
69
  "json5": "^2.2.3"
70
70
  },
71
- "gitHead": "1810818bb9682b586e9db2febcc2a89da5057449"
71
+ "gitHead": "55f5464185ef16a164fa23dc46c0c08b317419a0"
72
72
  }