@rpckit/core 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.
Files changed (58) hide show
  1. package/README.md +131 -0
  2. package/dist/batch.d.ts +17 -0
  3. package/dist/batch.d.ts.map +1 -0
  4. package/dist/batch.js +59 -0
  5. package/dist/batch.js.map +1 -0
  6. package/dist/electrum-cash/index.d.ts +3 -0
  7. package/dist/electrum-cash/index.d.ts.map +1 -0
  8. package/dist/electrum-cash/index.js +2 -0
  9. package/dist/electrum-cash/index.js.map +1 -0
  10. package/dist/electrum-cash/parse.d.ts +27 -0
  11. package/dist/electrum-cash/parse.d.ts.map +1 -0
  12. package/dist/electrum-cash/parse.js +32 -0
  13. package/dist/electrum-cash/parse.js.map +1 -0
  14. package/dist/electrum-cash/schema.d.ts +517 -0
  15. package/dist/electrum-cash/schema.d.ts.map +1 -0
  16. package/dist/electrum-cash/schema.js +2 -0
  17. package/dist/electrum-cash/schema.js.map +1 -0
  18. package/dist/ethereum/index.d.ts +3 -0
  19. package/dist/ethereum/index.d.ts.map +1 -0
  20. package/dist/ethereum/index.js +2 -0
  21. package/dist/ethereum/index.js.map +1 -0
  22. package/dist/ethereum/parse.d.ts +22 -0
  23. package/dist/ethereum/parse.d.ts.map +1 -0
  24. package/dist/ethereum/parse.js +26 -0
  25. package/dist/ethereum/parse.js.map +1 -0
  26. package/dist/ethereum/schema.d.ts +530 -0
  27. package/dist/ethereum/schema.d.ts.map +1 -0
  28. package/dist/ethereum/schema.js +8 -0
  29. package/dist/ethereum/schema.js.map +1 -0
  30. package/dist/index.d.ts +10 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +4 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/parse.d.ts +74 -0
  35. package/dist/parse.d.ts.map +1 -0
  36. package/dist/parse.js +310 -0
  37. package/dist/parse.js.map +1 -0
  38. package/dist/protocol.d.ts +22 -0
  39. package/dist/protocol.d.ts.map +1 -0
  40. package/dist/protocol.js +2 -0
  41. package/dist/protocol.js.map +1 -0
  42. package/dist/retry.d.ts +9 -0
  43. package/dist/retry.d.ts.map +1 -0
  44. package/dist/retry.js +26 -0
  45. package/dist/retry.js.map +1 -0
  46. package/dist/schema-utils.d.ts +28 -0
  47. package/dist/schema-utils.d.ts.map +1 -0
  48. package/dist/schema-utils.js +2 -0
  49. package/dist/schema-utils.js.map +1 -0
  50. package/dist/schema.d.ts +32 -0
  51. package/dist/schema.d.ts.map +1 -0
  52. package/dist/schema.js +2 -0
  53. package/dist/schema.js.map +1 -0
  54. package/dist/types.d.ts +187 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +2 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +51 -0
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # @rpckit/core
2
+
3
+ Core types, schema utilities, and batch scheduler for communication with JSON-RPC servers.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @rpckit/core
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import type { Schema, Transport } from '@rpckit/core'
15
+ import { webSocket } from '@rpckit/websocket'
16
+
17
+ type MySchema = {
18
+ requests: [
19
+ { method: 'getblockcount'; params: []; return: number }
20
+ ]
21
+ subscriptions: []
22
+ }
23
+
24
+ const transport = webSocket<MySchema>('wss://example.com')
25
+ const blockCount = await transport.request('getblockcount')
26
+ await transport.close()
27
+ ```
28
+
29
+ ## Electrum Cash Subpackage
30
+
31
+ Electrum Cash schema types and a pre-configured `parse()` variant are available under the `electrum-cash` subpath:
32
+
33
+ ```typescript
34
+ import type { ElectrumCashSchema } from '@rpckit/core/electrum-cash'
35
+ import { parse } from '@rpckit/core/electrum-cash'
36
+
37
+ const transport = await parse('wss://electrum.example.com')
38
+ ```
39
+
40
+ ## Ethereum Subpackage
41
+
42
+ Ethereum schema types and a pre-configured `parse()` variant are available under the `ethereum` subpath:
43
+
44
+ ```typescript
45
+ import type { EthereumSchema } from '@rpckit/core/ethereum'
46
+ import { parse } from '@rpckit/core/ethereum'
47
+
48
+ const transport = await parse('wss://ethereum-rpc.publicnode.com')
49
+ ```
50
+
51
+ ## Parse Utility
52
+
53
+ Create transports from one-liner configuration strings:
54
+
55
+ ```typescript
56
+ import { parse } from '@rpckit/core'
57
+
58
+ // Simple transports (uses base, protocol-agnostic packages)
59
+ const ws = await parse('wss://example.com:50004')
60
+ const tcp = await parse('tcp+tls://example.com:50002?timeout=10000')
61
+
62
+ // With options
63
+ const batched = await parse('wss://example.com?batchSize=10&batchWait=50')
64
+
65
+ // Fallback with ranking
66
+ const fb = await parse('fallback(wss://a.com,tcp://b.com)?rank=true')
67
+
68
+ // Cluster with quorum
69
+ const cl = await parse('cluster(2,ws://1.com,ws://2.com,ws://3.com)')
70
+
71
+ // Nested
72
+ const nested = await parse('fallback(wss://primary.com,cluster(2,ws://1.com,ws://2.com,ws://3.com))')
73
+ ```
74
+
75
+ ### createParse
76
+
77
+ Create a custom `parse` function that uses different packages for transport creation:
78
+
79
+ ```typescript
80
+ import { createParse } from '@rpckit/core'
81
+
82
+ // Use electrum-cash variants for all transports
83
+ const electrumParse = createParse({
84
+ websocket: '@rpckit/websocket/electrum-cash',
85
+ tcp: '@rpckit/tcp/electrum-cash',
86
+ http: '@rpckit/http/electrum-cash',
87
+ })
88
+
89
+ const transport = await electrumParse('wss://electrum.example.com')
90
+ ```
91
+
92
+ A pre-built Electrum Cash parse is available at `@rpckit/core/electrum-cash`.
93
+
94
+ ### createParseSync
95
+
96
+ Create a synchronous `parse` function using pre-imported factory functions. Unlike `createParse` which uses dynamic imports, this variant accepts already-loaded factories:
97
+
98
+ ```typescript
99
+ import { createParseSync } from '@rpckit/core'
100
+ import { webSocket } from '@rpckit/websocket/electrum-cash'
101
+ import { fallback } from '@rpckit/fallback'
102
+
103
+ const parseSync = createParseSync({ webSocket, fallback })
104
+ const transport = parseSync('fallback(wss://a.com,wss://b.com)?eagerConnect=true')
105
+ ```
106
+
107
+ Supported schemes: `wss://`, `ws://`, `tcp://`, `tcp+tls://`, `http://`, `https://`
108
+
109
+ Supported options: `timeout`, `retryCount`, `retryDelay`, `keepAlive`, `batch`, `batchSize`, `batchWait`, `rank`, `eagerConnect`
110
+
111
+ ## Exports
112
+
113
+ ### Main (`@rpckit/core`)
114
+
115
+ - `BatchScheduler` - Request batching utility
116
+ - `parse` - One-liner transport configuration parser
117
+ - `createParse` - Factory for custom parse functions with overridden package maps
118
+ - `createParseSync` - Synchronous factory using pre-imported transport functions
119
+ - `withRetry` - Async retry utility with exponential backoff
120
+ - `Transport` - Transport interface for implementing custom transports
121
+ - Type utilities: `ExtractReturn`, `ExtractParams`, `ExtractMethod`, `FilterMethods`, `OverrideRequests`, `PackageMap`, `FactoryMap`, etc.
122
+
123
+ ### Electrum Cash (`@rpckit/core/electrum-cash`)
124
+
125
+ - `parse` - Pre-configured parse using Electrum Cash transport variants
126
+ - `ElectrumCashSchema` - Type definitions for Electrum Cash protocol (v1.5 and v1.6)
127
+
128
+ ### Ethereum (`@rpckit/core/ethereum`)
129
+
130
+ - `parse` - Pre-configured parse using Ethereum transport variants
131
+ - `EthereumSchema` - Type definitions for Ethereum JSON-RPC (EIP-1474 standard methods)
@@ -0,0 +1,17 @@
1
+ import type { RpcRequest, RpcResponse } from './protocol.js';
2
+ import type { BatchConfig } from './types.js';
3
+ export interface BatchSchedulerOptions extends BatchConfig {
4
+ /** Return RPC errors as results instead of throwing (default: false) */
5
+ raw?: boolean;
6
+ }
7
+ export declare class BatchScheduler {
8
+ private queue;
9
+ private timer;
10
+ private config;
11
+ private raw;
12
+ private send;
13
+ constructor(config: BatchSchedulerOptions, send: (requests: RpcRequest[]) => Promise<RpcResponse[]>);
14
+ enqueue(request: RpcRequest): Promise<unknown>;
15
+ flush(): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAQ7C,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD,wEAAwE;IACxE,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,KAAK,CAA6C;IAC1D,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,IAAI,CAAoD;gBAG9D,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC;IAO1D,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAYxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAsC7B"}
package/dist/batch.js ADDED
@@ -0,0 +1,59 @@
1
+ export class BatchScheduler {
2
+ queue = [];
3
+ timer = null;
4
+ config;
5
+ raw;
6
+ send;
7
+ constructor(config, send) {
8
+ this.config = { batchSize: config.batchSize ?? 10, wait: config.wait ?? 0 };
9
+ this.raw = config.raw ?? false;
10
+ this.send = send;
11
+ }
12
+ enqueue(request) {
13
+ return new Promise((resolve, reject) => {
14
+ this.queue.push({ request, resolve, reject });
15
+ if (this.queue.length >= this.config.batchSize) {
16
+ this.flush();
17
+ }
18
+ else if (!this.timer) {
19
+ this.timer = setTimeout(() => this.flush(), this.config.wait);
20
+ }
21
+ });
22
+ }
23
+ async flush() {
24
+ if (this.timer) {
25
+ clearTimeout(this.timer);
26
+ this.timer = null;
27
+ }
28
+ if (this.queue.length === 0)
29
+ return;
30
+ const batch = this.queue.splice(0);
31
+ try {
32
+ const responses = await this.send(batch.map((p) => p.request));
33
+ const byId = new Map(responses.map((r) => [r.id, r]));
34
+ for (const pending of batch) {
35
+ const response = byId.get(pending.request.id);
36
+ if (!response) {
37
+ pending.reject(new Error(`No response for request id ${pending.request.id}, try reducing batch size`));
38
+ }
39
+ else if (response.error) {
40
+ if (this.raw) {
41
+ pending.resolve(response);
42
+ }
43
+ else {
44
+ pending.reject(response.error);
45
+ }
46
+ }
47
+ else {
48
+ pending.resolve(this.raw ? response : response.result);
49
+ }
50
+ }
51
+ }
52
+ catch (error) {
53
+ for (const pending of batch) {
54
+ pending.reject(error);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ //# sourceMappingURL=batch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.js","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { parse } from './parse.js';
2
+ export type { ElectrumCashSchema, ElectrumCashSchema_1_5_3, ElectrumCashSchema_1_6_0, } from './schema.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,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,YAAY,EACV,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,aAAa,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { parse } from './parse.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/electrum-cash/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Parse a transport one-liner string into a Transport with Electrum Cash defaults.
3
+ *
4
+ * Leaf transports (websocket, tcp, http) are loaded from their `electrum-cash`
5
+ * subpath variants, which apply protocol-specific defaults:
6
+ * - Handshake: `server.version` with `['rpckit', '1.6']`
7
+ * - KeepAlive: `server.ping` method when interval is specified
8
+ * - Unsubscribe: `method.replace('subscribe', 'unsubscribe')`
9
+ * - HTTP headers: `server.version` header
10
+ *
11
+ * Use `clientName` to override the client name in the handshake (default: `'rpckit'`).
12
+ * Use `protocolVersion` to override the protocol version (default: `'1.6'`).
13
+ *
14
+ * Meta-transports (fallback, cluster) are unchanged.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { parse } from '@rpckit/core/electrum-cash'
19
+ *
20
+ * const ws = await parse('wss://electrum.example.com')
21
+ * const tcp = await parse('tcp+tls://electrum.example.com:50002?timeout=10000')
22
+ * const custom = await parse('wss://electrum.example.com?clientName=myapp')
23
+ * const fb = await parse('fallback(wss://a.com,tcp://b.com:50001)')
24
+ * ```
25
+ */
26
+ export declare const parse: <S extends import("../schema.js").Schema = import("../schema.js").AnySchema>(input: string) => Promise<import("../types.js").Transport<S>>;
27
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/electrum-cash/parse.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,KAAK,4IAIhB,CAAA"}
@@ -0,0 +1,32 @@
1
+ import { createParse } from '../parse.js';
2
+ /**
3
+ * Parse a transport one-liner string into a Transport with Electrum Cash defaults.
4
+ *
5
+ * Leaf transports (websocket, tcp, http) are loaded from their `electrum-cash`
6
+ * subpath variants, which apply protocol-specific defaults:
7
+ * - Handshake: `server.version` with `['rpckit', '1.6']`
8
+ * - KeepAlive: `server.ping` method when interval is specified
9
+ * - Unsubscribe: `method.replace('subscribe', 'unsubscribe')`
10
+ * - HTTP headers: `server.version` header
11
+ *
12
+ * Use `clientName` to override the client name in the handshake (default: `'rpckit'`).
13
+ * Use `protocolVersion` to override the protocol version (default: `'1.6'`).
14
+ *
15
+ * Meta-transports (fallback, cluster) are unchanged.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { parse } from '@rpckit/core/electrum-cash'
20
+ *
21
+ * const ws = await parse('wss://electrum.example.com')
22
+ * const tcp = await parse('tcp+tls://electrum.example.com:50002?timeout=10000')
23
+ * const custom = await parse('wss://electrum.example.com?clientName=myapp')
24
+ * const fb = await parse('fallback(wss://a.com,tcp://b.com:50001)')
25
+ * ```
26
+ */
27
+ export const parse = createParse({
28
+ websocket: '@rpckit/websocket/electrum-cash',
29
+ tcp: '@rpckit/tcp/electrum-cash',
30
+ http: '@rpckit/http/electrum-cash',
31
+ });
32
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/electrum-cash/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,CAAC;IAC/B,SAAS,EAAE,iCAAiC;IAC5C,GAAG,EAAE,2BAA2B;IAChC,IAAI,EAAE,4BAA4B;CACnC,CAAC,CAAA"}