@olane/o-node 0.7.12-alpha.66 → 0.7.12-alpha.68

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,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;AAGpD,qBAAa,eAAgB,SAAQ,WAAW;IAIlC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB;IAHrD,aAAa,EAAE,UAAU,CAAC;IACjC,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;gBAER,MAAM,EAAE,qBAAqB;IAO5D,wBAAwB;IAYxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IAmBlB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAkBpC,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IAwC/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,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;AAGpD,qBAAa,eAAgB,SAAQ,WAAW;IAIlC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB;IAHrD,aAAa,EAAE,UAAU,CAAC;IACjC,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;gBAER,MAAM,EAAE,qBAAqB;IAO5D,wBAAwB;IAYxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IAmBlB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAkBpC,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IA0C/C,YAAY,CAAC,MAAM,EAAE,MAAM;IAQ3B,KAAK,CAAC,KAAK,EAAE,KAAK;IAMlB,KAAK;CAKZ"}
@@ -56,7 +56,8 @@ export class oNodeConnection extends oConnection {
56
56
  await this.streamHandler.send(stream, data, streamConfig);
57
57
  // Handle response using StreamHandler
58
58
  // Pass request handler if configured to enable bidirectional stream processing
59
- const response = await this.streamHandler.handleOutgoingStream(stream, this.emitter, streamConfig, this.config.requestHandler);
59
+ // Pass request ID to enable proper response correlation on shared streams
60
+ const response = await this.streamHandler.handleOutgoingStream(stream, this.emitter, streamConfig, this.config.requestHandler, request.id);
60
61
  // Handle cleanup of the stream
61
62
  await this.postTransmit(stream);
62
63
  return response;
@@ -81,9 +81,10 @@ export declare class StreamHandler {
81
81
  * @param emitter - Event emitter for chunk events
82
82
  * @param config - Configuration including abort signal
83
83
  * @param requestHandler - Optional handler for processing router requests received on this stream
84
+ * @param requestId - Optional request ID to filter responses (for stream reuse scenarios)
84
85
  * @returns Promise that resolves with the final response
85
86
  */
86
- handleOutgoingStream(stream: Stream, emitter: EventEmitter, config?: StreamHandlerConfig, requestHandler?: (request: oRequest, stream: Stream) => Promise<RunResult>): Promise<oResponse>;
87
+ handleOutgoingStream(stream: Stream, emitter: EventEmitter, config?: StreamHandlerConfig, requestHandler?: (request: oRequest, stream: Stream) => Promise<RunResult>, requestId?: string | number): Promise<oResponse>;
87
88
  /**
88
89
  * Forwards a request to the next hop and relays response chunks back
89
90
  * This implements the middleware/proxy pattern for intermediate nodes
@@ -1 +1 @@
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;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGtE;;;;;;;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;;OAEG;IACG,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAI7C;;;;;;OAMG;IACG,iBAAiB,CACrB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,MAAM,CAAC;IA0DlB;;;;;;OAMG;IACG,IAAI,CACR,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,IAAI,CAAC;IAiBhB;;;;;OAKG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB5E;;;;;;;;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;IAuChB;;;;;;OAMG;YACW,oBAAoB;IA4BlC;;;;;;;;;;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,GACzE,OAAO,CAAC,SAAS,CAAC;IAsGrB;;;;;;;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"}
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;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGtE;;;;;;;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;;OAEG;IACG,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAI7C;;;;;;OAMG;IACG,iBAAiB,CACrB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,MAAM,CAAC;IAsClB;;;;;;OAMG;IACG,IAAI,CACR,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,MAAM,GAAE,mBAAwB,GAC/B,OAAO,CAAC,IAAI,CAAC;IAiBhB;;;;;OAKG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB5E;;;;;;;;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;IAuChB;;;;;;OAMG;YACW,oBAAoB;IA4BlC;;;;;;;;;;;OAWG;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;IA+GrB;;;;;;;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"}
@@ -46,13 +46,6 @@ export class StreamHandler {
46
46
  this.logger.debug('Reuse policy:', reusePolicy);
47
47
  // Check for existing stream if reuse is enabled
48
48
  if (reusePolicy === 'reuse') {
49
- this.logger.debug('Reusing existing stream if we can find one. Stream insights:', JSON.stringify({
50
- streamCount: connection.streams.length,
51
- protocol: protocol,
52
- }));
53
- connection.streams.forEach((stream) => {
54
- this.logger.debug('Stream re-use option:', stream.protocol, stream.status, stream.direction, stream.remoteWriteStatus, stream.writeStatus, stream.remoteReadStatus, stream.readStatus);
55
- });
56
49
  const existingStream = connection.streams.find((stream) => stream.status === 'open' &&
57
50
  stream.protocol === protocol &&
58
51
  stream.writeStatus === 'writable' &&
@@ -190,9 +183,10 @@ export class StreamHandler {
190
183
  * @param emitter - Event emitter for chunk events
191
184
  * @param config - Configuration including abort signal
192
185
  * @param requestHandler - Optional handler for processing router requests received on this stream
186
+ * @param requestId - Optional request ID to filter responses (for stream reuse scenarios)
193
187
  * @returns Promise that resolves with the final response
194
188
  */
195
- async handleOutgoingStream(stream, emitter, config = {}, requestHandler) {
189
+ async handleOutgoingStream(stream, emitter, config = {}, requestHandler, requestId) {
196
190
  return new Promise((resolve, reject) => {
197
191
  let lastResponse;
198
192
  const messageHandler = async (event) => {
@@ -211,9 +205,15 @@ export class StreamHandler {
211
205
  }
212
206
  if (this.isResponse(message)) {
213
207
  const response = await CoreUtils.processStreamResponse(event);
208
+ // If requestId is provided, filter responses to only process those matching our request
209
+ // This prevents premature termination when multiple requests share the same stream
210
+ if (requestId !== undefined && response.id !== requestId) {
211
+ this.logger.debug(`Ignoring response for different request (expected: ${requestId}, received: ${response.id})`);
212
+ return;
213
+ }
214
214
  // Emit chunk for streaming responses
215
215
  emitter.emit('chunk', response);
216
- // Check if this is the last chunk
216
+ // Check if this is the last chunk for THIS request
217
217
  if (response.result._last || !response.result._isStreaming) {
218
218
  lastResponse = response;
219
219
  cleanup();
@@ -4,31 +4,17 @@ export interface oNodeConfig extends oCoreConfig {
4
4
  leader: oNodeAddress | null;
5
5
  parent: oNodeAddress | null;
6
6
  /**
7
- * Connection heartbeat configuration (libp2p-native pings)
8
- * Detects dead connections via periodic pings using libp2p's ping service
7
+ * Connection health monitoring configuration
8
+ * Detects dead connections by checking libp2p connection state
9
9
  */
10
10
  connectionHeartbeat?: {
11
11
  enabled?: boolean;
12
12
  intervalMs?: number;
13
- timeoutMs?: number;
14
13
  failureThreshold?: number;
15
14
  checkChildren?: boolean;
16
15
  checkParent?: boolean;
17
16
  checkLeader?: boolean;
18
17
  };
19
- /**
20
- * Automatic reconnection configuration
21
- * Handles parent connection failures and attempts to reconnect
22
- */
23
- reconnection?: {
24
- enabled?: boolean;
25
- maxAttempts?: number;
26
- baseDelayMs?: number;
27
- maxDelayMs?: number;
28
- useLeaderFallback?: boolean;
29
- parentDiscoveryIntervalMs?: number;
30
- parentDiscoveryMaxDelayMs?: number;
31
- };
32
18
  /**
33
19
  * Connection timeout configuration
34
20
  * Controls timeouts for stream read and drain operations in connections
@@ -1 +1 @@
1
- {"version":3,"file":"o-node.config.d.ts","sourceRoot":"","sources":["../../../src/interfaces/o-node.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAE5B;;;OAGG;IACH,mBAAmB,CAAC,EAAE;QACpB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IAEF;;;OAGG;IACH,YAAY,CAAC,EAAE;QACb,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,yBAAyB,CAAC,EAAE,MAAM,CAAC;KACpC,CAAC;IAEF;;;OAGG;IACH,kBAAkB,CAAC,EAAE;QACnB;;;WAGG;QACH,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB;;;WAGG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IAEF,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC"}
1
+ {"version":3,"file":"o-node.config.d.ts","sourceRoot":"","sources":["../../../src/interfaces/o-node.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAE5B;;;OAGG;IACH,mBAAmB,CAAC,EAAE;QACpB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,CAAC;IAEF;;;OAGG;IACH,kBAAkB,CAAC,EAAE;QACnB;;;WAGG;QACH,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB;;;WAGG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IAEF,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC"}
@@ -4,7 +4,6 @@ import { IHeartbeatableNode } from '../interfaces/i-heartbeatable-node.js';
4
4
  export interface HeartbeatConfig {
5
5
  enabled: boolean;
6
6
  intervalMs: number;
7
- timeoutMs: number;
8
7
  failureThreshold: number;
9
8
  checkChildren: boolean;
10
9
  checkParent: boolean;
@@ -19,14 +18,15 @@ export interface ConnectionHealth {
19
18
  status: 'healthy' | 'degraded' | 'dead';
20
19
  }
21
20
  /**
22
- * Connection Heartbeat Manager
21
+ * Connection Health Monitor
23
22
  *
24
- * Uses libp2p's native ping service to detect dead connections early.
25
- * Continuously pings parent and children to ensure they're alive.
23
+ * Monitors connection health by checking libp2p's connection state directly.
24
+ * Continuously checks parent and children connections to detect failures early.
26
25
  *
27
26
  * How it works:
28
- * - Every `intervalMs`, pings all tracked connections
29
- * - If ping fails, increments failure counter
27
+ * - Every `intervalMs`, checks connection status of all tracked connections
28
+ * - Uses libp2p's connection state (no network overhead from pings)
29
+ * - If connection is not open, increments failure counter
30
30
  * - After `failureThreshold` failures, marks connection as dead
31
31
  * - Emits events for degraded/recovered/dead connections
32
32
  * - Automatically removes dead children from hierarchy
@@ -41,9 +41,13 @@ export declare class oConnectionHeartbeatManager extends oObject {
41
41
  constructor(node: IHeartbeatableNode, config: HeartbeatConfig);
42
42
  start(): Promise<void>;
43
43
  stop(): Promise<void>;
44
- private performHeartbeatCycle;
45
- private doPing;
46
- private pingTarget;
44
+ private performHealthCheckCycle;
45
+ /**
46
+ * Check if a connection to the given address is open by examining libp2p's connection state
47
+ * @returns true if an open connection exists, false otherwise
48
+ */
49
+ private checkConnectionStatus;
50
+ private checkTarget;
47
51
  private handleConnectionDead;
48
52
  private emitConnectionDegradedEvent;
49
53
  private emitConnectionRecoveredEvent;
@@ -1 +1 @@
1
- {"version":3,"file":"o-connection-heartbeat.manager.d.ts","sourceRoot":"","sources":["../../../src/managers/o-connection-heartbeat.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAOR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;CACzC;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,2BAA4B,SAAQ,OAAO;IAMpD,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,iBAAiB,CAAC,CAAiB;IAC3C,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,SAAS,CAAS;gBAGhB,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,eAAe;IAK3B,KAAK;IAqBL,IAAI;YAQI,qBAAqB;IAgDnC,OAAO,CAAC,MAAM;YAcA,UAAU;IAuFxB,OAAO,CAAC,oBAAoB;IAyD5B,OAAO,CAAC,2BAA2B;IAmBnC,OAAO,CAAC,4BAA4B;IAiBpC;;OAEG;IACH,eAAe,IAAI,gBAAgB,EAAE;IAIrC;;OAEG;IACH,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,GAAG,SAAS;IAIxE;;OAEG;IACH,SAAS,IAAI,eAAe;CAG7B"}
1
+ {"version":3,"file":"o-connection-heartbeat.manager.d.ts","sourceRoot":"","sources":["../../../src/managers/o-connection-heartbeat.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAOR,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;CACzC;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,2BAA4B,SAAQ,OAAO;IAMpD,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,iBAAiB,CAAC,CAAiB;IAC3C,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,SAAS,CAAS;gBAGhB,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,eAAe;IAK3B,KAAK;IAqBL,IAAI;YAQI,uBAAuB;IAgDrC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;YA8Bf,WAAW;IAoEzB,OAAO,CAAC,oBAAoB;IAyD5B,OAAO,CAAC,2BAA2B;IAmBnC,OAAO,CAAC,4BAA4B;IAiBpC;;OAEG;IACH,eAAe,IAAI,gBAAgB,EAAE;IAIrC;;OAEG;IACH,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,gBAAgB,GAAG,SAAS;IAIxE;;OAEG;IACH,SAAS,IAAI,eAAe;CAG7B"}
@@ -1,13 +1,14 @@
1
1
  import { oObject, ChildLeftEvent, ParentDisconnectedEvent, LeaderDisconnectedEvent, ConnectionDegradedEvent, ConnectionRecoveredEvent, oAddress, } from '@olane/o-core';
2
2
  /**
3
- * Connection Heartbeat Manager
3
+ * Connection Health Monitor
4
4
  *
5
- * Uses libp2p's native ping service to detect dead connections early.
6
- * Continuously pings parent and children to ensure they're alive.
5
+ * Monitors connection health by checking libp2p's connection state directly.
6
+ * Continuously checks parent and children connections to detect failures early.
7
7
  *
8
8
  * How it works:
9
- * - Every `intervalMs`, pings all tracked connections
10
- * - If ping fails, increments failure counter
9
+ * - Every `intervalMs`, checks connection status of all tracked connections
10
+ * - Uses libp2p's connection state (no network overhead from pings)
11
+ * - If connection is not open, increments failure counter
11
12
  * - After `failureThreshold` failures, marks connection as dead
12
13
  * - Emits events for degraded/recovered/dead connections
13
14
  * - Automatically removes dead children from hierarchy
@@ -23,15 +24,15 @@ export class oConnectionHeartbeatManager extends oObject {
23
24
  }
24
25
  async start() {
25
26
  if (!this.config.enabled) {
26
- this.logger.debug('Connection heartbeat disabled');
27
+ this.logger.debug('Connection health monitoring disabled');
27
28
  return;
28
29
  }
29
- this.logger.info(`Starting connection heartbeat: interval=${this.config.intervalMs}ms, ` +
30
- `timeout=${this.config.timeoutMs}ms, threshold=${this.config.failureThreshold}`);
30
+ this.logger.info(`Starting connection health monitoring: interval=${this.config.intervalMs}ms, ` +
31
+ `threshold=${this.config.failureThreshold}`);
31
32
  // Immediate first check
32
- await this.performHeartbeatCycle();
33
+ await this.performHealthCheckCycle();
33
34
  // Schedule recurring checks
34
- this.heartbeatInterval = setInterval(() => this.performHeartbeatCycle(), this.config.intervalMs);
35
+ this.heartbeatInterval = setInterval(() => this.performHealthCheckCycle(), this.config.intervalMs);
35
36
  }
36
37
  async stop() {
37
38
  if (this.heartbeatInterval) {
@@ -40,8 +41,8 @@ export class oConnectionHeartbeatManager extends oObject {
40
41
  }
41
42
  this.healthMap.clear();
42
43
  }
43
- async performHeartbeatCycle() {
44
- if (!this.isRunning) {
44
+ async performHealthCheckCycle() {
45
+ if (this.isRunning) {
45
46
  return;
46
47
  }
47
48
  this.isRunning = true;
@@ -60,7 +61,7 @@ export class oConnectionHeartbeatManager extends oObject {
60
61
  // Use this.node.parent getter to get the current parent address with transports
61
62
  // rather than getParents() which may have a stale reference
62
63
  const parent = this.node.parent;
63
- // make sure that we don't double ping the leader
64
+ // make sure that we don't double check the leader
64
65
  if (parent && parent?.toString() !== oAddress.leader().toString()) {
65
66
  targets.push({ address: parent, role: 'parent' });
66
67
  }
@@ -72,26 +73,38 @@ export class oConnectionHeartbeatManager extends oObject {
72
73
  targets.push({ address: child, role: 'child' });
73
74
  }
74
75
  }
75
- // Ping all targets in parallel
76
- await Promise.allSettled(targets.map((target) => this.pingTarget(target.address, target.role)));
76
+ // Check all targets in parallel
77
+ await Promise.allSettled(targets.map((target) => this.checkTarget(target.address, target.role)));
77
78
  this.isRunning = false;
78
79
  }
79
- doPing(address) {
80
+ /**
81
+ * Check if a connection to the given address is open by examining libp2p's connection state
82
+ * @returns true if an open connection exists, false otherwise
83
+ */
84
+ checkConnectionStatus(address) {
80
85
  if (address.toString() === this.node.address.toString()) {
81
- return Promise.resolve();
86
+ return true; // Self-connection is always "open"
82
87
  }
83
- const transport = address.libp2pTransports[0].toMultiaddr();
84
- if (transport.toString().indexOf('p2p-circuit') > -1) {
85
- return this.node.use(address, {
86
- method: 'ping',
87
- params: {},
88
- });
88
+ if (!address.libp2pTransports.length) {
89
+ return false;
90
+ }
91
+ try {
92
+ // Get peer ID from the address
93
+ const peerIdString = address.libp2pTransports[0].toPeerId();
94
+ // Get all connections to this peer from libp2p
95
+ // Note: Using 'as any' since converting to proper PeerId breaks browser implementation
96
+ const connections = this.node.p2pNode.getConnections(peerIdString);
97
+ // Check if any connection is open
98
+ return connections.some((conn) => conn.status === 'open');
99
+ }
100
+ catch (error) {
101
+ this.logger.debug(`Error checking connection status for ${address}`, error);
102
+ return false;
89
103
  }
90
- return this.node.p2pNode.services.ping.ping(transport);
91
104
  }
92
- async pingTarget(address, role) {
105
+ async checkTarget(address, role) {
93
106
  if (!address.libp2pTransports.length) {
94
- this.logger.debug(`${role} has no transports, skipping ping`, address);
107
+ this.logger.debug(`${role} has no transports, skipping health check`, address);
95
108
  return;
96
109
  }
97
110
  const key = address.toString();
@@ -107,36 +120,24 @@ export class oConnectionHeartbeatManager extends oObject {
107
120
  };
108
121
  this.healthMap.set(key, health);
109
122
  }
110
- try {
111
- // Use libp2p's native ping service
112
- const startTime = Date.now();
113
- // Create timeout promise
114
- const timeoutPromise = new Promise((_, reject) => {
115
- setTimeout(() => reject(new Error('Ping timeout')), this.config.timeoutMs);
116
- });
117
- // Race between ping and timeout
118
- // The ping service accepts PeerId as string or object
119
- await Promise.race([this.doPing(address), timeoutPromise]);
120
- const latency = Date.now() - startTime;
121
- // Success - update health
123
+ // Check connection status using libp2p's connection state
124
+ const isOpen = this.checkConnectionStatus(address);
125
+ if (isOpen) {
126
+ // Connection is open - success
122
127
  health.lastSuccessfulPing = Date.now();
123
128
  health.consecutiveFailures = 0;
124
- health.averageLatency =
125
- health.averageLatency === 0
126
- ? latency
127
- : health.averageLatency * 0.7 + latency * 0.3; // Exponential moving average
128
129
  const previousStatus = health.status;
129
130
  health.status = 'healthy';
130
131
  // Emit recovery event if was degraded
131
132
  if (previousStatus === 'degraded') {
132
- this.logger.info(`Connection recovered: ${address} (latency: ${latency}ms)`);
133
+ this.logger.info(`Connection recovered: ${address}`);
133
134
  this.emitConnectionRecoveredEvent(address, role);
134
135
  }
135
- // this.logger.debug(`Ping successful: ${address} (${latency}ms)`);
136
136
  }
137
- catch (error) {
137
+ else {
138
+ // Connection is not open
138
139
  health.consecutiveFailures++;
139
- this.logger.warn(`Ping failed: ${address} (failures: ${health.consecutiveFailures}/${this.config.failureThreshold})`, error);
140
+ this.logger.warn(`Connection check failed: ${address} (failures: ${health.consecutiveFailures}/${this.config.failureThreshold})`);
140
141
  // Update status based on failure count
141
142
  if (health.consecutiveFailures >= this.config.failureThreshold) {
142
143
  this.handleConnectionDead(address, role, health);
@@ -9,7 +9,6 @@ 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 { oReconnectionManager } from './managers/o-reconnection.manager.js';
13
12
  import { oNodeConnectionConfig } from './connection/index.js';
14
13
  export declare class oNode extends oToolBase {
15
14
  peerId: PeerId;
@@ -19,7 +18,6 @@ export declare class oNode extends oToolBase {
19
18
  connectionManager: oNodeConnectionManager;
20
19
  hierarchyManager: oNodeHierarchyManager;
21
20
  connectionHeartbeatManager?: oConnectionHeartbeatManager;
22
- reconnectionManager?: oReconnectionManager;
23
21
  protected didRegister: boolean;
24
22
  constructor(config: oNodeConfig);
25
23
  get leader(): oNodeAddress | null;
@@ -32,6 +30,7 @@ export declare class oNode extends oToolBase {
32
30
  get parentTransports(): oNodeTransport[];
33
31
  get transports(): oNodeTransport[];
34
32
  unregister(): Promise<void>;
33
+ setKeepAliveTag(address: oNodeAddress): Promise<void>;
35
34
  registerParent(): Promise<void>;
36
35
  registerLeader(): Promise<void>;
37
36
  register(): Promise<void>;
@@ -46,7 +45,6 @@ export declare class oNode extends oToolBase {
46
45
  protected createNode(): Promise<Libp2p>;
47
46
  connect(config: oNodeConnectionConfig): Promise<oNodeConnection>;
48
47
  initConnectionManager(): Promise<void>;
49
- initReconnectionManager(): Promise<void>;
50
48
  hookInitializeFinished(): Promise<void>;
51
49
  hookStartFinished(): Promise<void>;
52
50
  initialize(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"o-node.d.ts","sourceRoot":"","sources":["../../src/o-node.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,MAAM,EACN,YAAY,EACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAKL,QAAQ,EAER,oBAAoB,EAGrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AAEnF,OAAO,EAAmB,SAAS,EAAE,MAAM,eAAe,CAAC;AAG3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,qBAAa,KAAM,SAAQ,SAAS;IAC3B,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAG,MAAM,CAAC;IACjB,OAAO,EAAG,YAAY,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,iBAAiB,EAAG,sBAAsB,CAAC;IAC3C,gBAAgB,EAAG,qBAAqB,CAAC;IACzC,0BAA0B,CAAC,EAAE,2BAA2B,CAAC;IACzD,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAClD,SAAS,CAAC,WAAW,EAAE,OAAO,CAAS;gBAE3B,MAAM,EAAE,WAAW;IAK/B,IAAI,MAAM,IAAI,YAAY,GAAG,IAAI,CAEhC;IAED,IAAI,aAAa,IAAI,YAAY,CAKhC;IAED,IAAI,YAAY,IAAI,MAAM,GAAG,IAAI,CAOhC;IAED,mBAAmB,IAAI,GAAG,EAAE;IAItB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IASvC,SAAS,CAAC,yBAAyB,IAAI,oBAAoB;IAQ3D,IAAI,aAAa,IAAI,YAAY,CAEhC;IAED,IAAI,gBAAgB,IAAI,cAAc,EAAE,CAEvC;IAED,IAAI,UAAU,IAAI,cAAc,EAAE,CAIjC;IAEK,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwD3B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAqC/B,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB/B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B/B,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM;IAItC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAG1D;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;cA0HxB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAMvC,OAAO,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC;IAsBhE,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAStC,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBxC,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAEvC,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCjC;;OAEG;IAiBG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAc/B,UAAU,IAAI,YAAY,EAAE;IAI5B,UAAU,IAAI,YAAY,EAAE;IAI5B,WAAW,IAAI,YAAY,EAAE;IAI7B,WAAW,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI;IAI7C;;;OAGG;IACH,cAAc,IAAI,MAAM;IAUxB;;;OAGG;IACG,wBAAwB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAwEhE"}
1
+ {"version":3,"file":"o-node.d.ts","sourceRoot":"","sources":["../../src/o-node.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { createNode, defaultLibp2pConfig, } from '@olane/o-config';
1
+ import { createNode, defaultLibp2pConfig, KEEP_ALIVE, } from '@olane/o-config';
2
2
  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';
@@ -11,7 +11,6 @@ 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 { oConnectionHeartbeatManager } from './managers/o-connection-heartbeat.manager.js';
14
- import { oReconnectionManager } from './managers/o-reconnection.manager.js';
15
14
  export class oNode extends oToolBase {
16
15
  constructor(config) {
17
16
  super(config);
@@ -106,6 +105,30 @@ export class oNode extends oToolBase {
106
105
  this.logger.error('Failed to unregister from network:', error);
107
106
  });
108
107
  }
108
+ async setKeepAliveTag(address) {
109
+ if (!address || !address.libp2pTransports?.length) {
110
+ this.logger.warn('Address has no transports, skipping keep alive tag!', address);
111
+ return;
112
+ }
113
+ try {
114
+ const peers = await this.p2pNode.peerStore.all();
115
+ // find the peer that is already indexed rather than building the PeerId from the string value to avoid browser issues
116
+ const peer = peers.find((p) => p.id.toString() === address.libp2pTransports[0].toPeerId().toString());
117
+ if (!peer) {
118
+ this.logger.warn('Peer not found, skipping keep alive tag!', address);
119
+ return;
120
+ }
121
+ await this.p2pNode.peerStore.merge(peer.id, {
122
+ tags: {
123
+ [KEEP_ALIVE]: { value: 100 },
124
+ },
125
+ });
126
+ this.logger.debug('Set keep alive tag for peer:', peer.id.toString(), ' with address:', address.toString());
127
+ }
128
+ catch (error) {
129
+ this.logger.error('Failed to set keep alive tag:', error);
130
+ }
131
+ }
109
132
  async registerParent() {
110
133
  if (this.type === NodeType.LEADER) {
111
134
  this.logger.debug('Skipping parent registration, node is leader');
@@ -118,7 +141,7 @@ export class oNode extends oToolBase {
118
141
  }
119
142
  else {
120
143
  this.logger.debug('Waiting for parent and reconnecting...');
121
- await this.reconnectionManager?.waitForParentAndReconnect();
144
+ // await this.reconnectionManager?.waitForParentAndReconnect();
122
145
  }
123
146
  }
124
147
  // if no parent transports, register with the parent to get them
@@ -134,6 +157,7 @@ export class oNode extends oToolBase {
134
157
  _token: this.config.joinToken,
135
158
  },
136
159
  });
160
+ this.setKeepAliveTag(this.parent);
137
161
  }
138
162
  }
139
163
  async registerLeader() {
@@ -149,6 +173,7 @@ export class oNode extends oToolBase {
149
173
  },
150
174
  };
151
175
  await this.use(address, params);
176
+ this.setKeepAliveTag(this.leader);
152
177
  }
153
178
  async register() {
154
179
  if (this.type === NodeType.LEADER) {
@@ -271,6 +296,13 @@ export class oNode extends oToolBase {
271
296
  ...(this.config.network?.connectionGater || {}),
272
297
  };
273
298
  }
299
+ params.connectionManager = {
300
+ ...(params.connectionManager || {}),
301
+ reconnectRetries: 20,
302
+ reconnectRetryInterval: 2000,
303
+ reconnectBackoffFactor: 1.2,
304
+ maxParallelReconnects: 10,
305
+ };
274
306
  // handle the address encapsulation
275
307
  if (this.config.leader &&
276
308
  !this.address.protocol.includes(this.config.leader.protocol)) {
@@ -311,27 +343,12 @@ export class oNode extends oToolBase {
311
343
  runOnLimitedConnection: this.config.runOnLimitedConnection ?? false,
312
344
  });
313
345
  }
314
- async initReconnectionManager() {
315
- // Initialize reconnection manager
316
- if (this.config.reconnection?.enabled !== false) {
317
- this.reconnectionManager = new oReconnectionManager(this, {
318
- enabled: true,
319
- maxAttempts: this.config.reconnection?.maxAttempts ?? 10,
320
- baseDelayMs: this.config.reconnection?.baseDelayMs ?? 5000,
321
- maxDelayMs: this.config.reconnection?.maxDelayMs ?? 60000,
322
- useLeaderFallback: this.config.reconnection?.useLeaderFallback ?? true,
323
- parentDiscoveryIntervalMs: this.config.reconnection?.parentDiscoveryIntervalMs ?? 10000,
324
- parentDiscoveryMaxDelayMs: this.config.reconnection?.parentDiscoveryMaxDelayMs ?? 60000,
325
- });
326
- }
327
- }
328
346
  async hookInitializeFinished() { }
329
347
  async hookStartFinished() {
330
- // Initialize connection heartbeat manager
348
+ // Initialize connection health monitor
331
349
  this.connectionHeartbeatManager = new oConnectionHeartbeatManager(this, {
332
350
  enabled: this.config.connectionHeartbeat?.enabled ?? true,
333
351
  intervalMs: this.config.connectionHeartbeat?.intervalMs ?? 15000,
334
- timeoutMs: this.config.connectionHeartbeat?.timeoutMs ?? 15000,
335
352
  failureThreshold: this.config.connectionHeartbeat?.failureThreshold ?? 3,
336
353
  checkChildren: this.config.connectionHeartbeat?.checkChildren ?? false,
337
354
  checkParent: this.config.connectionHeartbeat?.checkParent ?? true,
@@ -365,8 +382,6 @@ export class oNode extends oToolBase {
365
382
  this.logger.debug('Adding leader resolver fallback...');
366
383
  this.router.addResolver(new oLeaderResolverFallback(this.address));
367
384
  }
368
- // initialize reconnection manager
369
- await this.initReconnectionManager();
370
385
  await this.hookInitializeFinished();
371
386
  }
372
387
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-node",
3
- "version": "0.7.12-alpha.66",
3
+ "version": "0.7.12-alpha.68",
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.66",
58
- "@olane/o-core": "0.7.12-alpha.66",
59
- "@olane/o-protocol": "0.7.12-alpha.66",
60
- "@olane/o-tool": "0.7.12-alpha.66",
57
+ "@olane/o-config": "0.7.12-alpha.68",
58
+ "@olane/o-core": "0.7.12-alpha.68",
59
+ "@olane/o-protocol": "0.7.12-alpha.68",
60
+ "@olane/o-tool": "0.7.12-alpha.68",
61
61
  "debug": "^4.4.1",
62
62
  "dotenv": "^16.5.0"
63
63
  },
64
- "gitHead": "879cb37d1e93b54a1e5d804987daf478fcc2722f"
64
+ "gitHead": "3ffe39de1430bed3673c13adc1b144f9016967dc"
65
65
  }