@nice-code/action 0.1.1 → 0.1.2
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/build/index.js +49 -6
- package/build/types/ActionDomain/NiceActionDomain.types.d.ts +0 -1
- package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/Transport.d.ts +3 -0
- package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/Transport.types.d.ts +24 -4
- package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/TransportCustom.d.ts +12 -0
- package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/TransportWebSocket.d.ts +3 -1
- package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/err_nice_transport.d.ts +4 -0
- package/build/types/ActionRuntimeEnvironment/ActionHandler/ActionHandler.types.d.ts +2 -1
- package/build/types/NiceAction/MatchAction/MatchAction.d.ts +2 -1
- package/build/types/index.d.ts +2 -1
- package/build/types/utils/maybePromise.d.ts +1 -0
- package/package.json +3 -3
package/build/index.js
CHANGED
|
@@ -3393,6 +3393,7 @@ var EErrId_NiceTransport;
|
|
|
3393
3393
|
((EErrId_NiceTransport2) => {
|
|
3394
3394
|
EErrId_NiceTransport2["timeout"] = "timeout";
|
|
3395
3395
|
EErrId_NiceTransport2["not_found"] = "not_found";
|
|
3396
|
+
EErrId_NiceTransport2["not_available"] = "not_available";
|
|
3396
3397
|
EErrId_NiceTransport2["initialization_failed"] = "initialization_failed";
|
|
3397
3398
|
EErrId_NiceTransport2["send_failed"] = "send_failed";
|
|
3398
3399
|
EErrId_NiceTransport2["invalid_action_response"] = "invalid_action_response";
|
|
@@ -3406,6 +3407,9 @@ var err_nice_transport = err_nice_connect.createChildDomain({
|
|
|
3406
3407
|
["not_found" /* not_found */]: err({
|
|
3407
3408
|
message: ({ actionId, routeKey, tag }) => `No connected transport found for action "${actionId}"${routeKey ? ` with route key "${routeKey}"` : ``}${tag ? ` and action tag "${tag}"` : ""}.`
|
|
3408
3409
|
}),
|
|
3410
|
+
["not_available" /* not_available */]: err({
|
|
3411
|
+
message: ({ transportCount }) => `${transportCount} Transport(s) found but were filtered out via filterUsage().`
|
|
3412
|
+
}),
|
|
3409
3413
|
["initialization_failed" /* initialization_failed */]: err({
|
|
3410
3414
|
message: ({ actionId, routeKey, tag }) => `Transports found for action "${actionId}"${routeKey ? ` with route key "${routeKey}"` : ""}${tag ? ` and action tag "${tag}"` : ""}, but none are ready.`
|
|
3411
3415
|
}),
|
|
@@ -3487,13 +3491,21 @@ class Transport {
|
|
|
3487
3491
|
def;
|
|
3488
3492
|
type;
|
|
3489
3493
|
requestResolvers = new Map;
|
|
3494
|
+
_filterUsage;
|
|
3490
3495
|
constructor(def) {
|
|
3491
3496
|
this.def = def;
|
|
3492
3497
|
this.type = def.type;
|
|
3498
|
+
this._filterUsage = def.filterUsage;
|
|
3493
3499
|
}
|
|
3494
3500
|
get status() {
|
|
3495
3501
|
return this._status;
|
|
3496
3502
|
}
|
|
3503
|
+
filterUsage(primed) {
|
|
3504
|
+
if (this._filterUsage == null) {
|
|
3505
|
+
return true;
|
|
3506
|
+
}
|
|
3507
|
+
return this._filterUsage(primed);
|
|
3508
|
+
}
|
|
3497
3509
|
checkAndPrepare() {
|
|
3498
3510
|
return this._status;
|
|
3499
3511
|
}
|
|
@@ -3533,6 +3545,7 @@ var ETransportType;
|
|
|
3533
3545
|
((ETransportType2) => {
|
|
3534
3546
|
ETransportType2["ws"] = "ws";
|
|
3535
3547
|
ETransportType2["http"] = "http";
|
|
3548
|
+
ETransportType2["custom"] = "custom";
|
|
3536
3549
|
})(ETransportType ||= {});
|
|
3537
3550
|
var ETransportStatus;
|
|
3538
3551
|
((ETransportStatus2) => {
|
|
@@ -3621,6 +3634,7 @@ var err_nice_transport_ws = err_nice_transport.createChildDomain({
|
|
|
3621
3634
|
class TransportWebSocket extends Transport {
|
|
3622
3635
|
websocket;
|
|
3623
3636
|
_status = { status: "uninitialized" /* uninitialized */ };
|
|
3637
|
+
_customMessageSerde;
|
|
3624
3638
|
constructor(def) {
|
|
3625
3639
|
super(def);
|
|
3626
3640
|
}
|
|
@@ -3642,21 +3656,24 @@ class TransportWebSocket extends Transport {
|
|
|
3642
3656
|
waitForInitialization
|
|
3643
3657
|
};
|
|
3644
3658
|
}
|
|
3645
|
-
|
|
3659
|
+
handlePureActionResponseMessage(message) {
|
|
3646
3660
|
let json;
|
|
3647
3661
|
try {
|
|
3648
|
-
json = JSON.parse(
|
|
3662
|
+
json = JSON.parse(message);
|
|
3649
3663
|
} catch {
|
|
3650
3664
|
return;
|
|
3651
3665
|
}
|
|
3652
3666
|
if (!isActionResponseJsonObject(json)) {
|
|
3653
3667
|
return;
|
|
3654
3668
|
}
|
|
3655
|
-
|
|
3669
|
+
return json;
|
|
3670
|
+
}
|
|
3671
|
+
handleResponse(response) {
|
|
3672
|
+
const pending = this.requestResolvers.get(response.cuid);
|
|
3656
3673
|
if (pending == null) {
|
|
3657
3674
|
return;
|
|
3658
3675
|
}
|
|
3659
|
-
this.respond(pending.primed.coreAction.actionDomain.hydrateResponse(
|
|
3676
|
+
this.respond(pending.primed.coreAction.actionDomain.hydrateResponse(response));
|
|
3660
3677
|
}
|
|
3661
3678
|
rejectPendingWebSocketRequests(error) {
|
|
3662
3679
|
for (const [, pending] of this.requestResolvers) {
|
|
@@ -3676,7 +3693,9 @@ class TransportWebSocket extends Transport {
|
|
|
3676
3693
|
}
|
|
3677
3694
|
};
|
|
3678
3695
|
try {
|
|
3679
|
-
|
|
3696
|
+
const { ws, customMessageSerde } = await this.def.createWebSocket();
|
|
3697
|
+
this.websocket = ws;
|
|
3698
|
+
this._customMessageSerde = customMessageSerde;
|
|
3680
3699
|
} catch (e2) {
|
|
3681
3700
|
console.error("Failed to create WebSocket:", e2);
|
|
3682
3701
|
const error = err_nice_transport_ws.fromId("ws_create_failed" /* ws_create_failed */, {
|
|
@@ -3701,7 +3720,10 @@ class TransportWebSocket extends Transport {
|
|
|
3701
3720
|
});
|
|
3702
3721
|
this.websocket.addEventListener("message", (event) => {
|
|
3703
3722
|
if (typeof event.data === "string") {
|
|
3704
|
-
this.
|
|
3723
|
+
const response = this._customMessageSerde?.deserialize?.(event.data) ?? this.handlePureActionResponseMessage(event.data);
|
|
3724
|
+
if (response) {
|
|
3725
|
+
this.handleResponse(response);
|
|
3726
|
+
}
|
|
3705
3727
|
}
|
|
3706
3728
|
});
|
|
3707
3729
|
this.websocket.addEventListener("close", (event) => {
|
|
@@ -3773,7 +3795,23 @@ class ConnectionConfig {
|
|
|
3773
3795
|
async dispatch(primed, defaultTimeout) {
|
|
3774
3796
|
const timeout = this.config.defaultTimeout ?? defaultTimeout;
|
|
3775
3797
|
const initializingWaiters = [];
|
|
3798
|
+
const unavailableTransports = [];
|
|
3776
3799
|
for (const transport of this._transports) {
|
|
3800
|
+
const isAvailable = transport.filterUsage(primed);
|
|
3801
|
+
if (isAvailable instanceof Promise) {
|
|
3802
|
+
try {
|
|
3803
|
+
if (!await isAvailable) {
|
|
3804
|
+
unavailableTransports.push(transport);
|
|
3805
|
+
continue;
|
|
3806
|
+
}
|
|
3807
|
+
} catch {
|
|
3808
|
+
unavailableTransports.push(transport);
|
|
3809
|
+
continue;
|
|
3810
|
+
}
|
|
3811
|
+
} else if (!isAvailable) {
|
|
3812
|
+
unavailableTransports.push(transport);
|
|
3813
|
+
continue;
|
|
3814
|
+
}
|
|
3777
3815
|
const statusInfo = transport.checkAndPrepare();
|
|
3778
3816
|
if (statusInfo.status === "ready" /* ready */) {
|
|
3779
3817
|
return transport.makeRequest(primed, timeout);
|
|
@@ -3788,6 +3826,11 @@ class ConnectionConfig {
|
|
|
3788
3826
|
}
|
|
3789
3827
|
}
|
|
3790
3828
|
if (initializingWaiters.length === 0) {
|
|
3829
|
+
if (unavailableTransports.length > 0) {
|
|
3830
|
+
throw err_nice_transport.fromId("not_available" /* not_available */, {
|
|
3831
|
+
transportCount: unavailableTransports.length
|
|
3832
|
+
});
|
|
3833
|
+
}
|
|
3791
3834
|
throw err_nice_transport.fromId("not_found" /* not_found */, {
|
|
3792
3835
|
actionId: primed.id
|
|
3793
3836
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { NiceActionSchema } from "../ActionSchema/NiceActionSchema";
|
|
2
2
|
import type { INiceActionErrorDeclaration, TTransportedValue } from "../ActionSchema/NiceActionSchema.types";
|
|
3
|
-
export type MaybePromise<T> = T | Promise<T>;
|
|
4
3
|
export type TPossibleDomainId = string;
|
|
5
4
|
export type TPossibleDomainIdList = [TPossibleDomainId, ...TPossibleDomainId[]];
|
|
6
5
|
export type TNiceActionDomainSchema = Record<string, NiceActionSchema<TTransportedValue<any, any>, TTransportedValue<any, any>, readonly INiceActionErrorDeclaration<any, any>[]>>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { MaybePromise } from "../../..";
|
|
1
2
|
import type { NiceActionPrimed } from "../../../NiceAction/NiceActionPrimed";
|
|
2
3
|
import type { NiceActionResponse } from "../../../NiceAction/NiceActionResponse";
|
|
3
4
|
import { type ITransportPendingRequest, type TActionTransportDef, type TTransportStatusInfo } from "./Transport.types";
|
|
@@ -6,8 +7,10 @@ export declare abstract class Transport<DEF extends TActionTransportDef> {
|
|
|
6
7
|
readonly type: DEF["type"];
|
|
7
8
|
readonly requestResolvers: Map<string, ITransportPendingRequest>;
|
|
8
9
|
protected abstract _status: TTransportStatusInfo;
|
|
10
|
+
protected _filterUsage?: (primed: NiceActionPrimed<any>) => MaybePromise<boolean>;
|
|
9
11
|
constructor(def: DEF);
|
|
10
12
|
get status(): TTransportStatusInfo;
|
|
13
|
+
filterUsage(primed: NiceActionPrimed<any>): MaybePromise<boolean>;
|
|
11
14
|
checkAndPrepare(): TTransportStatusInfo;
|
|
12
15
|
protected abstract send(primed: NiceActionPrimed<any>): Promise<void>;
|
|
13
16
|
abstract disconnect(): void;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import type { NiceError } from "@nice-code/error";
|
|
1
|
+
import type { MaybePromise, NiceError } from "@nice-code/error";
|
|
2
|
+
import type { INiceActionPrimed_JsonObject, TNiceActionResponse_JsonObject } from "../../../NiceAction/NiceAction.types";
|
|
2
3
|
import type { NiceActionPrimed } from "../../../NiceAction/NiceActionPrimed";
|
|
3
4
|
import type { NiceActionResponse } from "../../../NiceAction/NiceActionResponse";
|
|
4
5
|
import type { Transport } from "./Transport";
|
|
5
6
|
export declare enum ETransportType {
|
|
6
7
|
ws = "ws",
|
|
7
|
-
http = "http"
|
|
8
|
+
http = "http",
|
|
9
|
+
custom = "custom"
|
|
8
10
|
}
|
|
9
11
|
export declare enum ETransportStatus {
|
|
10
12
|
uninitialized = "uninitialized",
|
|
@@ -31,16 +33,34 @@ export type TTransportStatusInfo = ITransportStatusInfo_Base<ETransportStatus.un
|
|
|
31
33
|
export interface IActionTransport_Base {
|
|
32
34
|
/** Per-transport timeout override (ms) */
|
|
33
35
|
timeout?: number;
|
|
36
|
+
filterUsage?: (primed: NiceActionPrimed<any>) => MaybePromise<boolean>;
|
|
37
|
+
}
|
|
38
|
+
export interface ICustomWebsocketMessageSerde {
|
|
39
|
+
serialize?: (primedJson: INiceActionPrimed_JsonObject<any>) => string;
|
|
40
|
+
deserialize?: (message: string) => TNiceActionResponse_JsonObject<any>;
|
|
34
41
|
}
|
|
35
42
|
export interface IActionTransportDef_Ws extends IActionTransport_Base {
|
|
36
43
|
type: ETransportType.ws;
|
|
37
|
-
createWebSocket: () => Promise<
|
|
44
|
+
createWebSocket: () => Promise<{
|
|
45
|
+
ws: WebSocket;
|
|
46
|
+
customMessageSerde?: ICustomWebsocketMessageSerde;
|
|
47
|
+
}>;
|
|
38
48
|
}
|
|
39
49
|
export interface IActionTransportDef_Http extends IActionTransport_Base {
|
|
40
50
|
type: ETransportType.http;
|
|
41
51
|
url: string;
|
|
42
52
|
}
|
|
43
|
-
export
|
|
53
|
+
export interface ICustomActionTransport {
|
|
54
|
+
checkAndPrepare: () => TTransportStatusInfo;
|
|
55
|
+
handleAction: (primed: NiceActionPrimed<any>, onResponse: (response: NiceActionResponse<any>) => void) => Promise<void>;
|
|
56
|
+
onDisconnect: () => void;
|
|
57
|
+
}
|
|
58
|
+
export interface IActionTransportDef_Custom extends IActionTransport_Base {
|
|
59
|
+
type: ETransportType.custom;
|
|
60
|
+
initialStatus: TTransportStatusInfo;
|
|
61
|
+
createTransport: () => ICustomActionTransport;
|
|
62
|
+
}
|
|
63
|
+
export type TActionTransportDef = IActionTransportDef_Ws | IActionTransportDef_Http | IActionTransportDef_Custom;
|
|
44
64
|
export interface ITransportPendingRequest {
|
|
45
65
|
type: ETransportType;
|
|
46
66
|
resolve: (response: NiceActionResponse<any>) => void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { NiceActionPrimed } from "../../../NiceAction/NiceActionPrimed";
|
|
2
|
+
import { Transport } from "./Transport";
|
|
3
|
+
import { type IActionTransportDef_Custom, type TTransportStatusInfo } from "./Transport.types";
|
|
4
|
+
export declare class TransportCustom extends Transport<IActionTransportDef_Custom> {
|
|
5
|
+
readonly abortControllers: Map<string, AbortController>;
|
|
6
|
+
protected _status: TTransportStatusInfo;
|
|
7
|
+
private _customTransport;
|
|
8
|
+
constructor(def: IActionTransportDef_Custom);
|
|
9
|
+
checkAndPrepare(): TTransportStatusInfo;
|
|
10
|
+
send(primed: NiceActionPrimed<any>): Promise<void>;
|
|
11
|
+
disconnect(): void;
|
|
12
|
+
}
|
package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/TransportWebSocket.d.ts
CHANGED
|
@@ -4,10 +4,12 @@ import { type IActionTransportDef_Ws, type TTransportStatusInfo } from "./Transp
|
|
|
4
4
|
export declare class TransportWebSocket extends Transport<IActionTransportDef_Ws> {
|
|
5
5
|
websocket?: WebSocket;
|
|
6
6
|
protected _status: TTransportStatusInfo;
|
|
7
|
+
private _customMessageSerde?;
|
|
7
8
|
constructor(def: IActionTransportDef_Ws);
|
|
8
9
|
checkAndPrepare(): TTransportStatusInfo;
|
|
9
10
|
private startInitializing;
|
|
10
|
-
private
|
|
11
|
+
private handlePureActionResponseMessage;
|
|
12
|
+
private handleResponse;
|
|
11
13
|
private rejectPendingWebSocketRequests;
|
|
12
14
|
private _connect;
|
|
13
15
|
protected send(primed: NiceActionPrimed<any>): Promise<void>;
|
package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/err_nice_transport.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare enum EErrId_NiceTransport {
|
|
2
2
|
timeout = "timeout",
|
|
3
3
|
not_found = "not_found",
|
|
4
|
+
not_available = "not_available",
|
|
4
5
|
initialization_failed = "initialization_failed",
|
|
5
6
|
send_failed = "send_failed",
|
|
6
7
|
invalid_action_response = "invalid_action_response"
|
|
@@ -17,6 +18,9 @@ export declare const err_nice_transport: import("@nice-code/error").NiceErrorDom
|
|
|
17
18
|
routeKey?: string;
|
|
18
19
|
tag?: string;
|
|
19
20
|
}, import("@nice-code/error").JSONSerializableValue>;
|
|
21
|
+
not_available: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
22
|
+
transportCount: number;
|
|
23
|
+
}, import("@nice-code/error").JSONSerializableValue>;
|
|
20
24
|
initialization_failed: import("@nice-code/error").INiceErrorIdMetadata<{
|
|
21
25
|
actionId: string;
|
|
22
26
|
routeKey?: string;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { INiceActionDomain,
|
|
1
|
+
import type { INiceActionDomain, TInferOutputFromSchema } from "../../ActionDomain/NiceActionDomain.types";
|
|
2
2
|
import type { INiceAction, TNiceActionResponse_JsonObject } from "../../NiceAction/NiceAction.types";
|
|
3
3
|
import type { TDistributedDomainActions } from "../../NiceAction/NiceActionCombined.types";
|
|
4
4
|
import type { NiceActionPrimed } from "../../NiceAction/NiceActionPrimed";
|
|
5
5
|
import type { NiceActionResponse } from "../../NiceAction/NiceActionResponse";
|
|
6
|
+
import type { MaybePromise } from "../../utils/maybePromise";
|
|
6
7
|
import type { IRuntimeEnvironmentMeta } from "../ActionRuntimeEnvironment.types";
|
|
7
8
|
export type TAtLeastOne<T extends object> = {
|
|
8
9
|
[K in keyof T]-?: Required<Pick<T, K>> & Partial<Omit<T, K>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { INiceActionDomain
|
|
1
|
+
import type { INiceActionDomain } from "../../ActionDomain/NiceActionDomain.types";
|
|
2
|
+
import type { MaybePromise } from "../../utils/maybePromise";
|
|
2
3
|
import type { INiceAction } from "../NiceAction.types";
|
|
3
4
|
import type { TNarrowActionType } from "../NiceActionCombined.types";
|
|
4
5
|
type TMatchHandler<A extends INiceAction<any>> = (action: A) => MaybePromise<void>;
|
package/build/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { createActionRootDomain } from "./ActionDomain/helpers/createRootActionDomain";
|
|
2
2
|
export { NiceActionDomain } from "./ActionDomain/NiceActionDomain";
|
|
3
|
-
export type { INiceActionDomain, INiceActionDomainChildOptions, INiceActionRootDomain,
|
|
3
|
+
export type { INiceActionDomain, INiceActionDomainChildOptions, INiceActionRootDomain, TDomainActionId, TInferInputFromSchema, TInferOutputFromSchema, TNiceActionDomainChildDef, TNiceActionDomainSchema, TPossibleDomainId, TPossibleDomainIdList, } from "./ActionDomain/NiceActionDomain.types";
|
|
4
4
|
export { NiceActionRootDomain } from "./ActionDomain/RootDomain/NiceActionRootDomain";
|
|
5
5
|
export { ActionConnect } from "./ActionRuntimeEnvironment/ActionConnect/ActionConnect";
|
|
6
6
|
export * from "./ActionRuntimeEnvironment/ActionConnect/ActionConnect.types";
|
|
@@ -30,3 +30,4 @@ export { NiceActionPrimed } from "./NiceAction/NiceActionPrimed";
|
|
|
30
30
|
export { NiceActionResponse } from "./NiceAction/NiceActionResponse";
|
|
31
31
|
export * from "./utils/isActionResponseJsonObject";
|
|
32
32
|
export * from "./utils/isPrimedActionJsonObject";
|
|
33
|
+
export * from "./utils/maybePromise";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type MaybePromise<T> = T | Promise<T>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nice-code/action",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"build-types": "tsc --project tsconfig.build.json"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@nice-code/error": "0.1.
|
|
36
|
-
"@nice-code/common-errors": "0.1.
|
|
35
|
+
"@nice-code/error": "0.1.2",
|
|
36
|
+
"@nice-code/common-errors": "0.1.2",
|
|
37
37
|
"@standard-schema/spec": "^1.1.0",
|
|
38
38
|
"http-status-codes": "^2.3.0",
|
|
39
39
|
"nanoid": "^5.1.9",
|