@blackglory/estore-js 0.5.3 → 0.6.1

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, options.timeout);
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);
23
- }
24
- async getAllItemIds(namespace, timeout) {
25
- return await this.withTimeout(() => this.client.getAllItemIds(namespace), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
18
+ async getNamespaceStats(namespace, signal) {
19
+ return await this.client.getNamespaceStats(namespace, this.withTimeout(signal));
26
20
  }
27
- async getAllEvents(namespace, itemId, timeout) {
28
- return await this.withTimeout(() => this.client.getAllEvents(namespace, itemId), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
21
+ async getAllNamespaces(signal) {
22
+ return await this.client.getAllNamespaces(this.withTimeout(signal));
29
23
  }
30
- async clearItemsByNamespace(namespace, timeout) {
31
- await this.withTimeout(() => this.client.clearItemsByNamespace(namespace), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
24
+ async getAllItemIds(namespace, signal) {
25
+ return await this.client.getAllItemIds(namespace, this.withTimeout(signal));
32
26
  }
33
- async removeItem(namespace, itemId, timeout) {
34
- await this.withTimeout(() => this.client.removeItem(namespace, itemId), 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));
35
29
  }
36
- async getItemSize(namespace, itemId, timeout) {
37
- return await this.withTimeout(() => this.client.getItemSize(namespace, itemId), timeout !== null && timeout !== void 0 ? timeout : this.timeout);
30
+ async clearItemsByNamespace(namespace, signal) {
31
+ await this.client.clearItemsByNamespace(namespace, this.withTimeout(signal));
38
32
  }
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);
33
+ async removeItem(namespace, itemId, signal) {
34
+ await this.client.removeItem(namespace, itemId, this.withTimeout(signal));
48
35
  }
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);
36
+ async getItemSize(namespace, itemId, signal) {
37
+ return await this.client.getItemSize(namespace, itemId, this.withTimeout(signal));
51
38
  }
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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"}
@@ -1,6 +1,6 @@
1
1
  import { IAPI } from "../contract.js";
2
2
  import { ClientProxy } from 'delight-rpc';
3
- export declare function createRPCClient(url: string, retryIntervalForReconnection?: number): Promise<{
3
+ export declare function createRPCClient(url: string, retryIntervalForReconnection?: number, timeoutForConnection?: number): Promise<{
4
4
  client: ClientProxy<IAPI>;
5
5
  close: () => Promise<void>;
6
6
  }>;
@@ -1,10 +1,13 @@
1
1
  import { expectedVersion } from "../contract.js";
2
2
  import { createClient } from '@delight-rpc/extra-native-websocket';
3
3
  import { ExtraNativeWebSocket, autoReconnect } from 'extra-native-websocket';
4
- export async function createRPCClient(url, retryIntervalForReconnection) {
4
+ import { timeoutSignal } from 'extra-abort';
5
+ export async function createRPCClient(url, retryIntervalForReconnection, timeoutForConnection) {
5
6
  const ws = new ExtraNativeWebSocket(() => new WebSocket(url));
6
- const cancelAutoReconnect = autoReconnect(ws, retryIntervalForReconnection);
7
- await ws.connect();
7
+ const cancelAutoReconnect = autoReconnect(ws, retryIntervalForReconnection, timeoutForConnection);
8
+ await ws.connect(timeoutForConnection
9
+ ? timeoutSignal(timeoutForConnection)
10
+ : undefined);
8
11
  const [client, closeClient] = createClient(ws, { expectedVersion });
9
12
  return {
10
13
  client,
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-client.browser.js","sourceRoot":"","sources":["../../src/utils/rpc-client.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,eAAe,EAAE,uBAAwB;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAE5E,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,4BAAqC;IAKrC,MAAM,EAAE,GAAG,IAAI,oBAAoB,CAAC,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IAC7D,MAAM,mBAAmB,GAAG,aAAa,CAAC,EAAE,EAAE,4BAA4B,CAAC,CAAA;IAC3E,MAAM,EAAE,CAAC,OAAO,EAAE,CAAA;IAElB,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,YAAY,CAAO,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAA;IAEzE,OAAO;QACL,MAAM;QACN,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,WAAW,EAAE,CAAA;YACb,mBAAmB,EAAE,CAAA;YACrB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAA;QAClB,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"rpc-client.browser.js","sourceRoot":"","sources":["../../src/utils/rpc-client.browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,eAAe,EAAE,uBAAwB;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,4BAAqC,EACrC,oBAA6B;IAK7B,MAAM,EAAE,GAAG,IAAI,oBAAoB,CAAC,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IAC7D,MAAM,mBAAmB,GAAG,aAAa,CACvC,EAAE,EACF,4BAA4B,EAC5B,oBAAoB,CACrB,CAAA;IACD,MAAM,EAAE,CAAC,OAAO,CACd,oBAAoB;QACtB,CAAC,CAAC,aAAa,CAAC,oBAAoB,CAAC;QACrC,CAAC,CAAC,SAAS,CACV,CAAA;IAED,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,YAAY,CAAO,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAA;IAEzE,OAAO;QACL,MAAM;QACN,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,WAAW,EAAE,CAAA;YACb,mBAAmB,EAAE,CAAA;YACrB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAA;QAClB,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { IAPI } from "../contract.js";
2
2
  import { ClientProxy } from 'delight-rpc';
3
- export declare function createRPCClient(url: string, retryIntervalForReconnection?: number): Promise<{
3
+ export declare function createRPCClient(url: string, retryIntervalForReconnection?: number, timeoutForConnection?: number): Promise<{
4
4
  client: ClientProxy<IAPI>;
5
5
  close: () => Promise<void>;
6
6
  }>;
@@ -2,10 +2,13 @@ import { expectedVersion } from "../contract.js";
2
2
  import { createClient } from '@delight-rpc/extra-websocket';
3
3
  import { WebSocket } from 'ws';
4
4
  import { ExtraWebSocket, autoReconnect } from 'extra-websocket';
5
- export async function createRPCClient(url, retryIntervalForReconnection) {
5
+ import { timeoutSignal } from 'extra-abort';
6
+ export async function createRPCClient(url, retryIntervalForReconnection, timeoutForConnection) {
6
7
  const ws = new ExtraWebSocket(() => new WebSocket(url));
7
- const cancelAutoReconnect = autoReconnect(ws, retryIntervalForReconnection);
8
- await ws.connect();
8
+ const cancelAutoReconnect = autoReconnect(ws, retryIntervalForReconnection, timeoutForConnection);
9
+ await ws.connect(timeoutForConnection
10
+ ? timeoutSignal(timeoutForConnection)
11
+ : undefined);
9
12
  const [client, closeClient] = createClient(ws, { expectedVersion });
10
13
  return {
11
14
  client,
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-client.js","sourceRoot":"","sources":["../../src/utils/rpc-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,eAAe,EAAE,uBAAwB;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AAC9B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE/D,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,4BAAqC;IAKrC,MAAM,EAAE,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IACvD,MAAM,mBAAmB,GAAG,aAAa,CAAC,EAAE,EAAE,4BAA4B,CAAC,CAAA;IAC3E,MAAM,EAAE,CAAC,OAAO,EAAE,CAAA;IAElB,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,YAAY,CAAO,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAA;IAEzE,OAAO;QACL,MAAM;QACN,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,WAAW,EAAE,CAAA;YACb,mBAAmB,EAAE,CAAA;YACrB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAA;QAClB,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"rpc-client.js","sourceRoot":"","sources":["../../src/utils/rpc-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,eAAe,EAAE,uBAAwB;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AAC9B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,4BAAqC,EACrC,oBAA6B;IAK7B,MAAM,EAAE,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IACvD,MAAM,mBAAmB,GAAG,aAAa,CACvC,EAAE,EACF,4BAA4B,EAC5B,oBAAoB,CACrB,CAAA;IACD,MAAM,EAAE,CAAC,OAAO,CACd,oBAAoB;QACtB,CAAC,CAAC,aAAa,CAAC,oBAAoB,CAAC;QACrC,CAAC,CAAC,SAAS,CACV,CAAA;IAED,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,YAAY,CAAO,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAA;IAEzE,OAAO;QACL,MAAM;QACN,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,WAAW,EAAE,CAAA;YACb,mBAAmB,EAAE,CAAA;YACrB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAA;QAClB,CAAC;KACF,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blackglory/estore-js",
3
- "version": "0.5.3",
3
+ "version": "0.6.1",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "files": [
@@ -18,22 +18,20 @@
18
18
  "license": "MIT",
19
19
  "sideEffects": false,
20
20
  "engines": {
21
- "node": ">=16"
21
+ "node": ">=22"
22
22
  },
23
23
  "scripts": {
24
24
  "prepare": "ts-patch install -s",
25
- "lint": "eslint --ext .js,.jsx,.ts,.tsx --quiet src __tests__",
26
- "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --no-cache --config jest.config.cjs",
27
- "test:debug": "cross-env NODE_OPTIONS=--experimental-vm-modules node --inspect-brk node_modules/.bin/jest --runInBand jest.config.cjs",
28
- "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",
29
27
  "prepublishOnly": "run-s prepare clean build",
30
28
  "clean": "rimraf lib",
31
29
  "build": "tsc --project tsconfig.build.json",
32
30
  "docker:test": "run-s docker:test:clean docker:test:build docker:test:run docker:test:clean",
33
31
  "docker:coverage": "run-s docker:test:clean docker:test:build docker:test:coverage docker:test:clean",
34
- "docker:test:build": "docker-compose --project-name estore-js --file docker-compose.test.yml build",
35
- "docker:test:run": "docker-compose --project-name estore-js --file docker-compose.test.yml run --rm test",
36
- "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",
37
35
  "release": "standard-version"
38
36
  },
39
37
  "husky": {
@@ -43,38 +41,36 @@
43
41
  }
44
42
  },
45
43
  "devDependencies": {
46
- "@blackglory/jest-resolver": "^0.3.0",
47
- "@commitlint/cli": "^17.5.1",
48
- "@commitlint/config-conventional": "^17.4.4",
49
- "@types/jest": "^29.5.0",
50
- "@types/ws": "^8.5.4",
51
- "@typescript-eslint/eslint-plugin": "^5.57.0",
52
- "@typescript-eslint/parser": "^5.57.0",
44
+ "@commitlint/cli": "^19.8.1",
45
+ "@commitlint/config-conventional": "^19.8.1",
46
+ "@eslint/js": "^9.31.0",
47
+ "@types/ws": "^8.18.1",
53
48
  "cross-env": "^7.0.3",
54
- "eslint": "^8.36.0",
55
- "extra-utils": "^5.1.1",
49
+ "eslint": "^9.31.0",
50
+ "extra-utils": "^5.19.0",
56
51
  "husky": "4",
57
- "jest": "^29.5.0",
58
- "jest-resolve": "^29.5.0",
59
52
  "npm-run-all": "^4.1.5",
60
- "rimraf": "^3.0.2",
53
+ "rimraf": "^6.0.1",
61
54
  "standard-version": "^9.3.2",
62
- "ts-jest": "^29.0.5",
63
- "ts-patch": "^2.1.0",
64
- "tslib": "^2.5.0",
65
- "typescript": "4.8",
66
- "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.38.0",
59
+ "typescript-transform-paths": "^3.5.5",
60
+ "vite": "^7.0.5",
61
+ "vite-tsconfig-paths": "^5.1.4",
62
+ "vitest": "^3.2.4"
67
63
  },
68
64
  "dependencies": {
69
- "@blackglory/errors": "^3.0.0",
70
- "@blackglory/prelude": "^0.3.1",
71
- "@delight-rpc/extra-native-websocket": "^0.5.1",
72
- "@delight-rpc/extra-websocket": "^0.6.1",
73
- "delight-rpc": "^6.0.1",
74
- "extra-abort": "^0.3.4",
75
- "extra-native-websocket": "^0.3.1",
76
- "extra-websocket": "^0.3.1",
77
- "justypes": "^4.2.0",
78
- "ws": "^8.13.0"
65
+ "@blackglory/errors": "^3.0.3",
66
+ "@blackglory/prelude": "^0.4.0",
67
+ "@delight-rpc/extra-native-websocket": "^0.6.1",
68
+ "@delight-rpc/extra-websocket": "^0.7.1",
69
+ "delight-rpc": "^6.1.2",
70
+ "extra-abort": "^0.4.0",
71
+ "extra-native-websocket": "^0.5.0",
72
+ "extra-websocket": "^0.5.0",
73
+ "justypes": "^4.4.1",
74
+ "ws": "^8.18.3"
79
75
  }
80
76
  }
package/src/contract.ts CHANGED
@@ -28,11 +28,18 @@ export interface IAPI {
28
28
  * @param nextEventIndex 如果指定, 则会在eventIndex不等于下一个index时抛出EventIndexConflict错误.
29
29
  * @throws {EventIndexConflict}
30
30
  */
31
- appendEvent(
32
- namespace: string
33
- , itemId: string
34
- , event: JSONValue
35
- , nextEventIndex?: number
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
+ ]
36
43
  ): null
37
44
 
38
45
  getEvent(
@@ -1,8 +1,8 @@
1
1
  import { createRPCClient } from '@utils/rpc-client.js'
2
2
  import { ClientProxy } from 'delight-rpc'
3
3
  import { IAPI, INamespaceStats } from './contract.js'
4
- import { timeoutSignal, withAbortSignal } from 'extra-abort'
5
- import { isUndefined, JSONValue } from '@blackglory/prelude'
4
+ import { raceAbortSignals, timeoutSignal } from 'extra-abort'
5
+ import { isntUndefined, isUndefined, JSONValue } from '@blackglory/prelude'
6
6
  export { INamespaceStats } from './contract.js'
7
7
  export { EventIndexConflict } from './contract.js'
8
8
 
@@ -17,6 +17,7 @@ export class EStoreClient {
17
17
  const { client, close } = await createRPCClient(
18
18
  options.server
19
19
  , options.retryIntervalForReconnection
20
+ , options.timeout
20
21
  )
21
22
  return new EStoreClient(client, close, options.timeout)
22
23
  }
@@ -33,65 +34,61 @@ export class EStoreClient {
33
34
 
34
35
  async getNamespaceStats(
35
36
  namespace: string
36
- , timeout?: number
37
+ , signal?: AbortSignal
37
38
  ): Promise<INamespaceStats> {
38
- return await this.withTimeout(
39
- () => this.client.getNamespaceStats(namespace)
40
- , timeout ?? this.timeout
39
+ return await this.client.getNamespaceStats(
40
+ namespace
41
+ , this.withTimeout(signal)
41
42
  )
42
43
  }
43
44
 
44
- async getAllNamespaces(timeout?: number): Promise<string[]> {
45
- return await this.withTimeout(
46
- () => this.client.getAllNamespaces()
47
- , timeout ?? this.timeout
48
- )
45
+ async getAllNamespaces(signal?: AbortSignal): Promise<string[]> {
46
+ return await this.client.getAllNamespaces(this.withTimeout(signal))
49
47
  }
50
48
 
51
- async getAllItemIds(namespace: string, timeout?: number): Promise<string[]> {
52
- return await this.withTimeout(
53
- () => this.client.getAllItemIds(namespace)
54
- , timeout ?? this.timeout
55
- )
49
+ async getAllItemIds(
50
+ namespace: string
51
+ , signal?: AbortSignal
52
+ ): Promise<string[]> {
53
+ return await this.client.getAllItemIds(namespace, this.withTimeout(signal))
56
54
  }
57
55
 
58
56
  async getAllEvents(
59
57
  namespace: string
60
58
  , itemId: string
61
- , timeout?: number
59
+ , signal?: AbortSignal
62
60
  ): Promise<JSONValue[]> {
63
- return await this.withTimeout(
64
- () => this.client.getAllEvents(namespace, itemId)
65
- , timeout ?? this.timeout
61
+ return await this.client.getAllEvents(
62
+ namespace
63
+ , itemId
64
+ , this.withTimeout(signal)
66
65
  )
67
66
  }
68
67
 
69
- async clearItemsByNamespace(namespace: string, timeout?: number): Promise<void> {
70
- await this.withTimeout(
71
- () => this.client.clearItemsByNamespace(namespace)
72
- , timeout ?? this.timeout
73
- )
68
+ async clearItemsByNamespace(
69
+ namespace: string
70
+ , signal?: AbortSignal
71
+ ): Promise<void> {
72
+ await this.client.clearItemsByNamespace(namespace, this.withTimeout(signal))
74
73
  }
75
74
 
76
75
  async removeItem(
77
76
  namespace: string
78
77
  , itemId: string
79
- , timeout?: number
78
+ , signal?: AbortSignal
80
79
  ): Promise<void> {
81
- await this.withTimeout(
82
- () => this.client.removeItem(namespace, itemId)
83
- , timeout ?? this.timeout
84
- )
80
+ await this.client.removeItem(namespace, itemId, this.withTimeout(signal))
85
81
  }
86
82
 
87
83
  async getItemSize(
88
84
  namespace: string
89
85
  , itemId: string
90
- , timeout?: number
86
+ , signal?: AbortSignal
91
87
  ): Promise<number> {
92
- return await this.withTimeout(
93
- () => this.client.getItemSize(namespace, itemId)
94
- , timeout ?? this.timeout
88
+ return await this.client.getItemSize(
89
+ namespace
90
+ , itemId
91
+ , this.withTimeout(signal)
95
92
  )
96
93
  }
97
94
 
@@ -104,40 +101,44 @@ export class EStoreClient {
104
101
  , itemId: string
105
102
  , event: JSONValue
106
103
  , nextEventIndex?: number
107
- , timeout?: number
104
+ , signal?: AbortSignal
108
105
  ): Promise<void> {
109
- await this.withTimeout(
110
- () => {
111
- if (isUndefined(nextEventIndex)) {
112
- return this.client.appendEvent(namespace, itemId, event)
113
- } else {
114
- return this.client.appendEvent(namespace, itemId, event, nextEventIndex)
115
- }
116
- }
117
- , timeout ?? this.timeout
118
- )
106
+ if (isUndefined(nextEventIndex)) {
107
+ await this.client.appendEvent(
108
+ namespace
109
+ , itemId
110
+ , event
111
+ , this.withTimeout(signal)
112
+ )
113
+ } else {
114
+ await this.client.appendEvent(
115
+ namespace
116
+ , itemId
117
+ , event
118
+ , nextEventIndex
119
+ , this.withTimeout(signal)
120
+ )
121
+ }
119
122
  }
120
123
 
121
124
  async getEvent(
122
125
  namespace: string
123
126
  , itemId: string
124
127
  , index: number
125
- , timeout?: number
128
+ , signal?: AbortSignal
126
129
  ): Promise<JSONValue | null> {
127
- return await this.withTimeout(
128
- () => this.client.getEvent(namespace, itemId, index)
129
- , timeout ?? this.timeout
130
+ return await this.client.getEvent(
131
+ namespace
132
+ , itemId
133
+ , index
134
+ , this.withTimeout(signal)
130
135
  )
131
136
  }
132
137
 
133
- private async withTimeout<T>(
134
- fn: () => PromiseLike<T>
135
- , timeout: number | undefined = this.timeout
136
- ): Promise<T> {
137
- if (timeout) {
138
- return await withAbortSignal(timeoutSignal(timeout), fn)
139
- } else {
140
- return await fn()
141
- }
138
+ private withTimeout(signal?: AbortSignal): AbortSignal {
139
+ return raceAbortSignals([
140
+ isntUndefined(this.timeout) && timeoutSignal(this.timeout)
141
+ , signal
142
+ ])
142
143
  }
143
144
  }
@@ -2,17 +2,27 @@ import { IAPI, expectedVersion } from '@src/contract.js'
2
2
  import { ClientProxy } from 'delight-rpc'
3
3
  import { createClient } from '@delight-rpc/extra-native-websocket'
4
4
  import { ExtraNativeWebSocket, autoReconnect } from 'extra-native-websocket'
5
+ import { timeoutSignal } from 'extra-abort'
5
6
 
6
7
  export async function createRPCClient(
7
8
  url: string
8
9
  , retryIntervalForReconnection?: number
10
+ , timeoutForConnection?: number
9
11
  ): Promise<{
10
12
  client: ClientProxy<IAPI>
11
13
  close: () => Promise<void>
12
14
  }> {
13
15
  const ws = new ExtraNativeWebSocket(() => new WebSocket(url))
14
- const cancelAutoReconnect = autoReconnect(ws, retryIntervalForReconnection)
15
- await ws.connect()
16
+ const cancelAutoReconnect = autoReconnect(
17
+ ws
18
+ , retryIntervalForReconnection
19
+ , timeoutForConnection
20
+ )
21
+ await ws.connect(
22
+ timeoutForConnection
23
+ ? timeoutSignal(timeoutForConnection)
24
+ : undefined
25
+ )
16
26
 
17
27
  const [client, closeClient] = createClient<IAPI>(ws, { expectedVersion })
18
28
 
@@ -3,17 +3,27 @@ import { ClientProxy } from 'delight-rpc'
3
3
  import { createClient } from '@delight-rpc/extra-websocket'
4
4
  import { WebSocket } from 'ws'
5
5
  import { ExtraWebSocket, autoReconnect } from 'extra-websocket'
6
+ import { timeoutSignal } from 'extra-abort'
6
7
 
7
8
  export async function createRPCClient(
8
9
  url: string
9
10
  , retryIntervalForReconnection?: number
11
+ , timeoutForConnection?: number
10
12
  ): Promise<{
11
13
  client: ClientProxy<IAPI>
12
14
  close: () => Promise<void>
13
15
  }> {
14
16
  const ws = new ExtraWebSocket(() => new WebSocket(url))
15
- const cancelAutoReconnect = autoReconnect(ws, retryIntervalForReconnection)
16
- await ws.connect()
17
+ const cancelAutoReconnect = autoReconnect(
18
+ ws
19
+ , retryIntervalForReconnection
20
+ , timeoutForConnection
21
+ )
22
+ await ws.connect(
23
+ timeoutForConnection
24
+ ? timeoutSignal(timeoutForConnection)
25
+ : undefined
26
+ )
17
27
 
18
28
  const [client, closeClient] = createClient<IAPI>(ws, { expectedVersion })
19
29