@blackglory/estore-js 0.5.2 → 0.6.0

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 CHANGED
@@ -24,23 +24,34 @@ export class EStoreClient {
24
24
 
25
25
  close(): Promise<void>
26
26
 
27
- getNamespaceStats(namespace: string, timeout?: number): Promise<INamespaceStats>
27
+ getNamespaceStats(
28
+ namespace: string
29
+ , signal?: AbortSignal
30
+ ): Promise<INamespaceStats>
28
31
 
29
- getAllNamespaces(timeout?: number): Promise<string[]>
32
+ getAllNamespaces(signal?: AbortSignal): Promise<string[]>
30
33
 
31
- getAllItemIds(namespace: string, timeout?: number): Promise<string[]>
34
+ getAllItemIds(namespace: string, signal?: AbortSignal): Promise<string[]>
32
35
 
33
36
  getAllEvents(
34
37
  namespace: string
35
38
  , itemId: string
36
- , timeout?: number
39
+ , signal?: AbortSignal
37
40
  ): Promise<JSONValue[]>
38
41
 
39
- clearItemsByNamespace(namespace: string, timeout?: number): Promise<void>
42
+ clearItemsByNamespace(namespace: string, signal?: AbortSignal): Promise<void>
40
43
 
41
- removeItem(namespace: string, itemId: string, timeout?: number): Promise<void>
44
+ removeItem(
45
+ namespace: string
46
+ , itemId: string
47
+ , signal?: AbortSignal
48
+ ): Promise<void>
42
49
 
43
- getItemSize(namespace: string, itemId: string, timeout?: number): Promise<number>
50
+ getItemSize(
51
+ namespace: string
52
+ , itemId: string
53
+ , signal?: AbortSignal
54
+ ): Promise<number>
44
55
 
45
56
  /**
46
57
  * @param nextEventIndex 如果指定, 则会在eventIndex不等于下一个index时抛出EventIndexConflict错误.
@@ -51,14 +62,14 @@ export class EStoreClient {
51
62
  , itemId: string
52
63
  , event: JSONValue
53
64
  , nextEventIndex?: number
54
- , timeout?: number
65
+ , signal?: ABortSignal
55
66
  ): Promise<void>
56
67
 
57
68
  getEvent(
58
69
  namespace: string
59
70
  , itemId: string
60
71
  , index: number
61
- , timeout?: number
72
+ , signal?: AbortSignal
62
73
  ): Promise<JSONValue | null>
63
74
  }
64
75
  ```
package/lib/contract.d.ts CHANGED
@@ -12,7 +12,16 @@ export interface IAPI {
12
12
  clearItemsByNamespace(namespace: string): null;
13
13
  removeItem(namespace: string, itemId: string): null;
14
14
  getItemSize(namespace: string, itemId: string): number;
15
- appendEvent(namespace: string, itemId: string, event: JSONValue, nextEventIndex?: number): null;
15
+ appendEvent(...args: [
16
+ namespace: string,
17
+ itemId: string,
18
+ event: JSONValue
19
+ ] | [
20
+ namespace: string,
21
+ itemId: string,
22
+ event: JSONValue,
23
+ nextEventIndex: number
24
+ ]): null;
16
25
  getEvent(namespace: string, itemId: string, eventIndex: number): JSONValue | null;
17
26
  }
18
27
  export declare class EventIndexConflict extends CustomError {
@@ -1 +1 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAA;AAyCvC,MAAM,OAAO,kBAAmB,SAAQ,WAAW;CAAG"}
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAA;AAgDvC,MAAM,OAAO,kBAAmB,SAAQ,WAAW;CAAG"}
@@ -14,14 +14,14 @@ export declare class EStoreClient {
14
14
  static create(options: IEStoreClientOptions): Promise<EStoreClient>;
15
15
  private constructor();
16
16
  close(): Promise<void>;
17
- getNamespaceStats(namespace: string, timeout?: number): Promise<INamespaceStats>;
18
- getAllNamespaces(timeout?: number): Promise<string[]>;
19
- getAllItemIds(namespace: string, timeout?: number): Promise<string[]>;
20
- getAllEvents(namespace: string, itemId: string, timeout?: number): Promise<JSONValue[]>;
21
- clearItemsByNamespace(namespace: string, timeout?: number): Promise<void>;
22
- removeItem(namespace: string, itemId: string, timeout?: number): Promise<void>;
23
- getItemSize(namespace: string, itemId: string, timeout?: number): Promise<number>;
24
- appendEvent(namespace: string, itemId: string, event: JSONValue, nextEventIndex?: number, timeout?: number): Promise<void>;
25
- getEvent(namespace: string, itemId: string, index: number, timeout?: number): Promise<JSONValue | null>;
17
+ getNamespaceStats(namespace: string, signal?: AbortSignal): Promise<INamespaceStats>;
18
+ getAllNamespaces(signal?: AbortSignal): Promise<string[]>;
19
+ getAllItemIds(namespace: string, signal?: AbortSignal): Promise<string[]>;
20
+ getAllEvents(namespace: string, itemId: string, signal?: AbortSignal): Promise<JSONValue[]>;
21
+ clearItemsByNamespace(namespace: string, signal?: AbortSignal): Promise<void>;
22
+ removeItem(namespace: string, itemId: string, signal?: AbortSignal): Promise<void>;
23
+ getItemSize(namespace: string, itemId: string, signal?: AbortSignal): Promise<number>;
24
+ appendEvent(namespace: string, itemId: string, event: JSONValue, nextEventIndex?: number, signal?: AbortSignal): Promise<void>;
25
+ getEvent(namespace: string, itemId: string, index: number, signal?: AbortSignal): Promise<JSONValue | null>;
26
26
  private withTimeout;
27
27
  }
@@ -1,61 +1,57 @@
1
1
  import { createRPCClient } from "./utils/rpc-client.js";
2
- import { timeoutSignal, withAbortSignal } from 'extra-abort';
3
- import { isUndefined } from '@blackglory/prelude';
2
+ import { raceAbortSignals, timeoutSignal } from 'extra-abort';
3
+ import { isntUndefined, isUndefined } from '@blackglory/prelude';
4
4
  export { EventIndexConflict } from './contract.js';
5
5
  export class EStoreClient {
6
+ static async create(options) {
7
+ const { client, close } = await createRPCClient(options.server, options.retryIntervalForReconnection);
8
+ return new EStoreClient(client, close, options.timeout);
9
+ }
6
10
  constructor(client, closeClients, timeout) {
7
11
  this.client = client;
8
12
  this.closeClients = closeClients;
9
13
  this.timeout = timeout;
10
14
  }
11
- static async create(options) {
12
- const { client, close } = await createRPCClient(options.server, options.retryIntervalForReconnection);
13
- return new EStoreClient(client, close, options.timeout);
14
- }
15
15
  async close() {
16
16
  await this.closeClients();
17
17
  }
18
- async getNamespaceStats(namespace, timeout) {
19
- return await this.withTimeout(() => this.client.getNamespaceStats(namespace), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
20
- }
21
- async getAllNamespaces(timeout) {
22
- return await this.withTimeout(() => this.client.getAllNamespaces(), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
18
+ async getNamespaceStats(namespace, signal) {
19
+ return await this.client.getNamespaceStats(namespace, this.withTimeout(signal));
23
20
  }
24
- async getAllItemIds(namespace, timeout) {
25
- return await this.withTimeout(() => this.client.getAllItemIds(namespace), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
21
+ async getAllNamespaces(signal) {
22
+ return await this.client.getAllNamespaces(this.withTimeout(signal));
26
23
  }
27
- async getAllEvents(namespace, itemId, timeout) {
28
- return await this.withTimeout(() => this.client.getAllEvents(namespace, itemId), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
24
+ async getAllItemIds(namespace, signal) {
25
+ return await this.client.getAllItemIds(namespace, this.withTimeout(signal));
29
26
  }
30
- async clearItemsByNamespace(namespace, timeout) {
31
- await this.withTimeout(() => this.client.clearItemsByNamespace(namespace), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
27
+ async getAllEvents(namespace, itemId, signal) {
28
+ return await this.client.getAllEvents(namespace, itemId, this.withTimeout(signal));
32
29
  }
33
- async removeItem(namespace, itemId, timeout) {
34
- await this.withTimeout(() => this.client.removeItem(namespace, itemId), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
30
+ async clearItemsByNamespace(namespace, signal) {
31
+ await this.client.clearItemsByNamespace(namespace, this.withTimeout(signal));
35
32
  }
36
- async getItemSize(namespace, itemId, timeout) {
37
- return await this.withTimeout(() => this.client.getItemSize(namespace, itemId), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
33
+ async removeItem(namespace, itemId, signal) {
34
+ await this.client.removeItem(namespace, itemId, this.withTimeout(signal));
38
35
  }
39
- async appendEvent(namespace, itemId, event, nextEventIndex, timeout) {
40
- await this.withTimeout(() => {
41
- if (isUndefined(nextEventIndex)) {
42
- return this.client.appendEvent(namespace, itemId, event);
43
- }
44
- else {
45
- return this.client.appendEvent(namespace, itemId, event, nextEventIndex);
46
- }
47
- }, timeout !== null && timeout !== void 0 ? timeout : this.timeout);
36
+ async getItemSize(namespace, itemId, signal) {
37
+ return await this.client.getItemSize(namespace, itemId, this.withTimeout(signal));
48
38
  }
49
- async getEvent(namespace, itemId, index, timeout) {
50
- return await this.withTimeout(() => this.client.getEvent(namespace, itemId, index), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
51
- }
52
- async withTimeout(fn, timeout = this.timeout) {
53
- if (timeout) {
54
- return await withAbortSignal(timeoutSignal(timeout), fn);
39
+ async appendEvent(namespace, itemId, event, nextEventIndex, signal) {
40
+ if (isUndefined(nextEventIndex)) {
41
+ await this.client.appendEvent(namespace, itemId, event, this.withTimeout(signal));
55
42
  }
56
43
  else {
57
- return await fn();
44
+ await this.client.appendEvent(namespace, itemId, event, nextEventIndex, this.withTimeout(signal));
58
45
  }
59
46
  }
47
+ async getEvent(namespace, itemId, index, signal) {
48
+ return await this.client.getEvent(namespace, itemId, index, this.withTimeout(signal));
49
+ }
50
+ withTimeout(signal) {
51
+ return raceAbortSignals([
52
+ isntUndefined(this.timeout) && timeoutSignal(this.timeout),
53
+ signal
54
+ ]);
55
+ }
60
56
  }
61
57
  //# sourceMappingURL=estore-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"estore-client.js","sourceRoot":"","sources":["../src/estore-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"estore-client.js","sourceRoot":"","sources":["../src/estore-client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@blackglory/estore-js",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "files": [
7
- "lib"
7
+ "lib",
8
+ "src"
8
9
  ],
9
10
  "type": "module",
10
11
  "main": "lib/index.js",
@@ -17,22 +18,20 @@
17
18
  "license": "MIT",
18
19
  "sideEffects": false,
19
20
  "engines": {
20
- "node": ">=16"
21
+ "node": ">=22"
21
22
  },
22
23
  "scripts": {
23
24
  "prepare": "ts-patch install -s",
24
- "lint": "eslint --ext .js,.jsx,.ts,.tsx --quiet src __tests__",
25
- "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --no-cache --config jest.config.cjs",
26
- "test:debug": "cross-env NODE_OPTIONS=--experimental-vm-modules node --inspect-brk node_modules/.bin/jest --runInBand jest.config.cjs",
27
- "test:coverage": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage --config jest.config.cjs",
25
+ "lint": "eslint --quiet src __tests__",
26
+ "test": "vitest --run",
28
27
  "prepublishOnly": "run-s prepare clean build",
29
28
  "clean": "rimraf lib",
30
29
  "build": "tsc --project tsconfig.build.json",
31
30
  "docker:test": "run-s docker:test:clean docker:test:build docker:test:run docker:test:clean",
32
31
  "docker:coverage": "run-s docker:test:clean docker:test:build docker:test:coverage docker:test:clean",
33
- "docker:test:build": "docker-compose --project-name estore-js --file docker-compose.test.yml build",
34
- "docker:test:run": "docker-compose --project-name estore-js --file docker-compose.test.yml run --rm test",
35
- "docker:test:clean": "docker-compose --project-name estore-js --file docker-compose.test.yml down",
32
+ "docker:test:build": "docker compose --project-name estore-js --file docker-compose.test.yml build",
33
+ "docker:test:run": "docker compose --project-name estore-js --file docker-compose.test.yml run --no-TTY --rm test",
34
+ "docker:test:clean": "docker compose --project-name estore-js --file docker-compose.test.yml down",
36
35
  "release": "standard-version"
37
36
  },
38
37
  "husky": {
@@ -42,38 +41,36 @@
42
41
  }
43
42
  },
44
43
  "devDependencies": {
45
- "@blackglory/jest-resolver": "^0.3.0",
46
- "@commitlint/cli": "^17.5.1",
47
- "@commitlint/config-conventional": "^17.4.4",
48
- "@types/jest": "^29.5.0",
49
- "@types/ws": "^8.5.4",
50
- "@typescript-eslint/eslint-plugin": "^5.57.0",
51
- "@typescript-eslint/parser": "^5.57.0",
44
+ "@commitlint/cli": "^19.8.1",
45
+ "@commitlint/config-conventional": "^19.8.1",
46
+ "@eslint/js": "^9.27.0",
47
+ "@types/ws": "^8.18.1",
52
48
  "cross-env": "^7.0.3",
53
- "eslint": "^8.36.0",
54
- "extra-utils": "^5.1.1",
49
+ "eslint": "^9.27.0",
50
+ "extra-utils": "^5.19.0",
55
51
  "husky": "4",
56
- "jest": "^29.5.0",
57
- "jest-resolve": "^29.5.0",
58
52
  "npm-run-all": "^4.1.5",
59
- "rimraf": "^3.0.2",
53
+ "rimraf": "^6.0.1",
60
54
  "standard-version": "^9.3.2",
61
- "ts-jest": "^29.0.5",
62
- "ts-patch": "^2.1.0",
63
- "tslib": "^2.5.0",
64
- "typescript": "4.8",
65
- "typescript-transform-paths": "^3.4.6"
55
+ "ts-patch": "^3.3.0",
56
+ "tslib": "^2.8.1",
57
+ "typescript": "5.8.3",
58
+ "typescript-eslint": "^8.33.0",
59
+ "typescript-transform-paths": "^3.5.5",
60
+ "vite": "^6.3.5",
61
+ "vite-tsconfig-paths": "^5.1.4",
62
+ "vitest": "^3.1.4"
66
63
  },
67
64
  "dependencies": {
68
- "@blackglory/errors": "^3.0.0",
69
- "@blackglory/prelude": "^0.3.1",
70
- "@delight-rpc/extra-native-websocket": "^0.5.1",
71
- "@delight-rpc/extra-websocket": "^0.6.1",
72
- "delight-rpc": "^6.0.1",
73
- "extra-abort": "^0.3.4",
74
- "extra-native-websocket": "^0.3.1",
75
- "extra-websocket": "^0.3.1",
76
- "justypes": "^4.2.0",
77
- "ws": "^8.13.0"
65
+ "@blackglory/errors": "^3.0.3",
66
+ "@blackglory/prelude": "^0.4.0",
67
+ "@delight-rpc/extra-native-websocket": "^0.6.0",
68
+ "@delight-rpc/extra-websocket": "^0.7.0",
69
+ "delight-rpc": "^6.1.2",
70
+ "extra-abort": "^0.4.0",
71
+ "extra-native-websocket": "^0.4.1",
72
+ "extra-websocket": "^0.4.2",
73
+ "justypes": "^4.4.1",
74
+ "ws": "^8.18.2"
78
75
  }
79
76
  }
@@ -0,0 +1,52 @@
1
+ import { CustomError } from '@blackglory/errors'
2
+ import { JSONValue } from 'justypes'
3
+
4
+ export const expectedVersion = '^0.4.0'
5
+
6
+ export interface INamespaceStats {
7
+ items: number
8
+ }
9
+
10
+ export interface IAPI {
11
+ getAllNamespaces(): string[]
12
+ getAllItemIds(namespace: string): string[]
13
+ getAllEvents(namespace: string, itemId: string): JSONValue[]
14
+
15
+ getNamespaceStats(namespace: string): INamespaceStats
16
+
17
+ clearItemsByNamespace(namespace: string): null
18
+
19
+ removeItem(namespace: string, itemId: string): null
20
+
21
+ /**
22
+ * 获得指定项目内包含的事件数量, 该值等同于下一个事件插入时的索引号.
23
+ * 对于不存在的项目, 它会返回0.
24
+ */
25
+ getItemSize(namespace: string, itemId: string): number
26
+
27
+ /**
28
+ * @param nextEventIndex 如果指定, 则会在eventIndex不等于下一个index时抛出EventIndexConflict错误.
29
+ * @throws {EventIndexConflict}
30
+ */
31
+ appendEvent(...args:
32
+ | [
33
+ namespace: string
34
+ , itemId: string
35
+ , event: JSONValue
36
+ ]
37
+ | [
38
+ namespace: string
39
+ , itemId: string
40
+ , event: JSONValue
41
+ , nextEventIndex: number
42
+ ]
43
+ ): null
44
+
45
+ getEvent(
46
+ namespace: string
47
+ , itemId: string
48
+ , eventIndex: number
49
+ ): JSONValue | null
50
+ }
51
+
52
+ export class EventIndexConflict extends CustomError {}
@@ -0,0 +1,143 @@
1
+ import { createRPCClient } from '@utils/rpc-client.js'
2
+ import { ClientProxy } from 'delight-rpc'
3
+ import { IAPI, INamespaceStats } from './contract.js'
4
+ import { raceAbortSignals, timeoutSignal } from 'extra-abort'
5
+ import { isntUndefined, isUndefined, JSONValue } from '@blackglory/prelude'
6
+ export { INamespaceStats } from './contract.js'
7
+ export { EventIndexConflict } from './contract.js'
8
+
9
+ export interface IEStoreClientOptions {
10
+ server: string
11
+ timeout?: number
12
+ retryIntervalForReconnection?: number
13
+ }
14
+
15
+ export class EStoreClient {
16
+ static async create(options: IEStoreClientOptions): Promise<EStoreClient> {
17
+ const { client, close } = await createRPCClient(
18
+ options.server
19
+ , options.retryIntervalForReconnection
20
+ )
21
+ return new EStoreClient(client, close, options.timeout)
22
+ }
23
+
24
+ private constructor(
25
+ private client: ClientProxy<IAPI>
26
+ , private closeClients: () => Promise<void>
27
+ , private timeout?: number
28
+ ) {}
29
+
30
+ async close(): Promise<void> {
31
+ await this.closeClients()
32
+ }
33
+
34
+ async getNamespaceStats(
35
+ namespace: string
36
+ , signal?: AbortSignal
37
+ ): Promise<INamespaceStats> {
38
+ return await this.client.getNamespaceStats(
39
+ namespace
40
+ , this.withTimeout(signal)
41
+ )
42
+ }
43
+
44
+ async getAllNamespaces(signal?: AbortSignal): Promise<string[]> {
45
+ return await this.client.getAllNamespaces(this.withTimeout(signal))
46
+ }
47
+
48
+ async getAllItemIds(
49
+ namespace: string
50
+ , signal?: AbortSignal
51
+ ): Promise<string[]> {
52
+ return await this.client.getAllItemIds(namespace, this.withTimeout(signal))
53
+ }
54
+
55
+ async getAllEvents(
56
+ namespace: string
57
+ , itemId: string
58
+ , signal?: AbortSignal
59
+ ): Promise<JSONValue[]> {
60
+ return await this.client.getAllEvents(
61
+ namespace
62
+ , itemId
63
+ , this.withTimeout(signal)
64
+ )
65
+ }
66
+
67
+ async clearItemsByNamespace(
68
+ namespace: string
69
+ , signal?: AbortSignal
70
+ ): Promise<void> {
71
+ await this.client.clearItemsByNamespace(namespace, this.withTimeout(signal))
72
+ }
73
+
74
+ async removeItem(
75
+ namespace: string
76
+ , itemId: string
77
+ , signal?: AbortSignal
78
+ ): Promise<void> {
79
+ await this.client.removeItem(namespace, itemId, this.withTimeout(signal))
80
+ }
81
+
82
+ async getItemSize(
83
+ namespace: string
84
+ , itemId: string
85
+ , signal?: AbortSignal
86
+ ): Promise<number> {
87
+ return await this.client.getItemSize(
88
+ namespace
89
+ , itemId
90
+ , this.withTimeout(signal)
91
+ )
92
+ }
93
+
94
+ /**
95
+ * @param nextEventIndex 如果指定, 则会在eventIndex不等于下一个index时抛出EventIndexConflict错误.
96
+ * @throws {EventIndexConflict}
97
+ */
98
+ async appendEvent(
99
+ namespace: string
100
+ , itemId: string
101
+ , event: JSONValue
102
+ , nextEventIndex?: number
103
+ , signal?: AbortSignal
104
+ ): Promise<void> {
105
+ if (isUndefined(nextEventIndex)) {
106
+ await this.client.appendEvent(
107
+ namespace
108
+ , itemId
109
+ , event
110
+ , this.withTimeout(signal)
111
+ )
112
+ } else {
113
+ await this.client.appendEvent(
114
+ namespace
115
+ , itemId
116
+ , event
117
+ , nextEventIndex
118
+ , this.withTimeout(signal)
119
+ )
120
+ }
121
+ }
122
+
123
+ async getEvent(
124
+ namespace: string
125
+ , itemId: string
126
+ , index: number
127
+ , signal?: AbortSignal
128
+ ): Promise<JSONValue | null> {
129
+ return await this.client.getEvent(
130
+ namespace
131
+ , itemId
132
+ , index
133
+ , this.withTimeout(signal)
134
+ )
135
+ }
136
+
137
+ private withTimeout(signal?: AbortSignal): AbortSignal {
138
+ return raceAbortSignals([
139
+ isntUndefined(this.timeout) && timeoutSignal(this.timeout)
140
+ , signal
141
+ ])
142
+ }
143
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './estore-client.js'
@@ -0,0 +1,27 @@
1
+ import { IAPI, expectedVersion } from '@src/contract.js'
2
+ import { ClientProxy } from 'delight-rpc'
3
+ import { createClient } from '@delight-rpc/extra-native-websocket'
4
+ import { ExtraNativeWebSocket, autoReconnect } from 'extra-native-websocket'
5
+
6
+ export async function createRPCClient(
7
+ url: string
8
+ , retryIntervalForReconnection?: number
9
+ ): Promise<{
10
+ client: ClientProxy<IAPI>
11
+ close: () => Promise<void>
12
+ }> {
13
+ const ws = new ExtraNativeWebSocket(() => new WebSocket(url))
14
+ const cancelAutoReconnect = autoReconnect(ws, retryIntervalForReconnection)
15
+ await ws.connect()
16
+
17
+ const [client, closeClient] = createClient<IAPI>(ws, { expectedVersion })
18
+
19
+ return {
20
+ client
21
+ , close: async () => {
22
+ closeClient()
23
+ cancelAutoReconnect()
24
+ await ws.close()
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,28 @@
1
+ import { IAPI, expectedVersion } from '@src/contract.js'
2
+ import { ClientProxy } from 'delight-rpc'
3
+ import { createClient } from '@delight-rpc/extra-websocket'
4
+ import { WebSocket } from 'ws'
5
+ import { ExtraWebSocket, autoReconnect } from 'extra-websocket'
6
+
7
+ export async function createRPCClient(
8
+ url: string
9
+ , retryIntervalForReconnection?: number
10
+ ): Promise<{
11
+ client: ClientProxy<IAPI>
12
+ close: () => Promise<void>
13
+ }> {
14
+ const ws = new ExtraWebSocket(() => new WebSocket(url))
15
+ const cancelAutoReconnect = autoReconnect(ws, retryIntervalForReconnection)
16
+ await ws.connect()
17
+
18
+ const [client, closeClient] = createClient<IAPI>(ws, { expectedVersion })
19
+
20
+ return {
21
+ client
22
+ , close: async () => {
23
+ closeClient()
24
+ cancelAutoReconnect()
25
+ await ws.close()
26
+ }
27
+ }
28
+ }