@rpckit/tcp 0.9.99
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/README.md +89 -0
- package/dist/electrum-cash/index.d.ts +3 -0
- package/dist/electrum-cash/index.d.ts.map +1 -0
- package/dist/electrum-cash/index.js +2 -0
- package/dist/electrum-cash/index.js.map +1 -0
- package/dist/electrum-cash/tcp.d.ts +20 -0
- package/dist/electrum-cash/tcp.d.ts.map +1 -0
- package/dist/electrum-cash/tcp.js +66 -0
- package/dist/electrum-cash/tcp.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/tcp.d.ts +6 -0
- package/dist/tcp.d.ts.map +1 -0
- package/dist/tcp.js +439 -0
- package/dist/tcp.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @rpckit/tcp
|
|
2
|
+
|
|
3
|
+
TCP transport for rpckit (Node.js only). Supports TLS, subscriptions, keep-alive, and request batching.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @rpckit/core @rpckit/tcp
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { tcp } from '@rpckit/tcp'
|
|
15
|
+
|
|
16
|
+
// Plain TCP
|
|
17
|
+
const transport = tcp('tcp://example.com:50001')
|
|
18
|
+
|
|
19
|
+
// TCP with TLS
|
|
20
|
+
const tlsTransport = tcp('tcp+tls://example.com:50002')
|
|
21
|
+
|
|
22
|
+
await transport.connect()
|
|
23
|
+
const result = await transport.request('my.method', 'param1')
|
|
24
|
+
await transport.close()
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Electrum Cash Variant
|
|
28
|
+
|
|
29
|
+
For Electrum Cash servers, use the `electrum-cash` subpath which pre-configures handshake, keep-alive method, and unsubscribe conventions:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { tcp } from '@rpckit/tcp/electrum-cash'
|
|
33
|
+
|
|
34
|
+
const transport = tcp('tcp+tls://electrum.example.com:50002', {
|
|
35
|
+
keepAlive: 60000 // Automatically uses server.ping
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
// Handshake (server.version) sent automatically on connect
|
|
39
|
+
const tip = await transport.request('blockchain.headers.get_tip')
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The electrum-cash variant also accepts:
|
|
43
|
+
|
|
44
|
+
- `clientName` - Client name sent in server.version handshake (default: `'rpckit'`)
|
|
45
|
+
- `protocolVersion` - Protocol version (default: `'1.6'`)
|
|
46
|
+
|
|
47
|
+
## Subscription Sharing
|
|
48
|
+
|
|
49
|
+
Multiple callers subscribing to the same method+params will share a single server subscription. New subscribers receive the most recent notification data (not stale initial data). The server unsubscribe is only sent when the last listener unsubscribes.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Both callbacks share one server subscription
|
|
53
|
+
const unsub1 = await transport.subscribe('events', callback1)
|
|
54
|
+
const unsub2 = await transport.subscribe('events', callback2)
|
|
55
|
+
|
|
56
|
+
await unsub1() // callback1 removed, server subscription stays active
|
|
57
|
+
await unsub2() // callback2 removed, NOW server unsubscribe is sent
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Options
|
|
61
|
+
|
|
62
|
+
- `timeout` - Request timeout in ms
|
|
63
|
+
- `connectTimeout` - Connection timeout in ms
|
|
64
|
+
- `retryCount` - Max retry attempts (default: 3)
|
|
65
|
+
- `retryDelay` - Base delay between retries in ms (default: 150, exponential backoff applied)
|
|
66
|
+
- `keepAlive` - Keep-alive ping interval in ms, or `{ interval, method, params }`
|
|
67
|
+
- `tls` - TLS options (or `true` for defaults when using `tcp+tls://`)
|
|
68
|
+
- `reconnect` - `{ delay: number, attempts: number }` for auto-reconnect after disconnect
|
|
69
|
+
- `handshake` - `{ method, params }` to send on connect
|
|
70
|
+
- `batch` - `true` (default), `false`, or `{ wait, batchSize }`
|
|
71
|
+
- `onUnsubscribe` - Cleanup callback when the last listener unsubscribes (receives `{ request, method, params, initialResult }`)
|
|
72
|
+
- `notificationFilter` - Filter notifications before delivery; receives `(subscriptionParams, notificationParams)` and returns `boolean`
|
|
73
|
+
- `transformInitialResult` - Transform the initial subscription result before delivery; return `undefined` to suppress
|
|
74
|
+
|
|
75
|
+
## Socket Access
|
|
76
|
+
|
|
77
|
+
Access the underlying TCP socket for advanced use cases:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// Synchronous - returns null if not yet connected
|
|
81
|
+
const socket = transport.getSocket()
|
|
82
|
+
|
|
83
|
+
// Async - connects first if needed, then returns socket
|
|
84
|
+
const socket = await transport.getSocketAsync()
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Lazy Initialization
|
|
88
|
+
|
|
89
|
+
Connections are established lazily on first use. Creating a transport is cheap - no resources are allocated until the first `request()`, `subscribe()`, or `connect()` call.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/electrum-cash/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AACrE,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/electrum-cash/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AnySchema, Schema, TcpTransport, TcpTransportOptions } from '@rpckit/core';
|
|
2
|
+
export interface ElectrumTcpOptions extends TcpTransportOptions {
|
|
3
|
+
/** Client name sent in server.version handshake (default: 'rpckit') */
|
|
4
|
+
clientName?: string;
|
|
5
|
+
/** Electrum protocol version (default: '1.6') */
|
|
6
|
+
protocolVersion?: string;
|
|
7
|
+
}
|
|
8
|
+
export type ElectrumTcpConfig = ({
|
|
9
|
+
url: string;
|
|
10
|
+
tls?: import('tls').ConnectionOptions;
|
|
11
|
+
} & ElectrumTcpOptions) | ({
|
|
12
|
+
host: string;
|
|
13
|
+
port: number;
|
|
14
|
+
tls?: boolean | import('tls').ConnectionOptions;
|
|
15
|
+
} & ElectrumTcpOptions);
|
|
16
|
+
export declare function tcp<S extends Schema = AnySchema>(url: string, options?: ElectrumTcpOptions & {
|
|
17
|
+
tls?: import('tls').ConnectionOptions;
|
|
18
|
+
}): TcpTransport<S>;
|
|
19
|
+
export declare function tcp<S extends Schema = AnySchema>(config: ElectrumTcpConfig): TcpTransport<S>;
|
|
20
|
+
//# sourceMappingURL=tcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tcp.d.ts","sourceRoot":"","sources":["../../src/electrum-cash/tcp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAET,MAAM,EACN,YAAY,EACZ,mBAAmB,EACpB,MAAM,cAAc,CAAA;AAGrB,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iDAAiD;IACjD,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,MAAM,iBAAiB,GACzB,CAAC;IACC,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,OAAO,KAAK,EAAE,iBAAiB,CAAA;CACtC,GAAG,kBAAkB,CAAC,GACvB,CAAC;IACC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,KAAK,EAAE,iBAAiB,CAAA;CAChD,GAAG,kBAAkB,CAAC,CAAA;AAE3B,wBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EAC9C,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,kBAAkB,GAAG;IAAE,GAAG,CAAC,EAAE,OAAO,KAAK,EAAE,iBAAiB,CAAA;CAAE,GACvE,YAAY,CAAC,CAAC,CAAC,CAAA;AAClB,wBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EAC9C,MAAM,EAAE,iBAAiB,GACxB,YAAY,CAAC,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { tcp as baseTcp } from '../tcp.js';
|
|
2
|
+
export function tcp(configOrUrl, options) {
|
|
3
|
+
if (typeof configOrUrl === 'string') {
|
|
4
|
+
const { clientName = 'rpckit', protocolVersion = '1.6', ...rest } = options ?? {};
|
|
5
|
+
const keepAlive = normalizeKeepAlive(rest.keepAlive);
|
|
6
|
+
return baseTcp(configOrUrl, {
|
|
7
|
+
handshake: {
|
|
8
|
+
method: 'server.version',
|
|
9
|
+
params: [clientName, protocolVersion],
|
|
10
|
+
},
|
|
11
|
+
onUnsubscribe: ({ request, method, params }) => request(method.replace('subscribe', 'unsubscribe'), ...params),
|
|
12
|
+
transformInitialResult: (_method, params, result) => [
|
|
13
|
+
...params,
|
|
14
|
+
...result,
|
|
15
|
+
],
|
|
16
|
+
notificationFilter: electrumParamsMatch,
|
|
17
|
+
...rest,
|
|
18
|
+
...(keepAlive !== undefined ? { keepAlive } : {}),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const { clientName = 'rpckit', protocolVersion = '1.6', ...rest } = configOrUrl;
|
|
22
|
+
const keepAlive = normalizeKeepAlive(rest.keepAlive);
|
|
23
|
+
return baseTcp({
|
|
24
|
+
handshake: {
|
|
25
|
+
method: 'server.version',
|
|
26
|
+
params: [clientName, protocolVersion],
|
|
27
|
+
},
|
|
28
|
+
onUnsubscribe: ({ request, method, params }) => request(method.replace('subscribe', 'unsubscribe'), ...params),
|
|
29
|
+
transformInitialResult: (_method, params, result) => [...params, ...result],
|
|
30
|
+
notificationFilter: electrumParamsMatch,
|
|
31
|
+
...rest,
|
|
32
|
+
...(keepAlive !== undefined ? { keepAlive } : {}),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function normalizeKeepAlive(ka) {
|
|
36
|
+
if (ka === undefined)
|
|
37
|
+
return undefined;
|
|
38
|
+
if (typeof ka === 'number') {
|
|
39
|
+
return { interval: ka, method: 'server.ping' };
|
|
40
|
+
}
|
|
41
|
+
const ping = { ...ka };
|
|
42
|
+
if (!ping.method)
|
|
43
|
+
ping.method = 'server.ping';
|
|
44
|
+
return ping;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Electrum protocol notification filter.
|
|
48
|
+
* Notifications include subscription params as prefix: subscribe([address]) → notification([address, status])
|
|
49
|
+
*/
|
|
50
|
+
function electrumParamsMatch(subscriptionParams, notificationParams) {
|
|
51
|
+
return subscriptionParams.every((p, i) => {
|
|
52
|
+
if (i >= notificationParams.length)
|
|
53
|
+
return false;
|
|
54
|
+
const np = notificationParams[i];
|
|
55
|
+
// Simple types can be compared directly
|
|
56
|
+
if (typeof p !== 'object' ||
|
|
57
|
+
p === null ||
|
|
58
|
+
typeof np !== 'object' ||
|
|
59
|
+
np === null) {
|
|
60
|
+
return p === np;
|
|
61
|
+
}
|
|
62
|
+
// Complex types need JSON comparison
|
|
63
|
+
return JSON.stringify(p) === JSON.stringify(np);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=tcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tcp.js","sourceRoot":"","sources":["../../src/electrum-cash/tcp.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA"}
|
package/dist/tcp.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AnySchema, type Schema, type TcpTransport, type TcpTransportConfig, type TcpTransportOptions } from '@rpckit/core';
|
|
2
|
+
export declare function tcp<S extends Schema = AnySchema>(url: string, options?: TcpTransportOptions & {
|
|
3
|
+
tls?: import('tls').ConnectionOptions;
|
|
4
|
+
}): TcpTransport<S>;
|
|
5
|
+
export declare function tcp<S extends Schema = AnySchema>(config: TcpTransportConfig): TcpTransport<S>;
|
|
6
|
+
//# sourceMappingURL=tcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tcp.d.ts","sourceRoot":"","sources":["../src/tcp.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,SAAS,EAId,KAAK,MAAM,EAEX,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EAGzB,MAAM,cAAc,CAAA;AA+crB,wBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EAC9C,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,mBAAmB,GAAG;IAAE,GAAG,CAAC,EAAE,OAAO,KAAK,EAAE,iBAAiB,CAAA;CAAE,GACxE,YAAY,CAAC,CAAC,CAAC,CAAA;AAClB,wBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,EAC9C,MAAM,EAAE,kBAAkB,GACzB,YAAY,CAAC,CAAC,CAAC,CAAA"}
|
package/dist/tcp.js
ADDED
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { createConnection as netConnect } from 'node:net';
|
|
2
|
+
import { connect as tlsConnect } from 'node:tls';
|
|
3
|
+
import { BatchScheduler, withRetry, } from '@rpckit/core';
|
|
4
|
+
function parseUrl(config) {
|
|
5
|
+
if ('url' in config) {
|
|
6
|
+
const isTls = config.url.startsWith('tcp+tls://');
|
|
7
|
+
const stripped = config.url.replace(/^tcp(\+tls)?:\/\//, '');
|
|
8
|
+
const [host, portStr] = stripped.split(':');
|
|
9
|
+
const port = portStr ? parseInt(portStr, 10) : isTls ? 50002 : 50001;
|
|
10
|
+
const tls = isTls
|
|
11
|
+
? (config.tls ?? true)
|
|
12
|
+
: false;
|
|
13
|
+
return { host, port, tls };
|
|
14
|
+
}
|
|
15
|
+
return { host: config.host, port: config.port, tls: config.tls ?? false };
|
|
16
|
+
}
|
|
17
|
+
const tcpSocketCache = new Map();
|
|
18
|
+
function getCacheKey(config) {
|
|
19
|
+
const { host, port, tls } = parseUrl(config);
|
|
20
|
+
return JSON.stringify({
|
|
21
|
+
host,
|
|
22
|
+
port,
|
|
23
|
+
tls: typeof tls === 'object' ? tls : !!tls,
|
|
24
|
+
keepAlive: config.keepAlive,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function getOrCreateTcpSocketClient(config) {
|
|
28
|
+
const cacheKey = getCacheKey(config);
|
|
29
|
+
let client = tcpSocketCache.get(cacheKey);
|
|
30
|
+
if (client) {
|
|
31
|
+
client.refCount++;
|
|
32
|
+
return client;
|
|
33
|
+
}
|
|
34
|
+
const { host, port, tls } = parseUrl(config);
|
|
35
|
+
const url = `tcp${tls ? '+tls' : ''}://${host}:${port}`;
|
|
36
|
+
let socket = null;
|
|
37
|
+
let nextId = 1;
|
|
38
|
+
let closed = false;
|
|
39
|
+
let connectPromise = null;
|
|
40
|
+
let buffer = '';
|
|
41
|
+
let _reconnectCount = 0;
|
|
42
|
+
const pending = new Map();
|
|
43
|
+
const subscriptions = new Map();
|
|
44
|
+
let keepAliveTimer = null;
|
|
45
|
+
let batchScheduler = null;
|
|
46
|
+
if (config.batch !== false) {
|
|
47
|
+
batchScheduler = new BatchScheduler(typeof config.batch === 'object' ? config.batch : {}, sendBatch);
|
|
48
|
+
}
|
|
49
|
+
function getSubscriptionKey(method, params) {
|
|
50
|
+
return `${method}:${JSON.stringify(params)}`;
|
|
51
|
+
}
|
|
52
|
+
function connect() {
|
|
53
|
+
if (connectPromise)
|
|
54
|
+
return connectPromise;
|
|
55
|
+
connectPromise = new Promise((resolve, reject) => {
|
|
56
|
+
let connectTimer;
|
|
57
|
+
if (config.connectTimeout) {
|
|
58
|
+
connectTimer = setTimeout(() => {
|
|
59
|
+
reject(new Error('Connection timeout'));
|
|
60
|
+
socket?.destroy();
|
|
61
|
+
void handleDisconnect();
|
|
62
|
+
}, config.connectTimeout);
|
|
63
|
+
}
|
|
64
|
+
const onConnect = async () => {
|
|
65
|
+
try {
|
|
66
|
+
_reconnectCount = 0;
|
|
67
|
+
if (config.handshake) {
|
|
68
|
+
const id = nextId++;
|
|
69
|
+
const req = {
|
|
70
|
+
jsonrpc: '2.0',
|
|
71
|
+
method: config.handshake.method,
|
|
72
|
+
params: config.handshake.params ?? [],
|
|
73
|
+
id,
|
|
74
|
+
};
|
|
75
|
+
await new Promise((res, rej) => {
|
|
76
|
+
pending.set(id, { resolve: () => res(), reject: rej });
|
|
77
|
+
sendRaw(req);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
startKeepAlive();
|
|
81
|
+
// Restore subscriptions after reconnect
|
|
82
|
+
if (subscriptions.size > 0) {
|
|
83
|
+
for (const [_key, entry] of subscriptions) {
|
|
84
|
+
const id = nextId++;
|
|
85
|
+
const req = {
|
|
86
|
+
jsonrpc: '2.0',
|
|
87
|
+
method: entry.method,
|
|
88
|
+
params: entry.params,
|
|
89
|
+
id,
|
|
90
|
+
};
|
|
91
|
+
sendRaw(req);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (connectTimer)
|
|
95
|
+
clearTimeout(connectTimer);
|
|
96
|
+
resolve();
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
reject(err);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
if (tls) {
|
|
103
|
+
const tlsOpts = typeof tls === 'object' ? tls : {};
|
|
104
|
+
socket = tlsConnect({ host, port, ...tlsOpts }, onConnect);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
socket = netConnect({ host, port }, onConnect);
|
|
108
|
+
}
|
|
109
|
+
socket.setEncoding('utf8');
|
|
110
|
+
socket.on('data', (chunk) => {
|
|
111
|
+
buffer += chunk;
|
|
112
|
+
const lines = buffer.split('\n');
|
|
113
|
+
// biome-ignore lint/style/noNonNullAssertion: split always returns at least one element
|
|
114
|
+
buffer = lines.pop();
|
|
115
|
+
for (const line of lines) {
|
|
116
|
+
if (!line.trim())
|
|
117
|
+
continue;
|
|
118
|
+
let msg;
|
|
119
|
+
try {
|
|
120
|
+
msg = JSON.parse(line);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const messages = Array.isArray(msg) ? msg : [msg];
|
|
126
|
+
for (const m of messages) {
|
|
127
|
+
if ('id' in m && m.id != null) {
|
|
128
|
+
const p = pending.get(m.id);
|
|
129
|
+
if (p) {
|
|
130
|
+
pending.delete(m.id);
|
|
131
|
+
if (p.timer)
|
|
132
|
+
clearTimeout(p.timer);
|
|
133
|
+
const resp = m;
|
|
134
|
+
if (resp.error)
|
|
135
|
+
p.reject(resp.error);
|
|
136
|
+
else
|
|
137
|
+
p.resolve(resp.result);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
const notif = m;
|
|
142
|
+
for (const [, entry] of subscriptions) {
|
|
143
|
+
if (entry.method === notif.method) {
|
|
144
|
+
// Apply notification filter if configured
|
|
145
|
+
if (config.notificationFilter) {
|
|
146
|
+
const notifParams = notif.params;
|
|
147
|
+
if (!config.notificationFilter(entry.params, notifParams)) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
entry.lastNotification = notif.params;
|
|
152
|
+
for (const handler of entry.listeners)
|
|
153
|
+
handler(notif.params);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
socket.on('error', (err) => {
|
|
161
|
+
if (connectTimer)
|
|
162
|
+
clearTimeout(connectTimer);
|
|
163
|
+
reject(err);
|
|
164
|
+
void handleDisconnect(err);
|
|
165
|
+
});
|
|
166
|
+
socket.on('close', () => {
|
|
167
|
+
void handleDisconnect();
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
return connectPromise;
|
|
171
|
+
}
|
|
172
|
+
async function handleDisconnect(error) {
|
|
173
|
+
stopKeepAlive();
|
|
174
|
+
connectPromise = null;
|
|
175
|
+
socket = null;
|
|
176
|
+
buffer = '';
|
|
177
|
+
// Reject all pending requests (but keep subscriptions for restore)
|
|
178
|
+
for (const [, p] of pending) {
|
|
179
|
+
if (p.timer)
|
|
180
|
+
clearTimeout(p.timer);
|
|
181
|
+
p.reject(error ?? new Error('TCP disconnected'));
|
|
182
|
+
}
|
|
183
|
+
pending.clear();
|
|
184
|
+
if (!closed &&
|
|
185
|
+
config.reconnect &&
|
|
186
|
+
_reconnectCount < config.reconnect.attempts) {
|
|
187
|
+
_reconnectCount++;
|
|
188
|
+
await new Promise((r) => setTimeout(r, config.reconnect?.delay));
|
|
189
|
+
if (!closed)
|
|
190
|
+
await connect();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function startKeepAlive() {
|
|
194
|
+
stopKeepAlive();
|
|
195
|
+
const ka = config.keepAlive;
|
|
196
|
+
if (!ka)
|
|
197
|
+
return;
|
|
198
|
+
const interval = typeof ka === 'number' ? ka : ka.interval;
|
|
199
|
+
const method = typeof ka === 'number' ? undefined : ka.method;
|
|
200
|
+
const params = typeof ka === 'number' ? [] : (ka.params ?? []);
|
|
201
|
+
if (interval > 0 && method) {
|
|
202
|
+
keepAliveTimer = setInterval(() => {
|
|
203
|
+
sendRaw({ jsonrpc: '2.0', method, params, id: nextId++ });
|
|
204
|
+
}, interval);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function stopKeepAlive() {
|
|
208
|
+
if (keepAliveTimer) {
|
|
209
|
+
clearInterval(keepAliveTimer);
|
|
210
|
+
keepAliveTimer = null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function sendRaw(request) {
|
|
214
|
+
socket?.write(`${JSON.stringify(request)}\n`);
|
|
215
|
+
}
|
|
216
|
+
async function sendBatch(requests) {
|
|
217
|
+
await connect();
|
|
218
|
+
return new Promise((resolve, reject) => {
|
|
219
|
+
const ids = new Set(requests.map((r) => r.id));
|
|
220
|
+
const results = [];
|
|
221
|
+
const timer = config.timeout
|
|
222
|
+
? setTimeout(() => {
|
|
223
|
+
for (const id of ids)
|
|
224
|
+
pending.delete(id);
|
|
225
|
+
reject(new Error('Batch timeout'));
|
|
226
|
+
}, config.timeout)
|
|
227
|
+
: undefined;
|
|
228
|
+
for (const req of requests) {
|
|
229
|
+
pending.set(req.id, {
|
|
230
|
+
resolve: (result) => {
|
|
231
|
+
results.push({ jsonrpc: '2.0', result, id: req.id });
|
|
232
|
+
ids.delete(req.id);
|
|
233
|
+
if (ids.size === 0) {
|
|
234
|
+
if (timer)
|
|
235
|
+
clearTimeout(timer);
|
|
236
|
+
resolve(results);
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
reject: (error) => {
|
|
240
|
+
for (const id of ids)
|
|
241
|
+
pending.delete(id);
|
|
242
|
+
if (timer)
|
|
243
|
+
clearTimeout(timer);
|
|
244
|
+
reject(error);
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
socket?.write(`${JSON.stringify(requests)}\n`);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
async function request(method, params = []) {
|
|
252
|
+
await connect();
|
|
253
|
+
const id = nextId++;
|
|
254
|
+
const req = { jsonrpc: '2.0', method, params, id };
|
|
255
|
+
if (batchScheduler) {
|
|
256
|
+
return batchScheduler.enqueue(req);
|
|
257
|
+
}
|
|
258
|
+
return new Promise((resolve, reject) => {
|
|
259
|
+
const timer = config.timeout
|
|
260
|
+
? setTimeout(() => {
|
|
261
|
+
pending.delete(id);
|
|
262
|
+
reject(new Error('Request timeout'));
|
|
263
|
+
}, config.timeout)
|
|
264
|
+
: undefined;
|
|
265
|
+
pending.set(id, { resolve, reject, timer });
|
|
266
|
+
sendRaw(req);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
async function subscribe(method, params, onData) {
|
|
270
|
+
await connect();
|
|
271
|
+
const subKey = getSubscriptionKey(method, params);
|
|
272
|
+
let entry = subscriptions.get(subKey);
|
|
273
|
+
if (entry) {
|
|
274
|
+
entry.listeners.add(onData);
|
|
275
|
+
const hasNotification = entry.lastNotification !== undefined;
|
|
276
|
+
return {
|
|
277
|
+
initialResult: hasNotification
|
|
278
|
+
? entry.lastNotification
|
|
279
|
+
: entry.initialResult,
|
|
280
|
+
unsubscribe: () => {
|
|
281
|
+
entry?.listeners.delete(onData);
|
|
282
|
+
if (entry?.listeners.size === 0) {
|
|
283
|
+
subscriptions.delete(subKey);
|
|
284
|
+
return true; // was the last listener
|
|
285
|
+
}
|
|
286
|
+
return false; // other listeners remain
|
|
287
|
+
},
|
|
288
|
+
fromNotification: hasNotification,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
const id = nextId++;
|
|
292
|
+
const req = { jsonrpc: '2.0', method, params, id };
|
|
293
|
+
const initialResult = await new Promise((resolve, reject) => {
|
|
294
|
+
const timer = config.timeout
|
|
295
|
+
? setTimeout(() => {
|
|
296
|
+
pending.delete(id);
|
|
297
|
+
reject(new Error('Request timeout'));
|
|
298
|
+
}, config.timeout)
|
|
299
|
+
: undefined;
|
|
300
|
+
pending.set(id, { resolve, reject, timer });
|
|
301
|
+
sendRaw(req);
|
|
302
|
+
});
|
|
303
|
+
entry = {
|
|
304
|
+
method,
|
|
305
|
+
params,
|
|
306
|
+
listeners: new Set([onData]),
|
|
307
|
+
initialResult,
|
|
308
|
+
lastNotification: undefined,
|
|
309
|
+
};
|
|
310
|
+
subscriptions.set(subKey, entry);
|
|
311
|
+
return {
|
|
312
|
+
initialResult,
|
|
313
|
+
unsubscribe: () => {
|
|
314
|
+
entry?.listeners.delete(onData);
|
|
315
|
+
if (entry?.listeners.size === 0) {
|
|
316
|
+
subscriptions.delete(subKey);
|
|
317
|
+
return true; // was the last listener
|
|
318
|
+
}
|
|
319
|
+
return false; // other listeners remain
|
|
320
|
+
},
|
|
321
|
+
fromNotification: false,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
async function close() {
|
|
325
|
+
closed = true;
|
|
326
|
+
stopKeepAlive();
|
|
327
|
+
if (batchScheduler)
|
|
328
|
+
await batchScheduler.flush();
|
|
329
|
+
for (const [, p] of pending) {
|
|
330
|
+
if (p.timer)
|
|
331
|
+
clearTimeout(p.timer);
|
|
332
|
+
p.reject(new Error('Transport closed'));
|
|
333
|
+
}
|
|
334
|
+
pending.clear();
|
|
335
|
+
subscriptions.clear();
|
|
336
|
+
socket?.destroy();
|
|
337
|
+
socket = null;
|
|
338
|
+
connectPromise = null;
|
|
339
|
+
tcpSocketCache.delete(cacheKey);
|
|
340
|
+
}
|
|
341
|
+
client = {
|
|
342
|
+
refCount: 1,
|
|
343
|
+
get socket() {
|
|
344
|
+
return socket;
|
|
345
|
+
},
|
|
346
|
+
nextId,
|
|
347
|
+
connectPromise,
|
|
348
|
+
closed,
|
|
349
|
+
buffer,
|
|
350
|
+
pending,
|
|
351
|
+
subscriptions,
|
|
352
|
+
keepAliveTimer,
|
|
353
|
+
batchScheduler,
|
|
354
|
+
connect,
|
|
355
|
+
sendRaw,
|
|
356
|
+
request,
|
|
357
|
+
subscribe,
|
|
358
|
+
close,
|
|
359
|
+
url,
|
|
360
|
+
};
|
|
361
|
+
tcpSocketCache.set(cacheKey, client);
|
|
362
|
+
return client;
|
|
363
|
+
}
|
|
364
|
+
export function tcp(configOrUrl, options) {
|
|
365
|
+
const config = typeof configOrUrl === 'string'
|
|
366
|
+
? { ...options, url: configOrUrl }
|
|
367
|
+
: configOrUrl;
|
|
368
|
+
// Compute URL without creating client
|
|
369
|
+
const { host, port, tls } = parseUrl(config);
|
|
370
|
+
const url = `tcp${tls ? '+tls' : ''}://${host}:${port}`;
|
|
371
|
+
// Lazy client initialization - only created on first use
|
|
372
|
+
let client = null;
|
|
373
|
+
const getClient = () => {
|
|
374
|
+
if (!client)
|
|
375
|
+
client = getOrCreateTcpSocketClient(config);
|
|
376
|
+
return client;
|
|
377
|
+
};
|
|
378
|
+
const retryOpts = {
|
|
379
|
+
retryCount: config.retryCount,
|
|
380
|
+
retryDelay: config.retryDelay,
|
|
381
|
+
};
|
|
382
|
+
const self = {
|
|
383
|
+
url,
|
|
384
|
+
connect: () => withRetry(() => getClient().connect(), retryOpts),
|
|
385
|
+
request: (method, ...params) => withRetry(() => getClient().request(method, params), retryOpts),
|
|
386
|
+
async subscribe(method, ...args) {
|
|
387
|
+
const onData = args.pop();
|
|
388
|
+
const params = args;
|
|
389
|
+
const { initialResult, unsubscribe, fromNotification } = await withRetry(() => getClient().subscribe(method, params, onData), retryOpts);
|
|
390
|
+
// Deliver initial result if we got one
|
|
391
|
+
if (initialResult !== undefined) {
|
|
392
|
+
if (fromNotification) {
|
|
393
|
+
// Reused subscription: lastNotification is already in notification format
|
|
394
|
+
onData(initialResult);
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
const transformed = config.transformInitialResult
|
|
398
|
+
? config.transformInitialResult(method, params, [initialResult])
|
|
399
|
+
: initialResult;
|
|
400
|
+
// Allow transformInitialResult to return undefined to suppress delivery
|
|
401
|
+
if (transformed !== undefined) {
|
|
402
|
+
onData(transformed);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
const unsub = async (cleanup) => {
|
|
407
|
+
const wasLastListener = unsubscribe();
|
|
408
|
+
// Only call onUnsubscribe when the last listener is removed
|
|
409
|
+
if (wasLastListener) {
|
|
410
|
+
const fn = cleanup ?? config.onUnsubscribe;
|
|
411
|
+
if (fn) {
|
|
412
|
+
await fn({ request: self.request, method, params, initialResult });
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
return unsub;
|
|
417
|
+
},
|
|
418
|
+
async close() {
|
|
419
|
+
if (!client)
|
|
420
|
+
return;
|
|
421
|
+
client.refCount--;
|
|
422
|
+
if (client.refCount <= 0) {
|
|
423
|
+
await client.close();
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
getSocket() {
|
|
427
|
+
return client?.socket ?? null;
|
|
428
|
+
},
|
|
429
|
+
async getSocketAsync() {
|
|
430
|
+
await getClient().connect();
|
|
431
|
+
const c = getClient();
|
|
432
|
+
if (!c.socket)
|
|
433
|
+
throw new Error('TCP socket not connected');
|
|
434
|
+
return c.socket;
|
|
435
|
+
},
|
|
436
|
+
};
|
|
437
|
+
return self;
|
|
438
|
+
}
|
|
439
|
+
//# sourceMappingURL=tcp.js.map
|
package/dist/tcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tcp.js","sourceRoot":"","sources":["../src/tcp.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rpckit/tcp",
|
|
3
|
+
"version": "0.9.99",
|
|
4
|
+
"description": "TCP transport for rpckit (Node.js) with TLS support",
|
|
5
|
+
"author": "mainnet_pat",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./electrum-cash": {
|
|
17
|
+
"types": "./dist/electrum-cash/index.d.ts",
|
|
18
|
+
"default": "./dist/electrum-cash/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"json-rpc",
|
|
26
|
+
"rpc",
|
|
27
|
+
"tcp",
|
|
28
|
+
"electrum",
|
|
29
|
+
"electrum-cash",
|
|
30
|
+
"typescript"
|
|
31
|
+
],
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/mainnet-pat/rpckit.git",
|
|
35
|
+
"directory": "packages/tcp"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://rpckit.dev",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/mainnet-pat/rpckit/issues"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@rpckit/core": "*"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"typescript": "^5.7.0"
|
|
49
|
+
}
|
|
50
|
+
}
|