@olane/o-node 0.7.12-alpha.38 → 0.7.12-alpha.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/connection/o-node-connection.d.ts +1 -0
- package/dist/src/connection/o-node-connection.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.js +26 -1
- package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -1
- package/dist/src/connection/o-node-connection.manager.js +1 -0
- package/dist/src/managers/o-connection-heartbeat.manager.d.ts +1 -0
- package/dist/src/managers/o-connection-heartbeat.manager.d.ts.map +1 -1
- package/dist/src/managers/o-connection-heartbeat.manager.js +9 -2
- package/dist/src/o-node.d.ts +10 -0
- package/dist/src/o-node.d.ts.map +1 -1
- package/dist/src/o-node.js +84 -1
- package/package.json +6 -6
|
@@ -7,6 +7,7 @@ export declare class oNodeConnection extends oConnection {
|
|
|
7
7
|
constructor(config: oNodeConnectionConfig);
|
|
8
8
|
validate(): void;
|
|
9
9
|
transmit(request: oRequest): Promise<oResponse>;
|
|
10
|
+
abort(error: Error): Promise<void>;
|
|
10
11
|
close(): Promise<void>;
|
|
11
12
|
}
|
|
12
13
|
//# sourceMappingURL=o-node-connection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-node-connection.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAEL,WAAW,EAGX,QAAQ,EACR,SAAS,EACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAEjF,qBAAa,eAAgB,SAAQ,WAAW;IAGlC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB;IAFrD,aAAa,EAAE,UAAU,CAAC;gBAEF,MAAM,EAAE,qBAAqB;IAK5D,QAAQ;IAOF,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"o-node-connection.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAEL,WAAW,EAGX,QAAQ,EACR,SAAS,EACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAEjF,qBAAa,eAAgB,SAAQ,WAAW;IAGlC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,qBAAqB;IAFrD,aAAa,EAAE,UAAU,CAAC;gBAEF,MAAM,EAAE,qBAAqB;IAK5D,QAAQ;IAOF,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC;IAsF/C,KAAK,CAAC,KAAK,EAAE,KAAK;IAMlB,KAAK;CAKZ"}
|
|
@@ -14,6 +14,7 @@ export class oNodeConnection extends oConnection {
|
|
|
14
14
|
async transmit(request) {
|
|
15
15
|
try {
|
|
16
16
|
const stream = await this.p2pConnection.newStream(this.nextHopAddress.protocol, {
|
|
17
|
+
signal: this.abortSignal,
|
|
17
18
|
maxOutboundStreams: process.env.MAX_OUTBOUND_STREAMS
|
|
18
19
|
? parseInt(process.env.MAX_OUTBOUND_STREAMS)
|
|
19
20
|
: 1000,
|
|
@@ -30,7 +31,19 @@ export class oNodeConnection extends oConnection {
|
|
|
30
31
|
const sent = stream.send(data);
|
|
31
32
|
let lastResponse;
|
|
32
33
|
await new Promise((resolve, reject) => {
|
|
33
|
-
|
|
34
|
+
const abortHandler = async () => {
|
|
35
|
+
try {
|
|
36
|
+
await stream.abort(new Error('Request aborted'));
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
// Stream may already be closed
|
|
40
|
+
}
|
|
41
|
+
reject(new Error('Request aborted'));
|
|
42
|
+
};
|
|
43
|
+
// Listen for abort signal
|
|
44
|
+
if (this.abortSignal) {
|
|
45
|
+
this.abortSignal.addEventListener('abort', abortHandler);
|
|
46
|
+
}
|
|
34
47
|
stream.addEventListener('message', async (event) => {
|
|
35
48
|
const response = await CoreUtils.processStreamResponse(event);
|
|
36
49
|
this.emitter.emit('chunk', response);
|
|
@@ -38,6 +51,10 @@ export class oNodeConnection extends oConnection {
|
|
|
38
51
|
if (response.result._last || !response.result._isStreaming) {
|
|
39
52
|
// this.logger.debug('Last chunk received...');
|
|
40
53
|
lastResponse = response;
|
|
54
|
+
// Clean up abort listener before closing
|
|
55
|
+
if (this.abortSignal) {
|
|
56
|
+
this.abortSignal.removeEventListener('abort', abortHandler);
|
|
57
|
+
}
|
|
41
58
|
await stream.close();
|
|
42
59
|
resolve(true);
|
|
43
60
|
}
|
|
@@ -50,6 +67,9 @@ export class oNodeConnection extends oConnection {
|
|
|
50
67
|
signal: AbortSignal.timeout(this.config.drainTimeoutMs ?? 30000),
|
|
51
68
|
}); // Default: 30 second timeout
|
|
52
69
|
}
|
|
70
|
+
if (stream.status === 'open') {
|
|
71
|
+
await stream.abort(new Error('Connection closed'));
|
|
72
|
+
}
|
|
53
73
|
const response = oResponse.fromJSON(lastResponse);
|
|
54
74
|
return response;
|
|
55
75
|
}
|
|
@@ -60,6 +80,11 @@ export class oNodeConnection extends oConnection {
|
|
|
60
80
|
throw error;
|
|
61
81
|
}
|
|
62
82
|
}
|
|
83
|
+
async abort(error) {
|
|
84
|
+
this.logger.debug('Aborting connection');
|
|
85
|
+
await this.p2pConnection.abort(error);
|
|
86
|
+
this.logger.debug('Connection aborted');
|
|
87
|
+
}
|
|
63
88
|
async close() {
|
|
64
89
|
this.logger.debug('Closing connection');
|
|
65
90
|
await this.p2pConnection.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"o-node-connection.manager.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAC5D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAAS;gBAE3B,MAAM,EAAE,4BAA4B;IAOhD;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"o-node-connection.manager.d.ts","sourceRoot":"","sources":["../../../src/connection/o-node-connection.manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAC5D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAAS;gBAE3B,MAAM,EAAE,4BAA4B;IAOhD;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAmDlE,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAIpC,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,WAAW,GAAG,IAAI;CAe3D"}
|
|
@@ -38,6 +38,7 @@ export class oNodeConnectionManager extends oConnectionManager {
|
|
|
38
38
|
readTimeoutMs: readTimeoutMs ?? this.defaultReadTimeoutMs,
|
|
39
39
|
drainTimeoutMs: drainTimeoutMs ?? this.defaultDrainTimeoutMs,
|
|
40
40
|
isStream: config.isStream ?? false,
|
|
41
|
+
abortSignal: config.abortSignal,
|
|
41
42
|
});
|
|
42
43
|
// this.cache.set(nextHopAddress.toString(), connection);
|
|
43
44
|
return connection;
|
|
@@ -37,6 +37,7 @@ export declare class oConnectionHeartbeatManager extends oObject {
|
|
|
37
37
|
private config;
|
|
38
38
|
private heartbeatInterval?;
|
|
39
39
|
private healthMap;
|
|
40
|
+
private isRunning;
|
|
40
41
|
constructor(node: IHeartbeatableNode, config: HeartbeatConfig);
|
|
41
42
|
start(): Promise<void>;
|
|
42
43
|
stop(): Promise<void>;
|
|
@@ -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;
|
|
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,4 +1,4 @@
|
|
|
1
|
-
import { oObject, ChildLeftEvent, ParentDisconnectedEvent, LeaderDisconnectedEvent, ConnectionDegradedEvent, ConnectionRecoveredEvent, } from '@olane/o-core';
|
|
1
|
+
import { oObject, ChildLeftEvent, ParentDisconnectedEvent, LeaderDisconnectedEvent, ConnectionDegradedEvent, ConnectionRecoveredEvent, oAddress, } from '@olane/o-core';
|
|
2
2
|
/**
|
|
3
3
|
* Connection Heartbeat Manager
|
|
4
4
|
*
|
|
@@ -19,6 +19,7 @@ export class oConnectionHeartbeatManager extends oObject {
|
|
|
19
19
|
this.node = node;
|
|
20
20
|
this.config = config;
|
|
21
21
|
this.healthMap = new Map();
|
|
22
|
+
this.isRunning = false;
|
|
22
23
|
}
|
|
23
24
|
async start() {
|
|
24
25
|
if (!this.config.enabled) {
|
|
@@ -40,6 +41,10 @@ export class oConnectionHeartbeatManager extends oObject {
|
|
|
40
41
|
this.healthMap.clear();
|
|
41
42
|
}
|
|
42
43
|
async performHeartbeatCycle() {
|
|
44
|
+
if (!this.isRunning) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
this.isRunning = true;
|
|
43
48
|
const targets = [];
|
|
44
49
|
// Check if this is a leader node (no leader in hierarchy = we are leader)
|
|
45
50
|
const isLeaderNode = this.node.getLeaders().length === 0;
|
|
@@ -55,7 +60,8 @@ export class oConnectionHeartbeatManager extends oObject {
|
|
|
55
60
|
// Use this.node.parent getter to get the current parent address with transports
|
|
56
61
|
// rather than getParents() which may have a stale reference
|
|
57
62
|
const parent = this.node.parent;
|
|
58
|
-
|
|
63
|
+
// make sure that we don't double ping the leader
|
|
64
|
+
if (parent && parent?.toString() !== oAddress.leader().toString()) {
|
|
59
65
|
targets.push({ address: parent, role: 'parent' });
|
|
60
66
|
}
|
|
61
67
|
}
|
|
@@ -68,6 +74,7 @@ export class oConnectionHeartbeatManager extends oObject {
|
|
|
68
74
|
}
|
|
69
75
|
// Ping all targets in parallel
|
|
70
76
|
await Promise.allSettled(targets.map((target) => this.pingTarget(target.address, target.role)));
|
|
77
|
+
this.isRunning = false;
|
|
71
78
|
}
|
|
72
79
|
doPing(address) {
|
|
73
80
|
if (address.toString() === this.node.address.toString()) {
|
package/dist/src/o-node.d.ts
CHANGED
|
@@ -58,5 +58,15 @@ export declare class oNode extends oToolBase {
|
|
|
58
58
|
getParents(): oNodeAddress[];
|
|
59
59
|
getChildren(): oNodeAddress[];
|
|
60
60
|
removeChild(childAddress: oNodeAddress): void;
|
|
61
|
+
/**
|
|
62
|
+
* Get the total number of active streams across all connections
|
|
63
|
+
* @returns Total count of active streams
|
|
64
|
+
*/
|
|
65
|
+
getStreamCount(): number;
|
|
66
|
+
/**
|
|
67
|
+
* Get libp2p metrics for this node
|
|
68
|
+
* Tool method that can be called remotely by monitoring systems
|
|
69
|
+
*/
|
|
70
|
+
_tool_get_libp2p_metrics(request: oRequest): Promise<any>;
|
|
61
71
|
}
|
|
62
72
|
//# sourceMappingURL=o-node.d.ts.map
|
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,
|
|
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
|
@@ -102,7 +102,9 @@ export class oNode extends oToolBase {
|
|
|
102
102
|
peerId: this.peerId.toString(),
|
|
103
103
|
},
|
|
104
104
|
};
|
|
105
|
-
|
|
105
|
+
this.use(address, params).catch((error) => {
|
|
106
|
+
this.logger.error('Failed to unregister from network:', error);
|
|
107
|
+
});
|
|
106
108
|
}
|
|
107
109
|
async registerParent() {
|
|
108
110
|
if (this.type === NodeType.LEADER) {
|
|
@@ -407,4 +409,85 @@ export class oNode extends oToolBase {
|
|
|
407
409
|
removeChild(childAddress) {
|
|
408
410
|
this.hierarchyManager.removeChild(childAddress);
|
|
409
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Get the total number of active streams across all connections
|
|
414
|
+
* @returns Total count of active streams
|
|
415
|
+
*/
|
|
416
|
+
getStreamCount() {
|
|
417
|
+
if (!this.p2pNode) {
|
|
418
|
+
return 0;
|
|
419
|
+
}
|
|
420
|
+
const connections = this.p2pNode.getConnections();
|
|
421
|
+
return connections.reduce((count, conn) => {
|
|
422
|
+
return count + (conn.streams?.length || 0);
|
|
423
|
+
}, 0);
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Get libp2p metrics for this node
|
|
427
|
+
* Tool method that can be called remotely by monitoring systems
|
|
428
|
+
*/
|
|
429
|
+
async _tool_get_libp2p_metrics(request) {
|
|
430
|
+
if (!this.p2pNode) {
|
|
431
|
+
return {
|
|
432
|
+
error: 'libp2p node not available',
|
|
433
|
+
available: false,
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
try {
|
|
437
|
+
// Get basic connection stats
|
|
438
|
+
const connections = this.p2pNode.getConnections();
|
|
439
|
+
const peers = await this.p2pNode.peerStore.all();
|
|
440
|
+
const inbound = connections.filter((c) => c.direction === 'inbound').length;
|
|
441
|
+
const outbound = connections.filter((c) => c.direction === 'outbound').length;
|
|
442
|
+
// Get DHT info if available
|
|
443
|
+
const services = this.p2pNode.services;
|
|
444
|
+
const dht = services?.dht;
|
|
445
|
+
const routingTable = dht?.routingTable;
|
|
446
|
+
const kBuckets = routingTable?.kb || null;
|
|
447
|
+
let routingTableSize = 0;
|
|
448
|
+
if (kBuckets) {
|
|
449
|
+
// Handle both array and object-like structures
|
|
450
|
+
if (Array.isArray(kBuckets)) {
|
|
451
|
+
for (const bucket of kBuckets) {
|
|
452
|
+
routingTableSize += bucket.peers?.length || 0;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
else if (typeof kBuckets === 'object') {
|
|
456
|
+
// If it's an object, iterate over its values
|
|
457
|
+
for (const bucket of Object.values(kBuckets)) {
|
|
458
|
+
routingTableSize += bucket?.peers?.length || 0;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
// Calculate total stream count across all connections
|
|
463
|
+
const streamCount = connections.reduce((count, conn) => {
|
|
464
|
+
return count + (conn.streams?.length || 0);
|
|
465
|
+
}, 0);
|
|
466
|
+
return {
|
|
467
|
+
available: true,
|
|
468
|
+
timestamp: Date.now(),
|
|
469
|
+
nodeAddress: this.address.toString(),
|
|
470
|
+
peerCount: peers.length,
|
|
471
|
+
connectionCount: connections.length,
|
|
472
|
+
inboundConnections: inbound,
|
|
473
|
+
outboundConnections: outbound,
|
|
474
|
+
streamCount,
|
|
475
|
+
dhtEnabled: !!dht,
|
|
476
|
+
dhtMode: dht?.clientMode ? 'client' : 'server',
|
|
477
|
+
dhtRoutingTableSize: routingTableSize,
|
|
478
|
+
protocols: Array.from(this.p2pNode.getProtocols()),
|
|
479
|
+
selfPeerId: this.p2pNode.peerId.toString(),
|
|
480
|
+
multiaddrs: this.p2pNode
|
|
481
|
+
.getMultiaddrs()
|
|
482
|
+
.map((ma) => ma.toString()),
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
catch (error) {
|
|
486
|
+
return {
|
|
487
|
+
error: `Failed to collect libp2p metrics: ${error.message}`,
|
|
488
|
+
available: false,
|
|
489
|
+
nodeAddress: this.address.toString(),
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
}
|
|
410
493
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olane/o-node",
|
|
3
|
-
"version": "0.7.12-alpha.
|
|
3
|
+
"version": "0.7.12-alpha.39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -54,12 +54,12 @@
|
|
|
54
54
|
"typescript": "5.4.5"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@olane/o-config": "0.7.12-alpha.
|
|
58
|
-
"@olane/o-core": "0.7.12-alpha.
|
|
59
|
-
"@olane/o-protocol": "0.7.12-alpha.
|
|
60
|
-
"@olane/o-tool": "0.7.12-alpha.
|
|
57
|
+
"@olane/o-config": "0.7.12-alpha.39",
|
|
58
|
+
"@olane/o-core": "0.7.12-alpha.39",
|
|
59
|
+
"@olane/o-protocol": "0.7.12-alpha.39",
|
|
60
|
+
"@olane/o-tool": "0.7.12-alpha.39",
|
|
61
61
|
"debug": "^4.4.1",
|
|
62
62
|
"dotenv": "^16.5.0"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "794416f70451282e59b498e969c6597896abec29"
|
|
65
65
|
}
|