@nice-code/action 0.0.21 → 0.1.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.
Files changed (49) hide show
  1. package/README.md +410 -0
  2. package/build/index.js +1148 -749
  3. package/build/react-query/index.js +170 -45
  4. package/build/types/ActionDomain/NiceActionDomain.d.ts +18 -46
  5. package/build/types/ActionDomain/NiceActionDomain.types.d.ts +9 -45
  6. package/build/types/ActionDomain/NiceActionDomainBase.d.ts +14 -0
  7. package/build/types/ActionDomain/RootDomain/NiceActionRootDomain.d.ts +22 -0
  8. package/build/types/ActionDomain/helpers/createRootActionDomain.d.ts +5 -0
  9. package/build/types/ActionRuntimeEnvironment/ActionConnect/ActionConnect.d.ts +24 -0
  10. package/build/types/ActionRuntimeEnvironment/ActionConnect/ActionConnect.types.d.ts +15 -0
  11. package/build/types/ActionRuntimeEnvironment/ActionConnect/ConnectionConfig/ConnectionConfig.d.ts +12 -0
  12. package/build/types/ActionRuntimeEnvironment/ActionConnect/ConnectionConfig/ConnectionConfig.types.d.ts +6 -0
  13. package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/Transport.d.ts +16 -0
  14. package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/Transport.types.d.ts +50 -0
  15. package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/TransportHttp.d.ts +9 -0
  16. package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/TransportWebSocket.d.ts +15 -0
  17. package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/err_nice_transport.d.ts +34 -0
  18. package/build/types/ActionRuntimeEnvironment/ActionConnect/Transport/err_nice_transport_ws.d.ts +18 -0
  19. package/build/types/ActionRuntimeEnvironment/ActionConnect/err_nice_connect.d.ts +5 -0
  20. package/build/types/ActionRuntimeEnvironment/ActionHandler/ActionHandler.d.ts +80 -0
  21. package/build/types/ActionRuntimeEnvironment/ActionHandler/ActionHandler.types.d.ts +68 -0
  22. package/build/types/ActionRuntimeEnvironment/ActionRuntimeEnvironment.d.ts +32 -0
  23. package/build/types/ActionRuntimeEnvironment/ActionRuntimeEnvironment.types.d.ts +15 -0
  24. package/build/types/ActionRuntimeEnvironment/utils/getAssumedRuntimeEnvironment.d.ts +2 -0
  25. package/build/types/ActionSchema/NiceActionSchema.d.ts +11 -7
  26. package/build/types/ActionSchema/NiceActionSchema.types.d.ts +1 -1
  27. package/build/types/NiceAction/MatchAction/MatchAction.d.ts +26 -0
  28. package/build/types/NiceAction/NiceAction.d.ts +19 -21
  29. package/build/types/NiceAction/NiceAction.enums.d.ts +5 -0
  30. package/build/types/NiceAction/NiceAction.types.d.ts +8 -11
  31. package/build/types/NiceAction/NiceActionCombined.types.d.ts +10 -0
  32. package/build/types/NiceAction/NiceActionPrimed.d.ts +19 -36
  33. package/build/types/NiceAction/NiceActionResponse.d.ts +15 -6
  34. package/build/types/NiceAction/utils/isNiceActionInstance.d.ts +3 -0
  35. package/build/types/errors/err_nice_action.d.ts +34 -12
  36. package/build/types/index.d.ts +22 -8
  37. package/build/types/react-query/index.d.ts +8 -10
  38. package/package.json +8 -6
  39. package/build/types/ActionDomain/createActionDomain.d.ts +0 -5
  40. package/build/types/ActionRequestResponse/ActionRequester/NiceActionRequester.d.ts +0 -31
  41. package/build/types/ActionRequestResponse/ActionResponder/NiceActionResponder.d.ts +0 -49
  42. package/build/types/ActionRequestResponse/ActionResponder/NiceActionResponder.types.d.ts +0 -7
  43. package/build/types/ActionRequestResponse/ActionResponder/NiceActionResponderEnvironment.d.ts +0 -42
  44. package/build/types/NiceAction/ActionSchema/NiceActionSchema.d.ts +0 -99
  45. package/build/types/NiceAction/ActionSchema/NiceActionSchema.types.d.ts +0 -31
  46. package/build/types/NiceAction/ActionSchema/NiceActionSchemaBuilder.d.ts +0 -1
  47. package/build/types/NiceAction/ActionSchema/action.d.ts +0 -2
  48. package/build/types/NiceAction/NiceActionPrimed.schema.d.ts +0 -8
  49. package/build/types/test/nice_action_test_schema.d.ts +0 -30
@@ -0,0 +1,14 @@
1
+ import type { TExecutionAndResponseListeners } from "../ActionRuntimeEnvironment/ActionHandler/ActionHandler.types";
2
+ import type { INiceActionDomain } from "./NiceActionDomain.types";
3
+ export declare abstract class NiceActionDomainBase<ACT_DOM extends INiceActionDomain = INiceActionDomain> implements INiceActionDomain<ACT_DOM["allDomains"], ACT_DOM["actions"]> {
4
+ readonly domain: ACT_DOM["domain"];
5
+ readonly allDomains: ACT_DOM["allDomains"];
6
+ readonly actions: ACT_DOM["actions"];
7
+ protected _listeners: TExecutionAndResponseListeners<ACT_DOM>[];
8
+ constructor(definition: ACT_DOM);
9
+ /**
10
+ * Add an observer that is called after every action dispatched through this domain.
11
+ * Returns an unsubscribe function — call it to remove the listener.
12
+ */
13
+ addActionListener(listener: TExecutionAndResponseListeners<ACT_DOM>): () => void;
14
+ }
@@ -0,0 +1,22 @@
1
+ import type { IActionHandlerInputs } from "../../ActionRuntimeEnvironment/ActionHandler/ActionHandler.types";
2
+ import type { ActionRuntimeEnvironment } from "../../ActionRuntimeEnvironment/ActionRuntimeEnvironment";
3
+ import type { IRuntimeEnvironmentMeta } from "../../ActionRuntimeEnvironment/ActionRuntimeEnvironment.types";
4
+ import type { NiceActionPrimed } from "../../NiceAction/NiceActionPrimed";
5
+ import { NiceActionDomain } from "../NiceActionDomain";
6
+ import type { INiceActionDomainChildOptions, INiceActionRootDomain, TNiceActionDomainChildDef } from "../NiceActionDomain.types";
7
+ import { NiceActionDomainBase } from "../NiceActionDomainBase";
8
+ export declare class NiceActionRootDomain<ROOT_DOM extends INiceActionRootDomain = INiceActionRootDomain> extends NiceActionDomainBase<ROOT_DOM> {
9
+ readonly domainDefinition: {
10
+ domain: ROOT_DOM["domain"];
11
+ };
12
+ private _runtimeEnvironment?;
13
+ constructor(domainDefinition: {
14
+ domain: ROOT_DOM["domain"];
15
+ });
16
+ getEnvironmentMeta(): IRuntimeEnvironmentMeta;
17
+ createChildDomain<SUB_DOM extends INiceActionDomainChildOptions>(subDomainDef: SUB_DOM & {
18
+ [K in Exclude<keyof SUB_DOM, keyof INiceActionDomainChildOptions>]: never;
19
+ }): NiceActionDomain<TNiceActionDomainChildDef<ROOT_DOM, SUB_DOM>>;
20
+ setRuntimeEnvironment(runtime: ActionRuntimeEnvironment): this;
21
+ _executeAction<P extends NiceActionPrimed<any, any, any>>(primed: P, { actionMeta, listeners, }: IActionHandlerInputs<P extends NiceActionPrimed<infer DOM, any, any> ? DOM : never>): Promise<unknown>;
22
+ }
@@ -0,0 +1,5 @@
1
+ import type { INiceActionRootDomain } from "../NiceActionDomain.types";
2
+ import { NiceActionRootDomain } from "../RootDomain/NiceActionRootDomain";
3
+ export declare const createActionRootDomain: <ID extends string>(definition: {
4
+ domain: ID;
5
+ }) => NiceActionRootDomain<INiceActionRootDomain<ID>>;
@@ -0,0 +1,24 @@
1
+ import type { NiceActionDomain } from "../../ActionDomain/NiceActionDomain";
2
+ import type { INiceActionDomain } from "../../ActionDomain/NiceActionDomain.types";
3
+ import type { NiceActionPrimed } from "../../NiceAction/NiceActionPrimed";
4
+ import type { NiceActionResponse } from "../../NiceAction/NiceActionResponse";
5
+ import { EActionHandlerType, type IActionHandler, type TMatchHandlerKey } from "../ActionHandler/ActionHandler.types";
6
+ import type { IActionConnectConfig, IActionConnectRoute } from "./ActionConnect.types";
7
+ import { ConnectionConfig } from "./ConnectionConfig/ConnectionConfig";
8
+ export declare class ActionConnect<TRANS_KEY extends string = never> implements IActionHandler {
9
+ readonly tag: string | "_";
10
+ readonly handlerType = EActionHandlerType.connect;
11
+ readonly cuid: string;
12
+ private _config;
13
+ private _connections;
14
+ private _connectionByMatchKey;
15
+ private _handlerKeys;
16
+ constructor(connectionConfigs: Array<ConnectionConfig<TRANS_KEY | undefined>>, config?: IActionConnectConfig);
17
+ get allHandlerKeys(): TMatchHandlerKey[];
18
+ routeDomain<DOM extends INiceActionDomain>(domain: NiceActionDomain<DOM>, route?: IActionConnectRoute<DOM, TRANS_KEY>): this;
19
+ routeAction<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string>(domain: NiceActionDomain<DOM>, id: ID, route?: IActionConnectRoute<DOM, TRANS_KEY, ID>): this;
20
+ routeActionIds<DOM extends INiceActionDomain, IDS extends ReadonlyArray<keyof DOM["actions"] & string>>(domain: NiceActionDomain<DOM>, ids: IDS, route?: IActionConnectRoute<DOM, TRANS_KEY, IDS[number]>): this;
21
+ dispatchAction(primed: NiceActionPrimed<any, any>): Promise<NiceActionResponse<any, any>>;
22
+ disconnect(): void;
23
+ private _dispatchViaRoute;
24
+ }
@@ -0,0 +1,15 @@
1
+ import type { NiceActionResponse } from "../..";
2
+ import type { INiceActionDomain } from "../../ActionDomain/NiceActionDomain.types";
3
+ export interface IActionConnectConfig {
4
+ tag?: string;
5
+ /** Default timeout for dispatching actions, in milliseconds. */
6
+ requestTimeout?: number;
7
+ }
8
+ /** Route config for a domain or action — controls which named transport handles the dispatch. */
9
+ export interface IActionConnectRoute<DOM extends INiceActionDomain, TKey extends string = string, ID extends keyof DOM["actions"] & string = keyof DOM["actions"] & string> {
10
+ /** Send via this named transport. Omit to use the default (unnamed) transport. */
11
+ routeKey?: TKey;
12
+ onResponse?: (response: {
13
+ [K in ID]: NiceActionResponse<DOM, K>;
14
+ }[ID]) => void;
15
+ }
@@ -0,0 +1,12 @@
1
+ import type { NiceActionPrimed } from "../../../NiceAction/NiceActionPrimed";
2
+ import type { NiceActionResponse } from "../../../NiceAction/NiceActionResponse";
3
+ import { type IConnectionConfig } from "./ConnectionConfig.types";
4
+ export declare class ConnectionConfig<K extends string | undefined = undefined> {
5
+ readonly config: IConnectionConfig;
6
+ readonly routeKey: K | undefined;
7
+ private _transports;
8
+ constructor(input: IConnectionConfig, routeKey?: K);
9
+ get connected(): boolean;
10
+ dispatch(primed: NiceActionPrimed<any>, defaultTimeout: number): Promise<NiceActionResponse<any>>;
11
+ disconnect(): void;
12
+ }
@@ -0,0 +1,6 @@
1
+ export { ETransportStatus, ETransportType, type IActionTransportDef_Http, type IActionTransportDef_Ws, type TActionTransportDef, } from "../Transport/Transport.types";
2
+ import type { TActionTransportDef } from "../Transport/Transport.types";
3
+ export interface IConnectionConfig {
4
+ defaultTimeout?: number;
5
+ transports: TActionTransportDef[];
6
+ }
@@ -0,0 +1,16 @@
1
+ import type { NiceActionPrimed } from "../../../NiceAction/NiceActionPrimed";
2
+ import type { NiceActionResponse } from "../../../NiceAction/NiceActionResponse";
3
+ import { type ITransportPendingRequest, type TActionTransportDef, type TTransportStatusInfo } from "./Transport.types";
4
+ export declare abstract class Transport<DEF extends TActionTransportDef> {
5
+ readonly def: DEF;
6
+ readonly type: DEF["type"];
7
+ readonly requestResolvers: Map<string, ITransportPendingRequest>;
8
+ protected abstract _status: TTransportStatusInfo;
9
+ constructor(def: DEF);
10
+ get status(): TTransportStatusInfo;
11
+ checkAndPrepare(): TTransportStatusInfo;
12
+ protected abstract send(primed: NiceActionPrimed<any>): Promise<void>;
13
+ abstract disconnect(): void;
14
+ protected respond(response: NiceActionResponse<any>): void;
15
+ makeRequest(primed: NiceActionPrimed<any>, connectionDefaultTimeout: number): Promise<NiceActionResponse<any>>;
16
+ }
@@ -0,0 +1,50 @@
1
+ import type { NiceError } from "@nice-code/error";
2
+ import type { NiceActionPrimed } from "../../../NiceAction/NiceActionPrimed";
3
+ import type { NiceActionResponse } from "../../../NiceAction/NiceActionResponse";
4
+ import type { Transport } from "./Transport";
5
+ export declare enum ETransportType {
6
+ ws = "ws",
7
+ http = "http"
8
+ }
9
+ export declare enum ETransportStatus {
10
+ uninitialized = "uninitialized",
11
+ initializing = "initializing",
12
+ ready = "ready",
13
+ failed = "failed"
14
+ }
15
+ export interface ITransportStatusInfo_Base<S extends ETransportStatus> {
16
+ status: S;
17
+ }
18
+ export interface ITransportStatusInfo_Failed extends ITransportStatusInfo_Base<ETransportStatus.failed> {
19
+ error: NiceError;
20
+ timeFailed: number;
21
+ }
22
+ export interface ITransportInitializationFinishedInfo {
23
+ transport: Transport<any>;
24
+ newStatus: ITransportStatusInfo_Base<ETransportStatus.ready> | ITransportStatusInfo_Failed;
25
+ }
26
+ export interface ITransportStatusInfo_Initializing extends ITransportStatusInfo_Base<ETransportStatus.initializing> {
27
+ timeStarted: number;
28
+ waitForInitialization: Promise<ITransportInitializationFinishedInfo>;
29
+ }
30
+ export type TTransportStatusInfo = ITransportStatusInfo_Base<ETransportStatus.uninitialized> | ITransportStatusInfo_Initializing | ITransportStatusInfo_Base<ETransportStatus.ready> | ITransportStatusInfo_Failed;
31
+ export interface IActionTransport_Base {
32
+ /** Per-transport timeout override (ms) */
33
+ timeout?: number;
34
+ }
35
+ export interface IActionTransportDef_Ws extends IActionTransport_Base {
36
+ type: ETransportType.ws;
37
+ createWebSocket: () => Promise<WebSocket>;
38
+ }
39
+ export interface IActionTransportDef_Http extends IActionTransport_Base {
40
+ type: ETransportType.http;
41
+ url: string;
42
+ }
43
+ export type TActionTransportDef = IActionTransportDef_Ws | IActionTransportDef_Http;
44
+ export interface ITransportPendingRequest {
45
+ type: ETransportType;
46
+ resolve: (response: NiceActionResponse<any>) => void;
47
+ reject: (error: unknown) => void;
48
+ timer: ReturnType<typeof setTimeout>;
49
+ primed: NiceActionPrimed<any>;
50
+ }
@@ -0,0 +1,9 @@
1
+ import type { NiceActionPrimed } from "../../../NiceAction/NiceActionPrimed";
2
+ import { Transport } from "./Transport";
3
+ import { type IActionTransportDef_Http, type TTransportStatusInfo } from "./Transport.types";
4
+ export declare class TransportHttp extends Transport<IActionTransportDef_Http> {
5
+ readonly abortControllers: Map<string, AbortController>;
6
+ protected _status: TTransportStatusInfo;
7
+ send(primed: NiceActionPrimed<any>): Promise<void>;
8
+ disconnect(): void;
9
+ }
@@ -0,0 +1,15 @@
1
+ import type { NiceActionPrimed } from "../../../NiceAction/NiceActionPrimed";
2
+ import { Transport } from "./Transport";
3
+ import { type IActionTransportDef_Ws, type TTransportStatusInfo } from "./Transport.types";
4
+ export declare class TransportWebSocket extends Transport<IActionTransportDef_Ws> {
5
+ websocket?: WebSocket;
6
+ protected _status: TTransportStatusInfo;
7
+ constructor(def: IActionTransportDef_Ws);
8
+ checkAndPrepare(): TTransportStatusInfo;
9
+ private startInitializing;
10
+ private handleMessage;
11
+ private rejectPendingWebSocketRequests;
12
+ private _connect;
13
+ protected send(primed: NiceActionPrimed<any>): Promise<void>;
14
+ disconnect(): void;
15
+ }
@@ -0,0 +1,34 @@
1
+ export declare enum EErrId_NiceTransport {
2
+ timeout = "timeout",
3
+ not_found = "not_found",
4
+ initialization_failed = "initialization_failed",
5
+ send_failed = "send_failed",
6
+ invalid_action_response = "invalid_action_response"
7
+ }
8
+ export declare const err_nice_transport: import("@nice-code/error").NiceErrorDomain<{
9
+ domain: string;
10
+ allDomains: [string, string, string, "err_nice"];
11
+ schema: {
12
+ timeout: import("@nice-code/error").INiceErrorIdMetadata<{
13
+ timeout: number;
14
+ }, import("@nice-code/error").JSONSerializableValue>;
15
+ not_found: import("@nice-code/error").INiceErrorIdMetadata<{
16
+ actionId: string;
17
+ routeKey?: string;
18
+ tag?: string;
19
+ }, import("@nice-code/error").JSONSerializableValue>;
20
+ initialization_failed: import("@nice-code/error").INiceErrorIdMetadata<{
21
+ actionId: string;
22
+ routeKey?: string;
23
+ tag?: string;
24
+ }, import("@nice-code/error").JSONSerializableValue>;
25
+ send_failed: import("@nice-code/error").INiceErrorIdMetadata<{
26
+ actionId: string;
27
+ httpStatusCode?: number;
28
+ message?: string;
29
+ }, import("@nice-code/error").JSONSerializableValue>;
30
+ invalid_action_response: import("@nice-code/error").INiceErrorIdMetadata<{
31
+ actionId: string;
32
+ }, import("@nice-code/error").JSONSerializableValue>;
33
+ };
34
+ }>;
@@ -0,0 +1,18 @@
1
+ export declare enum EErrId_NiceTransport_WebSocket {
2
+ ws_disconnected = "ws_disconnected",
3
+ ws_create_failed = "ws_create_failed",
4
+ ws_error = "ws_error"
5
+ }
6
+ export declare const err_nice_transport_ws: import("@nice-code/error").NiceErrorDomain<{
7
+ domain: string;
8
+ allDomains: [string, string, string, string, "err_nice"];
9
+ schema: {
10
+ ws_disconnected: import("@nice-code/error").INiceErrorIdMetadata<Record<string, never>, import("@nice-code/error").JSONSerializableValue>;
11
+ ws_create_failed: import("@nice-code/error").INiceErrorIdMetadata<{
12
+ originalError?: Error;
13
+ }, import("@nice-code/error").JSONSerializableValue>;
14
+ ws_error: import("@nice-code/error").INiceErrorIdMetadata<{
15
+ originalError?: Error;
16
+ }, import("@nice-code/error").JSONSerializableValue>;
17
+ };
18
+ }>;
@@ -0,0 +1,5 @@
1
+ export declare const err_nice_connect: import("@nice-code/error").NiceErrorDomain<{
2
+ domain: string;
3
+ allDomains: [string, string, "err_nice"];
4
+ schema: {};
5
+ }>;
@@ -0,0 +1,80 @@
1
+ import type { NiceActionDomain } from "../../ActionDomain/NiceActionDomain";
2
+ import type { INiceActionDomain } from "../../ActionDomain/NiceActionDomain.types";
3
+ import type { INiceAction } from "../../NiceAction/NiceAction.types";
4
+ import type { NiceActionPrimed } from "../../NiceAction/NiceActionPrimed";
5
+ import { NiceActionResponse } from "../../NiceAction/NiceActionResponse";
6
+ import { EActionHandlerType, type IActionHandler, type IActionHandlerInputs, type TExecutionAndResponseHandlers, type TExecutionAndResponseHandlers_Domain, type THandleActionResult, type TMatchHandlerKey } from "./ActionHandler.types";
7
+ export declare class ActionHandler implements IActionHandler {
8
+ readonly tag: string | "_";
9
+ readonly handlerType = EActionHandlerType.custom;
10
+ readonly cuid: string;
11
+ readonly _domains: Map<string, NiceActionDomain<any>>;
12
+ private _handlersByKey;
13
+ constructor(config?: IActionHandlerInputs["actionMeta"]);
14
+ get allHandlerKeys(): TMatchHandlerKey[];
15
+ private getHandlersForAction;
16
+ /**
17
+ * Register a handler for all actions in a domain.
18
+ * Receives the full primed action — use `matchAction()` to narrow to a specific action id.
19
+ * Useful for forwarding all domain actions to a remote endpoint.
20
+ * Lower priority than `forAction`.
21
+ */
22
+ forDomain<FOR_DOM extends INiceActionDomain>(domain: NiceActionDomain<FOR_DOM>, handlers: TExecutionAndResponseHandlers_Domain<FOR_DOM>): this;
23
+ /**
24
+ * Register a typed handler for a specific action ID.
25
+ * The handler receives the full primed action with narrowed input type.
26
+ * Takes priority over `forDomain` for the same domain.
27
+ */
28
+ forAction<ACT_DOM extends INiceActionDomain, ID extends keyof ACT_DOM["actions"] & string>(domain: NiceActionDomain<ACT_DOM>, id: ID, handlers: TExecutionAndResponseHandlers<INiceAction<ACT_DOM, ID>>): this;
29
+ /**
30
+ * Register a handler for multiple action IDs (first-match-wins among cases).
31
+ * Receives the full primed action narrowed to the union of those IDs.
32
+ * Use `act.coreAction.id` to branch on which action was dispatched.
33
+ */
34
+ forActionIds<ACT_DOM extends INiceActionDomain, IDS extends ReadonlyArray<keyof ACT_DOM["actions"] & string>>(domain: NiceActionDomain<ACT_DOM>, ids: IDS, handlers: TExecutionAndResponseHandlers<INiceAction<ACT_DOM, IDS[number]>>): this;
35
+ /**
36
+ * Register per-action handlers for a domain using a single map, without needing
37
+ * separate `forAction` calls. Unregistered action IDs are unaffected.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * handler.forDomainActionCases(userDomain, {
42
+ * getUser: { execution: (primed) => db.getUser(primed.input.userId) },
43
+ * deleteUser: { execution: (primed) => db.deleteUser(primed.input.userId) },
44
+ * });
45
+ * ```
46
+ */
47
+ forDomainActionCases<FOR_DOM extends INiceActionDomain>(domain: NiceActionDomain<FOR_DOM>, cases: {
48
+ [ID in keyof FOR_DOM["actions"] & string]?: TExecutionAndResponseHandlers<INiceAction<FOR_DOM, ID>>;
49
+ }): this;
50
+ private _tryHandleResponse;
51
+ protected _tryExecute(primed: NiceActionPrimed<any, any, any>): Promise<THandleActionResult>;
52
+ /**
53
+ * Dispatch a primed action. Throws if no execution handler matches.
54
+ */
55
+ dispatchAction(primed: NiceActionPrimed<any, any>): Promise<NiceActionResponse<any, any>>;
56
+ /**
57
+ * Dispatch a wire-format action (primed or resolved).
58
+ *
59
+ * Returns `{ handled: true, response }` when a handler matched, or
60
+ * `{ handled: false }` when no handler is registered for the action.
61
+ *
62
+ * Throws for structural errors only:
63
+ * - `domain_no_handler` — domain not known to this handler
64
+ * - `hydration_*` — the wire payload is malformed
65
+ * - `handle_wire_not_primed_or_response` — unknown wire type
66
+ *
67
+ * Execution errors thrown by handlers propagate as-is.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * app.post("/actions", async (req, res) => {
72
+ * const result = await handler.handleWire(req.body);
73
+ * if (result.handled) res.json(result.response.toJsonObject());
74
+ * else res.status(404).end();
75
+ * });
76
+ * ```
77
+ */
78
+ handleWire(wire: unknown): Promise<THandleActionResult>;
79
+ }
80
+ export declare const createHandler: (config?: IActionHandlerInputs["actionMeta"]) => ActionHandler;
@@ -0,0 +1,68 @@
1
+ import type { INiceActionDomain, MaybePromise, TInferOutputFromSchema } from "../../ActionDomain/NiceActionDomain.types";
2
+ import type { INiceAction, TNiceActionResponse_JsonObject } from "../../NiceAction/NiceAction.types";
3
+ import type { TDistributedDomainActions } from "../../NiceAction/NiceActionCombined.types";
4
+ import type { NiceActionPrimed } from "../../NiceAction/NiceActionPrimed";
5
+ import type { NiceActionResponse } from "../../NiceAction/NiceActionResponse";
6
+ import type { IRuntimeEnvironmentMeta } from "../ActionRuntimeEnvironment.types";
7
+ export type TAtLeastOne<T extends object> = {
8
+ [K in keyof T]-?: Required<Pick<T, K>> & Partial<Omit<T, K>>;
9
+ }[keyof T];
10
+ /**
11
+ * Format: `${matchTag | "_"}::${domainName}::${actionName | "_"}`
12
+ */
13
+ export type TMatchHandlerKey = `${string}::${string | "_"}`;
14
+ export interface IActionMetaInputs {
15
+ /**
16
+ * An action "tag" for the handler.
17
+ *
18
+ * This can be used to specify which handler should be used for a given
19
+ * action.
20
+ */
21
+ tag?: string;
22
+ meta?: any;
23
+ }
24
+ export interface IActionMetaInputsWithRuntime extends IActionMetaInputs {
25
+ runtime: IRuntimeEnvironmentMeta;
26
+ }
27
+ export type THandleActionExecutionFn<A extends INiceAction<any, any>> = A extends INiceAction<infer DOM, infer IDS> ? (primed: NiceActionPrimed<DOM, IDS>, envData: IActionMetaInputsWithRuntime) => MaybePromise<NiceActionResponse<DOM, IDS> | TNiceActionResponse_JsonObject<DOM, IDS> | TInferOutputFromSchema<DOM["actions"][IDS]>["Output"] | undefined> : never;
28
+ export type THandleActionResponseFn<A extends INiceAction<any, any>> = A extends INiceAction<infer DOM, infer IDS> ? (response: NiceActionResponse<DOM, IDS>, envData: IActionMetaInputsWithRuntime) => MaybePromise<NiceActionResponse<DOM, IDS> | TNiceActionResponse_JsonObject<DOM, IDS> | undefined> : never;
29
+ export type TExecutionAndResponseHandlers<A extends INiceAction<any, any>> = TAtLeastOne<{
30
+ execution: THandleActionExecutionFn<A>;
31
+ response: THandleActionResponseFn<A>;
32
+ }>;
33
+ export type THandleActionExecutionFn_Domain<DOM extends INiceActionDomain> = (primed: TDistributedDomainActions<NiceActionPrimed<DOM>, DOM>, envData: IActionMetaInputsWithRuntime) => MaybePromise<NiceActionResponse<DOM, keyof DOM["actions"] & string> | TNiceActionResponse_JsonObject<DOM, keyof DOM["actions"] & string> | TInferOutputFromSchema<DOM["actions"][keyof DOM["actions"] & string]>["Output"] | undefined>;
34
+ export type THandleActionResponseFn_Domain<DOM extends INiceActionDomain> = (response: TDistributedDomainActions<NiceActionResponse<DOM>, DOM>, envData: IActionMetaInputsWithRuntime) => MaybePromise<NiceActionResponse<DOM, keyof DOM["actions"] & string> | TNiceActionResponse_JsonObject<DOM, keyof DOM["actions"] & string> | undefined>;
35
+ export type TExecutionAndResponseHandlers_Domain<DOM extends INiceActionDomain> = TAtLeastOne<{
36
+ execution: THandleActionExecutionFn_Domain<DOM>;
37
+ response: THandleActionResponseFn_Domain<DOM>;
38
+ }>;
39
+ export type TListenToActionExecutionFn<DOM extends INiceActionDomain> = (primed: TDistributedDomainActions<NiceActionPrimed<DOM>, DOM>, envData: IActionMetaInputsWithRuntime) => void;
40
+ export type TListenToActionResponseFn<DOM extends INiceActionDomain> = (response: TDistributedDomainActions<NiceActionResponse<DOM>, DOM>, envData: IActionMetaInputsWithRuntime) => void;
41
+ export type TExecutionAndResponseListeners<DOM extends INiceActionDomain> = TAtLeastOne<{
42
+ execution: TListenToActionExecutionFn<DOM>;
43
+ response: TListenToActionResponseFn<DOM>;
44
+ }>;
45
+ export interface IActionHandlerInputs<DOM extends INiceActionDomain = INiceActionDomain> {
46
+ listeners?: TExecutionAndResponseListeners<DOM>[];
47
+ actionMeta: IActionMetaInputs;
48
+ }
49
+ export type THandleActionResult = {
50
+ handled: true;
51
+ response: NiceActionResponse<any, any>;
52
+ } | {
53
+ handled: false;
54
+ };
55
+ export type TStoredHandlers<A extends INiceAction<any, any> = INiceAction<any, any>> = {
56
+ execution?: THandleActionExecutionFn<A>;
57
+ response?: THandleActionResponseFn<A>;
58
+ };
59
+ export declare enum EActionHandlerType {
60
+ connect = "connect",
61
+ custom = "custom"
62
+ }
63
+ export interface IActionHandler {
64
+ cuid: string;
65
+ handlerType: EActionHandlerType;
66
+ allHandlerKeys: TMatchHandlerKey[];
67
+ dispatchAction: (primed: NiceActionPrimed<any, any>) => Promise<NiceActionResponse<any, any>>;
68
+ }
@@ -0,0 +1,32 @@
1
+ import type { INiceAction } from "../NiceAction/NiceAction.types";
2
+ import type { IActionHandler, TStoredHandlers } from "./ActionHandler/ActionHandler.types";
3
+ import type { IActionRuntimeEnvironment_JsonObject, IRuntimeMeta } from "./ActionRuntimeEnvironment.types";
4
+ interface IActionRuntimeEnvironment_Constructor_Input {
5
+ envId: string;
6
+ }
7
+ export declare class ActionRuntimeEnvironment {
8
+ readonly envId: string;
9
+ /**
10
+ * A unique identifier for this runtime environment instance.
11
+ *
12
+ * Format: `${envId}::${randomSuffix}` where `envId` is the runtime static ID and `randomSuffix` is a short random
13
+ * string to distinguish multiple instances of the same runtime.
14
+ */
15
+ readonly memCuid: string;
16
+ readonly timeCreated: number;
17
+ readonly runtimeInfo: IRuntimeMeta;
18
+ private _handlersByTag;
19
+ private _defaultHandlers;
20
+ constructor(input: IActionRuntimeEnvironment_Constructor_Input);
21
+ addHandlers(handlers: IActionHandler[]): this;
22
+ setDefaultHandler(handler: TStoredHandlers, tag?: string): this;
23
+ getDefaultHandler(tag?: string): TStoredHandlers | undefined;
24
+ /**
25
+ * Return the first handler registered for the given matchTag, or undefined
26
+ * if none has been registered.
27
+ */
28
+ getHandlerForAction(action: Pick<INiceAction<any, any>, "domain" | "id">, tag?: string): IActionHandler | undefined;
29
+ toJsonObject(): IActionRuntimeEnvironment_JsonObject;
30
+ }
31
+ export declare const createActionRuntime: (config: IActionRuntimeEnvironment_Constructor_Input) => ActionRuntimeEnvironment;
32
+ export {};
@@ -0,0 +1,15 @@
1
+ import type { RuntimeName } from "std-env";
2
+ export interface IRuntimeMeta {
3
+ assumed: boolean;
4
+ runtimeName: RuntimeName;
5
+ }
6
+ export interface IActionRuntimeEnvironment_JsonObject {
7
+ envId: string;
8
+ memCuid: string;
9
+ timeCreated: number;
10
+ runtimeInfo: IRuntimeMeta;
11
+ }
12
+ export interface IRuntimeEnvironmentMeta {
13
+ envId?: string;
14
+ runtimeInfo: IRuntimeMeta;
15
+ }
@@ -0,0 +1,2 @@
1
+ import type { IRuntimeMeta } from "../ActionRuntimeEnvironment.types";
2
+ export declare const getAssumedRuntimeInfo: () => IRuntimeMeta;
@@ -1,18 +1,18 @@
1
1
  import { err_cast_not_nice, type INiceErrorDomainProps, type InferNiceError, type JSONSerializableValue, type NiceErrorDomain } from "@nice-code/error";
2
2
  import type { StandardSchemaV1 } from "@standard-schema/spec";
3
- import type { INiceActionErrorDeclaration, TInferDeclaredErrors, TNiceActonSchemaInputOptions, TTransportedValue } from "./NiceActionSchema.types";
4
- export declare class NiceActionSchema<INPUT extends TTransportedValue<any, any> = TTransportedValue<any, any>, OUTPUT extends TTransportedValue<any, any> = TTransportedValue<any>, ERRORS extends readonly INiceActionErrorDeclaration<any, any>[] = readonly []> {
3
+ import type { INiceActionErrorDeclaration, TInferDeclaredErrors, TNiceActonSchemaOptions, TTransportedValue } from "./NiceActionSchema.types";
4
+ export declare class NiceActionSchema<INPUT extends TTransportedValue<any, any> = never, OUTPUT extends TTransportedValue<any, any> = never, ERRORS extends readonly INiceActionErrorDeclaration<any, any>[] = readonly []> {
5
5
  private _errorDeclarations;
6
6
  private inputOptions;
7
7
  private outputOptions;
8
- get inputSchema(): StandardSchemaV1;
9
- get outputSchema(): StandardSchemaV1;
8
+ get inputSchema(): StandardSchemaV1 | undefined;
9
+ get outputSchema(): StandardSchemaV1 | undefined;
10
10
  /**
11
11
  * Declare the input schema (JSON-native or with explicit SERDE type param).
12
12
  * For non-JSON-native inputs, prefer the 3-argument form below to avoid
13
13
  * needing explicit type parameters.
14
14
  */
15
- input<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_IN extends JSONSerializableValue = never>(options: TNiceActonSchemaInputOptions<VS, SERDE_IN>): NiceActionSchema<TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_IN>, OUTPUT, ERRORS>;
15
+ input<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_IN extends JSONSerializableValue = never>(options: TNiceActonSchemaOptions<VS, SERDE_IN>): NiceActionSchema<TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_IN>, OUTPUT, ERRORS>;
16
16
  /**
17
17
  * Declare the input schema with serialization via sequential parameters.
18
18
  * TypeScript infers SERDE_IN from `serialize`'s return type (left-to-right),
@@ -27,7 +27,7 @@ export declare class NiceActionSchema<INPUT extends TTransportedValue<any, any>
27
27
  * For non-JSON-native outputs, prefer the 3-argument form below to avoid
28
28
  * needing explicit type parameters.
29
29
  */
30
- output<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_OUT extends JSONSerializableValue = JSONSerializableValue>(options: TNiceActonSchemaInputOptions<VS, SERDE_OUT>): NiceActionSchema<INPUT, TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_OUT>, ERRORS>;
30
+ output<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_OUT extends JSONSerializableValue = JSONSerializableValue>(options: TNiceActonSchemaOptions<VS, SERDE_OUT>): NiceActionSchema<INPUT, TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_OUT>, ERRORS>;
31
31
  /**
32
32
  * Declare the output schema with serialization via sequential parameters.
33
33
  * TypeScript infers SERDE_OUT from `serialize`'s return type (left-to-right),
@@ -68,7 +68,11 @@ export declare class NiceActionSchema<INPUT extends TTransportedValue<any, any>
68
68
  validateInput(value: unknown, meta: {
69
69
  domain: string;
70
70
  actionId: string;
71
- }): Promise<INPUT[0]>;
71
+ }): INPUT[0];
72
+ validateOutput(value: unknown, meta: {
73
+ domain: string;
74
+ actionId: string;
75
+ }): OUTPUT[0];
72
76
  /**
73
77
  * Serialize raw output to a JSON-serializable form.
74
78
  */
@@ -6,7 +6,7 @@ export type TNiceActionSerializationDefinition<RAW_VAL = any, SERDE_VAL extends
6
6
  serialize: (value: RAW_VAL) => SERDE_VAL;
7
7
  deserialize: (value: SERDE_VAL) => RAW_VAL;
8
8
  };
9
- export type TNiceActonSchemaInputOptions<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_IN extends TNiceActionJsonSerializableValue = TNiceActionJsonSerializableValue> = StandardSchemaV1.InferInput<VS> extends TNiceActionJsonSerializableValue ? {
9
+ export type TNiceActonSchemaOptions<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_IN extends TNiceActionJsonSerializableValue = TNiceActionJsonSerializableValue> = StandardSchemaV1.InferInput<VS> extends TNiceActionJsonSerializableValue ? {
10
10
  schema: VS;
11
11
  serialization?: TNiceActionSerializationDefinition<StandardSchemaV1.InferInput<VS>, SERDE_IN>;
12
12
  } : {
@@ -0,0 +1,26 @@
1
+ import type { INiceActionDomain, MaybePromise } from "../../ActionDomain/NiceActionDomain.types";
2
+ import type { INiceAction } from "../NiceAction.types";
3
+ import type { TNarrowActionType } from "../NiceActionCombined.types";
4
+ type TMatchHandler<A extends INiceAction<any>> = (action: A) => MaybePromise<void>;
5
+ type THandlerForId<ACT extends INiceAction<any>> = (action: ACT) => MaybePromise<void>;
6
+ declare class MatchAction<ACT extends INiceAction<any>> {
7
+ readonly action: ACT;
8
+ private _entries;
9
+ private _otherwise?;
10
+ constructor(action: ACT);
11
+ with<D extends INiceActionDomain, ID extends keyof D["actions"] & string>(opts: {
12
+ domain: D;
13
+ id: ID;
14
+ handler: THandlerForId<TNarrowActionType<ACT, D, ID>>;
15
+ }): this;
16
+ with<D extends INiceActionDomain>(opts: {
17
+ domain: D;
18
+ handler: TMatchHandler<TNarrowActionType<ACT, D, keyof D["actions"] & string>>;
19
+ }): this;
20
+ otherwise(handler: TMatchHandler<ACT>): this;
21
+ private _findMatch;
22
+ run(): boolean;
23
+ runAsync(): Promise<boolean>;
24
+ }
25
+ export declare const matchAction: <ACT extends INiceAction<any>>(action: ACT) => MatchAction<ACT>;
26
+ export {};