@olane/o-node 0.7.43 → 0.7.44

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.
@@ -7,21 +7,20 @@ export declare class oNodeConnectionManager extends oConnectionManager {
7
7
  protected p2pNode: Libp2p;
8
8
  private defaultReadTimeoutMs?;
9
9
  private defaultDrainTimeoutMs?;
10
- private connectionsByTransportKey;
11
- private pendingDialsByTransportKey;
10
+ private connectionsByAddress;
11
+ private pendingDialsByAddress;
12
12
  constructor(config: oNodeConnectionManagerConfig);
13
13
  /**
14
14
  * Set up listeners to maintain connection cache state
15
15
  */
16
16
  private setupConnectionListeners;
17
17
  /**
18
- * Build a stable cache key from the libp2p transports on an address.
18
+ * Build a stable cache key from an address.
19
19
  *
20
- * We intentionally key the cache by transports (multiaddrs) instead of peer IDs
21
- * to avoid ambiguity when multiple peers may share a peer ID or when addresses
22
- * change but the libp2p transports are the true dial targets.
20
+ * We key the cache by address value (e.g., "o://my-tool") to maintain
21
+ * a simple one-to-one mapping between addresses and connections.
23
22
  */
24
- private getTransportKeyFromAddress;
23
+ private getAddressKey;
25
24
  /**
26
25
  * Extract peer ID string from an address
27
26
  * @param address - The address to extract peer ID from
@@ -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,MAAM,EAAE,UAAU,EAAU,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAQhD,QAAQ,CAAC,MAAM,EAAE,4BAA4B;IAPzD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAAS;IACvC,OAAO,CAAC,yBAAyB,CAAsC;IACvE,OAAO,CAAC,0BAA0B,CACtB;gBAES,MAAM,EAAE,4BAA4B;IAWzD;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAsBhC;;;;;;OAMG;IACH,OAAO,CAAC,0BAA0B;IAiBlC;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAatB,qBAAqB,CACzB,cAAc,EAAE,QAAQ,EACxB,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,UAAU,CAAC;YA+DR,WAAW;IAwBnB,MAAM,CACV,MAAM,EAAE,iBAAiB,GAAG;QAAE,aAAa,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GACzE,OAAO,CAAC,eAAe,CAAC;IAmC3B;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IA8BlE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAwCpC;;;;OAIG;IACH,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,UAAU,GAAG,IAAI;IA+C/D;;;OAGG;IACH,aAAa,IAAI;QACf,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,KAAK,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC9D;IAaD;;;OAGG;IACH,uBAAuB,IAAI,MAAM;CAgBlC"}
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,MAAM,EAAE,UAAU,EAAU,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,kDAAkD,CAAC;AAEhG,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAQhD,QAAQ,CAAC,MAAM,EAAE,4BAA4B;IAPzD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,oBAAoB,CAAC,CAAS;IACtC,OAAO,CAAC,qBAAqB,CAAC,CAAS;IACvC,OAAO,CAAC,oBAAoB,CAAsC;IAClE,OAAO,CAAC,qBAAqB,CACjB;gBAES,MAAM,EAAE,4BAA4B;IAWzD;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAsBhC;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IASrB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAatB,qBAAqB,CACzB,cAAc,EAAE,QAAQ,EACxB,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,UAAU,CAAC;YA+DR,WAAW;IAwBnB,MAAM,CACV,MAAM,EAAE,iBAAiB,GAAG;QAAE,aAAa,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GACzE,OAAO,CAAC,eAAe,CAAC;IAmC3B;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IA8BlE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAwCpC;;;;OAIG;IACH,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,UAAU,GAAG,IAAI;IA+C/D;;;OAGG;IACH,aAAa,IAAI;QACf,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,KAAK,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC9D;IAaD;;;OAGG;IACH,uBAAuB,IAAI,MAAM;CAgBlC"}
@@ -4,8 +4,8 @@ export class oNodeConnectionManager extends oConnectionManager {
4
4
  constructor(config) {
5
5
  super(config);
6
6
  this.config = config;
7
- this.connectionsByTransportKey = new Map();
8
- this.pendingDialsByTransportKey = new Map();
7
+ this.connectionsByAddress = new Map();
8
+ this.pendingDialsByAddress = new Map();
9
9
  this.p2pNode = config.p2pNode;
10
10
  this.defaultReadTimeoutMs = config.defaultReadTimeoutMs;
11
11
  this.defaultDrainTimeoutMs = config.defaultDrainTimeoutMs;
@@ -22,34 +22,26 @@ export class oNodeConnectionManager extends oConnectionManager {
22
22
  if (!connection) {
23
23
  return;
24
24
  }
25
- for (const [transportKey, cachedConnection,] of this.connectionsByTransportKey.entries()) {
25
+ for (const [addressKey, cachedConnection,] of this.connectionsByAddress.entries()) {
26
26
  if (cachedConnection === connection) {
27
- this.logger.debug('Connection closed, removing from cache for transport key:', transportKey);
28
- this.connectionsByTransportKey.delete(transportKey);
27
+ this.logger.debug('Connection closed, removing from cache for address:', addressKey);
28
+ this.connectionsByAddress.delete(addressKey);
29
29
  }
30
30
  }
31
31
  });
32
32
  }
33
33
  /**
34
- * Build a stable cache key from the libp2p transports on an address.
34
+ * Build a stable cache key from an address.
35
35
  *
36
- * We intentionally key the cache by transports (multiaddrs) instead of peer IDs
37
- * to avoid ambiguity when multiple peers may share a peer ID or when addresses
38
- * change but the libp2p transports are the true dial targets.
36
+ * We key the cache by address value (e.g., "o://my-tool") to maintain
37
+ * a simple one-to-one mapping between addresses and connections.
39
38
  */
40
- getTransportKeyFromAddress(address) {
39
+ getAddressKey(address) {
41
40
  try {
42
- const nodeAddress = address;
43
- const transports = nodeAddress.libp2pTransports;
44
- if (!transports?.length) {
45
- return null;
46
- }
47
- // Sort to ensure deterministic keys regardless of transport ordering.
48
- const parts = transports.map((t) => t.toString()).sort();
49
- return parts.join('|');
41
+ return address.value || null;
50
42
  }
51
43
  catch (error) {
52
- this.logger.debug('Error extracting transport key from address:', error);
44
+ this.logger.debug('Error extracting address key from address:', error);
53
45
  return null;
54
46
  }
55
47
  }
@@ -75,56 +67,56 @@ export class oNodeConnectionManager extends oConnectionManager {
75
67
  if (!nextHopAddress) {
76
68
  throw new Error('Invalid address passed');
77
69
  }
78
- // Build a transport-based cache key from the next hop address
79
- const transportKey = this.getTransportKeyFromAddress(nextHopAddress);
80
- if (!transportKey) {
81
- throw new Error(`Unable to extract libp2p transports from address: ${nextHopAddress.toString()}`);
70
+ // Build an address-based cache key from the next hop address
71
+ const addressKey = this.getAddressKey(nextHopAddress);
72
+ if (!addressKey) {
73
+ throw new Error(`Unable to extract address key from address: ${nextHopAddress.toString()}`);
82
74
  }
83
- // Check if we have a cached connection by transport key
84
- const cachedConnection = this.connectionsByTransportKey.get(transportKey);
75
+ // Check if we have a cached connection by address key
76
+ const cachedConnection = this.connectionsByAddress.get(addressKey);
85
77
  if (cachedConnection && cachedConnection.status === 'open') {
86
- this.logger.debug('Reusing cached connection for transports:', nextHopAddress?.value);
78
+ this.logger.debug('Reusing cached connection for address:', nextHopAddress?.value);
87
79
  return cachedConnection;
88
80
  }
89
81
  // Clean up stale connection if it exists but is not open
90
82
  if (cachedConnection && cachedConnection.status !== 'open') {
91
- this.logger.debug('Removing stale connection for transports:', transportKey);
92
- this.connectionsByTransportKey.delete(transportKey);
83
+ this.logger.debug('Removing stale connection for address:', addressKey);
84
+ this.connectionsByAddress.delete(addressKey);
93
85
  }
94
86
  // Check if libp2p has an active connection for this address
95
87
  const libp2pConnection = this.getCachedLibp2pConnection(nextHopAddress);
96
88
  if (libp2pConnection && libp2pConnection.status === 'open') {
97
- this.logger.debug('Caching existing libp2p connection for transports:', transportKey);
98
- this.connectionsByTransportKey.set(transportKey, libp2pConnection);
89
+ this.logger.debug('Caching existing libp2p connection for address:', addressKey);
90
+ this.connectionsByAddress.set(addressKey, libp2pConnection);
99
91
  return libp2pConnection;
100
92
  }
101
- // Check if dial is already in progress for this transport key
102
- const pendingDial = this.pendingDialsByTransportKey.get(transportKey);
93
+ // Check if dial is already in progress for this address key
94
+ const pendingDial = this.pendingDialsByAddress.get(addressKey);
103
95
  if (pendingDial) {
104
- this.logger.debug('Awaiting existing dial for transports:', transportKey);
96
+ this.logger.debug('Awaiting existing dial for address:', addressKey);
105
97
  return pendingDial;
106
98
  }
107
- // Start new dial and cache the promise by transport key
108
- const dialPromise = this.performDial(nextHopAddress, transportKey);
109
- this.pendingDialsByTransportKey.set(transportKey, dialPromise);
99
+ // Start new dial and cache the promise by address key
100
+ const dialPromise = this.performDial(nextHopAddress, addressKey);
101
+ this.pendingDialsByAddress.set(addressKey, dialPromise);
110
102
  try {
111
103
  const connection = await dialPromise;
112
- // Cache the established connection by transport key
113
- this.connectionsByTransportKey.set(transportKey, connection);
104
+ // Cache the established connection by address key
105
+ this.connectionsByAddress.set(addressKey, connection);
114
106
  return connection;
115
107
  }
116
108
  finally {
117
- this.pendingDialsByTransportKey.delete(transportKey);
109
+ this.pendingDialsByAddress.delete(addressKey);
118
110
  }
119
111
  }
120
- async performDial(nextHopAddress, transportKey) {
112
+ async performDial(nextHopAddress, addressKey) {
121
113
  this.logger.debug('Dialing new connection', {
122
114
  address: nextHopAddress.value,
123
- transportKey,
115
+ addressKey,
124
116
  });
125
117
  const connection = await this.p2pNode.dial(nextHopAddress.libp2pTransports.map((ma) => ma.toMultiaddr()));
126
118
  this.logger.debug('Successfully dialed connection', {
127
- transportKey,
119
+ addressKey,
128
120
  status: connection.status,
129
121
  remotePeer: connection.remotePeer?.toString(),
130
122
  });
@@ -145,12 +137,12 @@ export class oNodeConnectionManager extends oConnectionManager {
145
137
  requestHandler: config.requestHandler ?? undefined,
146
138
  reusePolicy: reuse ? 'reuse' : 'none',
147
139
  });
148
- const transportKey = this.getTransportKeyFromAddress(nextHopAddress);
149
- if (transportKey) {
150
- this.connectionsByTransportKey.set(transportKey, p2pConnection);
140
+ const addressKey = this.getAddressKey(nextHopAddress);
141
+ if (addressKey) {
142
+ this.connectionsByAddress.set(addressKey, p2pConnection);
151
143
  }
152
144
  else {
153
- this.logger.error('Should not happen! Failed to generate a transport key for address:', nextHopAddress);
145
+ this.logger.error('Should not happen! Failed to generate an address key for address:', nextHopAddress);
154
146
  }
155
147
  return connection;
156
148
  }
@@ -183,12 +175,12 @@ export class oNodeConnectionManager extends oConnectionManager {
183
175
  */
184
176
  isCached(address) {
185
177
  try {
186
- const transportKey = this.getTransportKeyFromAddress(address);
187
- if (!transportKey) {
178
+ const addressKey = this.getAddressKey(address);
179
+ if (!addressKey) {
188
180
  return false;
189
181
  }
190
- // Check our transport-based cache first
191
- const cachedConnection = this.connectionsByTransportKey.get(transportKey);
182
+ // Check our address-based cache first
183
+ const cachedConnection = this.connectionsByAddress.get(addressKey);
192
184
  if (cachedConnection?.status === 'open') {
193
185
  return true;
194
186
  }
@@ -202,7 +194,7 @@ export class oNodeConnectionManager extends oConnectionManager {
202
194
  if (hasOpenConnection) {
203
195
  const openConnection = connections.find((conn) => conn.status === 'open');
204
196
  if (openConnection) {
205
- this.connectionsByTransportKey.set(transportKey, openConnection);
197
+ this.connectionsByAddress.set(addressKey, openConnection);
206
198
  }
207
199
  }
208
200
  return hasOpenConnection;
@@ -219,12 +211,12 @@ export class oNodeConnectionManager extends oConnectionManager {
219
211
  */
220
212
  getCachedLibp2pConnection(address) {
221
213
  try {
222
- const transportKey = this.getTransportKeyFromAddress(address);
223
- if (!transportKey) {
214
+ const addressKey = this.getAddressKey(address);
215
+ if (!addressKey) {
224
216
  return null;
225
217
  }
226
- // Check transport-based cache first
227
- const cachedConnection = this.connectionsByTransportKey.get(transportKey);
218
+ // Check address-based cache first
219
+ const cachedConnection = this.connectionsByAddress.get(addressKey);
228
220
  if (cachedConnection?.status === 'open') {
229
221
  return cachedConnection;
230
222
  }
@@ -237,14 +229,14 @@ export class oNodeConnectionManager extends oConnectionManager {
237
229
  const filteredConnections = connections.filter((conn) => conn.remotePeer?.toString() === peerId);
238
230
  // Find the first open connection
239
231
  const openConnection = filteredConnections.find((conn) => conn.status === 'open');
240
- // If we found an open connection in libp2p, cache it by transport key
232
+ // If we found an open connection in libp2p, cache it by address key
241
233
  if (openConnection) {
242
- this.connectionsByTransportKey.set(transportKey, openConnection);
234
+ this.connectionsByAddress.set(addressKey, openConnection);
243
235
  return openConnection;
244
236
  }
245
237
  // Clean up stale cache entry if connection is no longer open
246
238
  if (cachedConnection) {
247
- this.connectionsByTransportKey.delete(transportKey);
239
+ this.connectionsByAddress.delete(addressKey);
248
240
  }
249
241
  return null;
250
242
  }
@@ -259,9 +251,9 @@ export class oNodeConnectionManager extends oConnectionManager {
259
251
  */
260
252
  getCacheStats() {
261
253
  return {
262
- cachedConnections: this.connectionsByTransportKey.size,
263
- pendingDials: this.pendingDialsByTransportKey.size,
264
- connectionsByPeer: Array.from(this.connectionsByTransportKey.values()).map((conn) => ({
254
+ cachedConnections: this.connectionsByAddress.size,
255
+ pendingDials: this.pendingDialsByAddress.size,
256
+ connectionsByPeer: Array.from(this.connectionsByAddress.values()).map((conn) => ({
265
257
  peerId: conn.remotePeer?.toString() ?? 'unknown',
266
258
  status: conn.status,
267
259
  })),
@@ -273,9 +265,9 @@ export class oNodeConnectionManager extends oConnectionManager {
273
265
  */
274
266
  cleanupStaleConnections() {
275
267
  let removed = 0;
276
- for (const [transportKey, connection,] of this.connectionsByTransportKey.entries()) {
268
+ for (const [addressKey, connection,] of this.connectionsByAddress.entries()) {
277
269
  if (connection.status !== 'open') {
278
- this.connectionsByTransportKey.delete(transportKey);
270
+ this.connectionsByAddress.delete(addressKey);
279
271
  removed++;
280
272
  }
281
273
  }
@@ -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;WACtB,qBAAqB,CAAC,OAAO,EAAE;QACjD,WAAW,EAAE,GAAG,CAAC;QACjB,UAAU,EAAE,UAAU,CAAC;KACxB;CAmEF"}
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;WACtB,qBAAqB,CAAC,OAAO,EAAE;QACjD,WAAW,EAAE,GAAG,CAAC;QACjB,UAAU,EAAE,UAAU,CAAC;KACxB;CA+DF"}
@@ -4,12 +4,13 @@ import { oNodeTransport } from '../router/o-node.transport.js';
4
4
  export class ConnectionUtils extends oObject {
5
5
  static async addressFromConnection(options) {
6
6
  try {
7
- console.log('[ConnectionUtils] addressFromConnection');
8
7
  const { currentNode, connection } = options;
9
8
  const p2pNode = currentNode.p2pNode;
10
9
  // Extract the actual olane address from the peer store
11
10
  const peers = await p2pNode.peerStore.all();
12
- const remotePeer = peers.find((peer) => peer.id.toString() === connection.remotePeer.toString());
11
+ const remotePeer = peers.find((peer) => {
12
+ return peer.id.toString() === connection.remotePeer.toString();
13
+ });
13
14
  if (!remotePeer) {
14
15
  console.log('Failed to find peer:', remotePeer);
15
16
  throw new Error(`Failed to extract remote address, peer ${connection.remotePeer.toString()} not found in peer store.`);
@@ -19,8 +20,7 @@ export class ConnectionUtils extends oObject {
19
20
  if (!originAddress) {
20
21
  throw new Error('Origin address is not configured');
21
22
  }
22
- const originProtocol = originAddress.toString();
23
- const oProtocol = remotePeer.protocols.find((p) => p.startsWith('/o/') && p.startsWith(originProtocol) === false);
23
+ const oProtocol = remotePeer.protocols.find((p) => p.startsWith('/o/'));
24
24
  if (!oProtocol) {
25
25
  throw new Error('Failed to extract remote address, could not find o-protocol in peer protocols.');
26
26
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-node",
3
- "version": "0.7.43",
3
+ "version": "0.7.44",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -40,7 +40,7 @@
40
40
  "devDependencies": {
41
41
  "@eslint/eslintrc": "^3.3.1",
42
42
  "@eslint/js": "^9.29.0",
43
- "@olane/o-test": "0.7.43",
43
+ "@olane/o-test": "0.7.44",
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.43",
64
- "@olane/o-core": "0.7.43",
65
- "@olane/o-protocol": "0.7.43",
66
- "@olane/o-tool": "0.7.43",
63
+ "@olane/o-config": "0.7.44",
64
+ "@olane/o-core": "0.7.44",
65
+ "@olane/o-protocol": "0.7.44",
66
+ "@olane/o-tool": "0.7.44",
67
67
  "debug": "^4.4.1",
68
68
  "dotenv": "^16.5.0",
69
69
  "json5": "^2.2.3"
70
70
  },
71
- "gitHead": "12e63fad2b09173fbcf455d881276b7ca7b3344d"
71
+ "gitHead": "de7bc5247c97fb219d522cc5874f7459634e03ec"
72
72
  }