@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 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,3 @@
1
+ export type { ElectrumTcpConfig, ElectrumTcpOptions } from './tcp.js';
2
+ export { tcp } from './tcp.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,2 @@
1
+ export { tcp } from './tcp.js';
2
+ //# sourceMappingURL=index.js.map
@@ -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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"}
@@ -0,0 +1,2 @@
1
+ export { tcp } from './tcp.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -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,2 @@
1
+ export { tcp } from './tcp.js';
2
+ //# sourceMappingURL=index.js.map
@@ -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
@@ -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
+ }