@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 +20 -9
- package/lib/contract.d.ts +10 -1
- package/lib/contract.js.map +1 -1
- package/lib/estore-client.d.ts +9 -9
- package/lib/estore-client.js +33 -37
- package/lib/estore-client.js.map +1 -1
- package/lib/utils/rpc-client.browser.d.ts +1 -1
- package/lib/utils/rpc-client.browser.js +6 -3
- package/lib/utils/rpc-client.browser.js.map +1 -1
- package/lib/utils/rpc-client.d.ts +1 -1
- package/lib/utils/rpc-client.js +6 -3
- package/lib/utils/rpc-client.js.map +1 -1
- package/package.json +32 -36
- package/src/contract.ts +12 -5
- package/src/estore-client.ts +59 -58
- package/src/utils/rpc-client.browser.ts +12 -2
- package/src/utils/rpc-client.ts +12 -2
package/README.md
CHANGED
|
@@ -24,23 +24,34 @@ export class EStoreClient {
|
|
|
24
24
|
|
|
25
25
|
close(): Promise<void>
|
|
26
26
|
|
|
27
|
-
getNamespaceStats(
|
|
27
|
+
getNamespaceStats(
|
|
28
|
+
namespace: string
|
|
29
|
+
, signal?: AbortSignal
|
|
30
|
+
): Promise<INamespaceStats>
|
|
28
31
|
|
|
29
|
-
getAllNamespaces(
|
|
32
|
+
getAllNamespaces(signal?: AbortSignal): Promise<string[]>
|
|
30
33
|
|
|
31
|
-
getAllItemIds(namespace: string,
|
|
34
|
+
getAllItemIds(namespace: string, signal?: AbortSignal): Promise<string[]>
|
|
32
35
|
|
|
33
36
|
getAllEvents(
|
|
34
37
|
namespace: string
|
|
35
38
|
, itemId: string
|
|
36
|
-
,
|
|
39
|
+
, signal?: AbortSignal
|
|
37
40
|
): Promise<JSONValue[]>
|
|
38
41
|
|
|
39
|
-
clearItemsByNamespace(namespace: string,
|
|
42
|
+
clearItemsByNamespace(namespace: string, signal?: AbortSignal): Promise<void>
|
|
40
43
|
|
|
41
|
-
removeItem(
|
|
44
|
+
removeItem(
|
|
45
|
+
namespace: string
|
|
46
|
+
, itemId: string
|
|
47
|
+
, signal?: AbortSignal
|
|
48
|
+
): Promise<void>
|
|
42
49
|
|
|
43
|
-
getItemSize(
|
|
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
|
-
,
|
|
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
|
-
,
|
|
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(
|
|
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 {
|
package/lib/contract.js.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/lib/estore-client.d.ts
CHANGED
|
@@ -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,
|
|
18
|
-
getAllNamespaces(
|
|
19
|
-
getAllItemIds(namespace: string,
|
|
20
|
-
getAllEvents(namespace: string, itemId: string,
|
|
21
|
-
clearItemsByNamespace(namespace: string,
|
|
22
|
-
removeItem(namespace: string, itemId: string,
|
|
23
|
-
getItemSize(namespace: string, itemId: string,
|
|
24
|
-
appendEvent(namespace: string, itemId: string, event: JSONValue, nextEventIndex?: number,
|
|
25
|
-
getEvent(namespace: string, itemId: string, index: number,
|
|
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
|
}
|
package/lib/estore-client.js
CHANGED
|
@@ -1,61 +1,57 @@
|
|
|
1
1
|
import { createRPCClient } from "./utils/rpc-client.js";
|
|
2
|
-
import {
|
|
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,
|
|
19
|
-
return await this.
|
|
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
|
|
28
|
-
return await this.
|
|
21
|
+
async getAllNamespaces(signal) {
|
|
22
|
+
return await this.client.getAllNamespaces(this.withTimeout(signal));
|
|
29
23
|
}
|
|
30
|
-
async
|
|
31
|
-
await this.
|
|
24
|
+
async getAllItemIds(namespace, signal) {
|
|
25
|
+
return await this.client.getAllItemIds(namespace, this.withTimeout(signal));
|
|
32
26
|
}
|
|
33
|
-
async
|
|
34
|
-
await this.
|
|
27
|
+
async getAllEvents(namespace, itemId, signal) {
|
|
28
|
+
return await this.client.getAllEvents(namespace, itemId, this.withTimeout(signal));
|
|
35
29
|
}
|
|
36
|
-
async
|
|
37
|
-
|
|
30
|
+
async clearItemsByNamespace(namespace, signal) {
|
|
31
|
+
await this.client.clearItemsByNamespace(namespace, this.withTimeout(signal));
|
|
38
32
|
}
|
|
39
|
-
async
|
|
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
|
|
50
|
-
return await this.
|
|
36
|
+
async getItemSize(namespace, itemId, signal) {
|
|
37
|
+
return await this.client.getItemSize(namespace, itemId, this.withTimeout(signal));
|
|
51
38
|
}
|
|
52
|
-
async
|
|
53
|
-
if (
|
|
54
|
-
|
|
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
|
-
|
|
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
|
package/lib/estore-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estore-client.js","sourceRoot":"","sources":["../src/estore-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,8BAA4B;AAGtD,OAAO,EAAE,
|
|
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
|
-
|
|
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;
|
|
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
|
}>;
|
package/lib/utils/rpc-client.js
CHANGED
|
@@ -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
|
-
|
|
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;
|
|
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.
|
|
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": ">=
|
|
21
|
+
"node": ">=22"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
24
|
"prepare": "ts-patch install -s",
|
|
25
|
-
"lint": "eslint --
|
|
26
|
-
"test": "
|
|
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
|
|
35
|
-
"docker:test:run": "docker
|
|
36
|
-
"docker:test:clean": "docker
|
|
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
|
-
"@
|
|
47
|
-
"@commitlint/
|
|
48
|
-
"@
|
|
49
|
-
"@types/
|
|
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": "^
|
|
55
|
-
"extra-utils": "^5.
|
|
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": "^
|
|
53
|
+
"rimraf": "^6.0.1",
|
|
61
54
|
"standard-version": "^9.3.2",
|
|
62
|
-
"ts-
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"typescript": "
|
|
66
|
-
"typescript-transform-paths": "^3.
|
|
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.
|
|
70
|
-
"@blackglory/prelude": "^0.
|
|
71
|
-
"@delight-rpc/extra-native-websocket": "^0.
|
|
72
|
-
"@delight-rpc/extra-websocket": "^0.
|
|
73
|
-
"delight-rpc": "^6.
|
|
74
|
-
"extra-abort": "^0.
|
|
75
|
-
"extra-native-websocket": "^0.
|
|
76
|
-
"extra-websocket": "^0.
|
|
77
|
-
"justypes": "^4.
|
|
78
|
-
"ws": "^8.
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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(
|
package/src/estore-client.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
,
|
|
37
|
+
, signal?: AbortSignal
|
|
37
38
|
): Promise<INamespaceStats> {
|
|
38
|
-
return await this.
|
|
39
|
-
|
|
40
|
-
,
|
|
39
|
+
return await this.client.getNamespaceStats(
|
|
40
|
+
namespace
|
|
41
|
+
, this.withTimeout(signal)
|
|
41
42
|
)
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
async getAllNamespaces(
|
|
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(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
,
|
|
59
|
+
, signal?: AbortSignal
|
|
62
60
|
): Promise<JSONValue[]> {
|
|
63
|
-
return await this.
|
|
64
|
-
|
|
65
|
-
,
|
|
61
|
+
return await this.client.getAllEvents(
|
|
62
|
+
namespace
|
|
63
|
+
, itemId
|
|
64
|
+
, this.withTimeout(signal)
|
|
66
65
|
)
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
async clearItemsByNamespace(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
,
|
|
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
|
-
,
|
|
86
|
+
, signal?: AbortSignal
|
|
91
87
|
): Promise<number> {
|
|
92
|
-
return await this.
|
|
93
|
-
|
|
94
|
-
,
|
|
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
|
-
,
|
|
104
|
+
, signal?: AbortSignal
|
|
108
105
|
): Promise<void> {
|
|
109
|
-
|
|
110
|
-
(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
,
|
|
128
|
+
, signal?: AbortSignal
|
|
126
129
|
): Promise<JSONValue | null> {
|
|
127
|
-
return await this.
|
|
128
|
-
|
|
129
|
-
,
|
|
130
|
+
return await this.client.getEvent(
|
|
131
|
+
namespace
|
|
132
|
+
, itemId
|
|
133
|
+
, index
|
|
134
|
+
, this.withTimeout(signal)
|
|
130
135
|
)
|
|
131
136
|
}
|
|
132
137
|
|
|
133
|
-
private
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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(
|
|
15
|
-
|
|
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
|
|
package/src/utils/rpc-client.ts
CHANGED
|
@@ -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(
|
|
16
|
-
|
|
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
|
|