@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
@@ -1,18 +1,20 @@
1
- import type { StandardSchemaV1 } from "@standard-schema/spec";
1
+ import type { JSONSerializableValue } from "@nice-code/error";
2
2
  import type { NiceActionDomain } from "../ActionDomain/NiceActionDomain";
3
3
  import type { INiceActionDomain, TInferInputFromSchema, TInferOutputFromSchema } from "../ActionDomain/NiceActionDomain.types";
4
+ import type { IActionMetaInputs } from "../ActionRuntimeEnvironment/ActionHandler/ActionHandler.types";
4
5
  import type { TInferActionError } from "../ActionSchema/NiceActionSchema";
5
- import { EActionState, type INiceAction, type INiceAction_JsonObject, type INiceActionPrimed_JsonObject, type NiceActionResult } from "./NiceAction.types";
6
+ import { EActionState } from "./NiceAction.enums";
7
+ import { type INiceAction, type INiceAction_JsonObject, type INiceActionPrimed_JsonObject, type TNiceActionResult } from "./NiceAction.types";
8
+ import type { TNarrowActionType } from "./NiceActionCombined.types";
6
9
  import { NiceActionPrimed } from "./NiceActionPrimed";
7
10
  import { NiceActionResponse } from "./NiceActionResponse";
8
- export declare class NiceAction<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string, SCH extends DOM["actions"][ID]> implements INiceAction<DOM, ID> {
11
+ export declare class NiceAction<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string = keyof DOM["actions"] & string, SCH extends DOM["actions"][ID] = DOM["actions"][ID]> implements INiceAction<DOM, ID> {
9
12
  readonly actionDomain: NiceActionDomain<DOM>;
10
13
  readonly schema: SCH;
11
- readonly id: ID;
12
14
  readonly type = EActionState.empty;
15
+ readonly id: ID;
13
16
  readonly domain: DOM["domain"];
14
17
  readonly allDomains: DOM["allDomains"];
15
- readonly _actionDomain: NiceActionDomain<DOM>;
16
18
  readonly timeCreated: number;
17
19
  readonly cuid: string;
18
20
  constructor(actionDomain: NiceActionDomain<DOM>, schema: SCH, id: ID, hydrationData?: Pick<INiceAction_JsonObject<DOM, ID>, "cuid" | "timeCreated">);
@@ -23,20 +25,12 @@ export declare class NiceAction<DOM extends INiceActionDomain, ID extends keyof
23
25
  toJsonObject(): INiceAction_JsonObject<DOM, ID>;
24
26
  toJsonString(): string;
25
27
  toHttpResponse(): Response;
26
- toValidationSchema(): StandardSchemaV1;
27
- is(action: unknown): action is NiceActionPrimed<DOM, ID, SCH>;
28
+ is<ACT extends INiceAction<any>>(action: ACT | unknown | null | undefined): action is TNarrowActionType<ACT, DOM, ID>;
28
29
  prime(input: TInferInputFromSchema<SCH>["Input"], hydrationData?: Pick<INiceActionPrimed_JsonObject<DOM, ID>, "timePrimed">): NiceActionPrimed<DOM, ID, SCH>;
29
- /**
30
- * Prime this action with input and immediately execute it through the domain handler or resolver.
31
- *
32
- * Pass `envId` to target a specific named handler/resolver registered on the domain via
33
- * `setActionHandler(h, { envId })` or `registerResolver(r, { envId })`.
34
- * Throws `action_environment_not_found` if no handler or resolver with that id exists.
35
- */
36
- execute(input: TInferInputFromSchema<SCH>["Input"], envId?: string): Promise<TInferOutputFromSchema<SCH>["Output"]>;
30
+ execute(input: TInferInputFromSchema<SCH>["Input"], meta?: IActionMetaInputs): Promise<TInferOutputFromSchema<SCH>["Output"]>;
37
31
  /**
38
32
  * Like `execute`, but catches thrown errors and returns a `NiceActionResult` discriminated union
39
- * instead of propagating. On success: `{ ok: true, value }`. On failure: `{ ok: false, error }`.
33
+ * instead of propagating. On success: `{ ok: true, output }`. On failure: `{ ok: false, error }`.
40
34
  *
41
35
  * The `error` type is the union of all `NiceError` types declared via `.throws()` on the schema,
42
36
  * plus `InferNiceError<typeof err_cast_not_nice>` as the always-present fallback.
@@ -45,22 +39,26 @@ export declare class NiceAction<DOM extends INiceActionDomain, ID extends keyof
45
39
  * ```ts
46
40
  * const result = await domain.action("getUser").executeSafe({ userId: "123" });
47
41
  * if (!result.ok) {
48
- * result.error.handleWith([
42
+ * result.error.handleWithSync([
49
43
  * forDomain(err_auth, (h) => res.status(401).end()),
50
44
  * ]);
51
45
  * return;
52
46
  * }
53
- * console.log(result.value);
47
+ * console.log(result.output); // typed as the action's OUTPUT
54
48
  * ```
55
49
  */
56
- executeSafe(input: TInferInputFromSchema<SCH>["Input"], envId?: string): Promise<NiceActionResult<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>>>;
50
+ executeSafe(input: TInferInputFromSchema<SCH>["Input"], meta?: IActionMetaInputs): Promise<TNiceActionResult<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>>>;
57
51
  /**
58
52
  * Prime this action with input, execute it, and return a `NiceActionResponse`
59
53
  * that carries both the original primed action (domain + actionId + input) and
60
- * the result (`{ ok: true, value }` or `{ ok: false, error }`).
54
+ * the result (`{ ok: true, output }` or `{ ok: false, error }`).
61
55
  *
62
56
  * The response can be serialized for cross-boundary transport via `toJsonObject()`.
63
57
  * Reconstruct on the receiving end with `domain.hydrateResponse(wire)`.
64
58
  */
65
- executeToResponse(input: TInferInputFromSchema<SCH>["Input"], envId?: string): Promise<NiceActionResponse<DOM, ID, SCH>>;
59
+ executeToResponse(input: TInferInputFromSchema<SCH>["Input"], meta?: IActionMetaInputs): Promise<NiceActionResponse<DOM, ID, SCH>>;
60
+ deserializeInput(serialized: JSONSerializableValue): TInferInputFromSchema<SCH>["Input"];
61
+ serializeInput(raw: TInferInputFromSchema<SCH>["Input"]): JSONSerializableValue;
62
+ validateInput(input: unknown): TInferInputFromSchema<SCH>["Input"];
63
+ validateOutput(output: unknown): TInferOutputFromSchema<SCH>["Output"];
66
64
  }
@@ -0,0 +1,5 @@
1
+ export declare enum EActionState {
2
+ empty = "empty",
3
+ primed = "primed",
4
+ resolved = "resolved"
5
+ }
@@ -1,12 +1,9 @@
1
1
  import type { INiceErrorJsonObject } from "@nice-code/error";
2
2
  import type { INiceActionDomain, TInferInputFromSchema, TInferOutputFromSchema } from "../ActionDomain/NiceActionDomain.types";
3
- export declare enum EActionState {
4
- empty = "empty",
5
- primed = "primed",
6
- response = "response"
7
- }
8
- export interface INiceAction<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string> {
3
+ import type { EActionState } from "./NiceAction.enums";
4
+ export interface INiceAction<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string = keyof DOM["actions"] & string> {
9
5
  id: ID;
6
+ type: EActionState;
10
7
  domain: DOM["domain"];
11
8
  allDomains: DOM["allDomains"];
12
9
  schema: DOM["actions"][ID];
@@ -35,22 +32,22 @@ export type INiceActionPrimed_JsonObject<DOM extends INiceActionDomain = INiceAc
35
32
  /**
36
33
  * Return type of `executeSafe` — a discriminated union of success and failure.
37
34
  *
38
- * - `{ ok: true; value: OUT }` — the action completed and returned `OUT`
35
+ * - `{ ok: true; output: OUT }` — the action completed and returned `OUT`
39
36
  * - `{ ok: false; error: ERR }` — the action threw; `ERR` is the declared error union
40
37
  *
41
38
  * @example
42
39
  * ```ts
43
40
  * const result = await domain.action("getUser").executeSafe({ userId: "123" });
44
41
  * if (!result.ok) {
45
- * result.error.handleWith([
42
+ * result.error.handleWithSync([
46
43
  * forDomain(err_auth, (h) => res.status(401).end()),
47
44
  * ]);
48
45
  * return;
49
46
  * }
50
- * console.log(result.value); // typed as the action's OUTPUT
47
+ * console.log(result.output); // typed as the action's OUTPUT
51
48
  * ```
52
49
  */
53
- export type NiceActionResult<OUT, ERR> = {
50
+ export type TNiceActionResult<OUT, ERR> = {
54
51
  ok: true;
55
52
  output: OUT;
56
53
  } | {
@@ -67,7 +64,7 @@ export type NiceActionResult<OUT, ERR> = {
67
64
  * Reconstructed by `NiceActionDomain.hydrateResponse()`.
68
65
  */
69
66
  export interface INiceActionResponse_JsonObject_Base<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string> extends Omit<INiceActionPrimed_JsonObject<DOM, ID>, "type"> {
70
- type: EActionState.response;
67
+ type: EActionState.resolved;
71
68
  timeResponded: number;
72
69
  }
73
70
  export type INiceActionResponse_JsonObject_Success<DOM extends INiceActionDomain = INiceActionDomain, ID extends keyof DOM["actions"] & string = keyof DOM["actions"] & string> = INiceActionResponse_JsonObject_Base<DOM, ID> & {
@@ -0,0 +1,10 @@
1
+ import type { INiceActionDomain } from "../ActionDomain/NiceActionDomain.types";
2
+ import type { NiceAction } from "./NiceAction";
3
+ import type { INiceAction } from "./NiceAction.types";
4
+ import type { NiceActionPrimed } from "./NiceActionPrimed";
5
+ import type { NiceActionResponse } from "./NiceActionResponse";
6
+ export type TNiceActionInstanceAny<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string = keyof DOM["actions"] & string> = NiceAction<DOM, ID, DOM["actions"][ID]> | NiceActionPrimed<DOM, ID, DOM["actions"][ID]> | NiceActionResponse<DOM, ID, DOM["actions"][ID]>;
7
+ export type TNarrowActionType<ACT extends INiceAction<any>, D extends INiceActionDomain, ID extends keyof D["actions"] & string = keyof D["actions"] & string> = ACT extends NiceActionResponse<any> ? NiceActionResponse<D, ID> : ACT extends NiceActionPrimed<any> ? NiceActionPrimed<D, ID> : ACT extends NiceAction<any> ? NiceAction<D, ID> : INiceAction<D, ID>;
8
+ export type TDistributedDomainActions<ACT extends INiceAction<any>, DOM extends INiceActionDomain> = {
9
+ [ID in keyof DOM["actions"] & string]: TNarrowActionType<ACT, DOM, ID>;
10
+ }[keyof DOM["actions"] & string];
@@ -1,17 +1,25 @@
1
1
  import type { INiceActionDomain, TInferInputFromSchema, TInferOutputFromSchema } from "../ActionDomain/NiceActionDomain.types";
2
+ import type { IActionMetaInputs } from "../ActionRuntimeEnvironment/ActionHandler/ActionHandler.types";
3
+ import type { IRuntimeEnvironmentMeta } from "../ActionRuntimeEnvironment/ActionRuntimeEnvironment.types";
2
4
  import type { TInferActionError } from "../ActionSchema/NiceActionSchema";
3
5
  import type { NiceAction } from "./NiceAction";
4
- import { EActionState, type INiceAction, type INiceActionPrimed_JsonObject, type NiceActionResult, type TNiceActionResponse_JsonObject } from "./NiceAction.types";
6
+ import { EActionState } from "./NiceAction.enums";
7
+ import { type INiceAction, type INiceActionPrimed_JsonObject, type TNiceActionResponse_JsonObject, type TNiceActionResult } from "./NiceAction.types";
5
8
  import { NiceActionResponse } from "./NiceActionResponse";
6
- export declare class NiceActionPrimed<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string, SCH extends DOM["actions"][ID]> implements Omit<INiceAction<DOM, ID>, "schema" | "cuid" | "timeCreated"> {
9
+ export declare class NiceActionPrimed<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string = keyof DOM["actions"] & string, SCH extends DOM["actions"][ID] = DOM["actions"][ID]> implements INiceAction<DOM, ID> {
7
10
  readonly coreAction: NiceAction<DOM, ID, SCH>;
8
- readonly input: TInferInputFromSchema<SCH>["Input"];
11
+ private _input;
9
12
  readonly type = EActionState.primed;
10
13
  readonly domain: DOM["domain"];
11
14
  readonly allDomains: DOM["allDomains"];
12
15
  readonly id: ID;
13
16
  readonly timePrimed: number;
14
- constructor(coreAction: NiceAction<DOM, ID, SCH>, input: TInferInputFromSchema<SCH>["Input"], hydrationData?: Pick<INiceActionPrimed_JsonObject<DOM, ID>, "timePrimed">);
17
+ readonly cuid: string;
18
+ readonly schema: SCH;
19
+ readonly timeCreated: number;
20
+ constructor(coreAction: NiceAction<DOM, ID, SCH>, _input: TInferInputFromSchema<SCH>["Input"], hydrationData?: Pick<INiceActionPrimed_JsonObject<DOM, ID>, "timePrimed">);
21
+ get input(): TInferInputFromSchema<SCH>["Input"];
22
+ getEnvironmentMeta(): IRuntimeEnvironmentMeta;
15
23
  /**
16
24
  * Serialize this primed action to a JSON-safe wire format.
17
25
  * The input is passed through the schema's serialize function if one is defined,
@@ -19,42 +27,17 @@ export declare class NiceActionPrimed<DOM extends INiceActionDomain, ID extends
19
27
  */
20
28
  toJsonObject(): INiceActionPrimed_JsonObject<DOM, ID>;
21
29
  toJsonString(): string;
30
+ hydratePrimeJson(wire: INiceActionPrimed_JsonObject<DOM, ID>): NiceActionPrimed<DOM, ID, SCH>;
31
+ hydrateResponseJson(wire: TNiceActionResponse_JsonObject<DOM, ID>): NiceActionResponse<DOM, ID, SCH>;
32
+ errorResponse(err: TInferActionError<SCH>): NiceActionResponse<DOM, ID, SCH>;
22
33
  toHttpResponse(): Response;
23
- setOutput(output: TInferOutputFromSchema<SCH>["Output"]): NiceActionResponse<DOM, ID, SCH>;
24
- /**
25
- * Process a wire response returned by a remote `NiceActionResponderEnvironment`.
26
- *
27
- * Deserializes the output using the schema's deserialization if defined, and throws
28
- * the error (via `castNiceError`) if the response indicates failure.
29
- *
30
- * Intended for use inside `NiceActionRequester` handlers that receive a
31
- * `TNiceActionResponse_JsonObject` from a network call, so the caller of `execute()`
32
- * always gets the raw output type without manually deserializing.
33
- *
34
- * @example
35
- * ```ts
36
- * dom.setActionRequester().forDomain(dom, async (act) => {
37
- * const wire = await fetch("/api/actions", {
38
- * method: "POST",
39
- * body: JSON.stringify(act.toJsonObject()),
40
- * }).then((r) => r.json());
41
- * return act.processResponse(wire);
42
- * });
43
- * ```
44
- */
45
- processResponse(wire: TNiceActionResponse_JsonObject): TInferOutputFromSchema<SCH>["Output"];
46
- /**
47
- * Re-execute this primed action through the domain handler or resolver.
48
- * Useful for deferred or cross-environment execution of a hydrated action.
49
- *
50
- * Pass `envId` to target a specific named handler/resolver on the domain.
51
- */
52
- execute(envId?: string): Promise<TInferOutputFromSchema<SCH>["Output"]>;
34
+ setResponse(...args: [TInferOutputFromSchema<SCH>["Output"]] extends [never] ? [] : [output: TInferOutputFromSchema<SCH>["Output"]]): NiceActionResponse<DOM, ID, SCH>;
35
+ execute(meta?: IActionMetaInputs): Promise<TInferOutputFromSchema<SCH>["Output"]>;
53
36
  /**
54
37
  * Like `execute`, but catches thrown errors and returns a `NiceActionResult` discriminated union
55
- * instead of propagating. On success: `{ ok: true, value }`. On failure: `{ ok: false, error }`.
38
+ * instead of propagating. On success: `{ ok: true, output }`. On failure: `{ ok: false, error }`.
56
39
  *
57
40
  * Mirrors `NiceAction.executeSafe` — useful when re-executing a hydrated primed action.
58
41
  */
59
- executeSafe(envId?: string): Promise<NiceActionResult<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>>>;
42
+ executeSafe(meta?: IActionMetaInputs): Promise<TNiceActionResult<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>>>;
60
43
  }
@@ -1,17 +1,23 @@
1
1
  import type { INiceActionDomain, TInferOutputFromSchema } from "../ActionDomain/NiceActionDomain.types";
2
+ import type { IRuntimeEnvironmentMeta } from "../ActionRuntimeEnvironment/ActionRuntimeEnvironment.types";
2
3
  import type { TInferActionError } from "../ActionSchema/NiceActionSchema";
3
4
  import type { NiceAction } from "./NiceAction";
4
- import { EActionState, type INiceAction, type NiceActionResult, type TNiceActionResponse_JsonObject } from "./NiceAction.types";
5
+ import { EActionState } from "./NiceAction.enums";
6
+ import { type INiceAction, type TNiceActionResponse_JsonObject, type TNiceActionResult } from "./NiceAction.types";
5
7
  import { NiceActionPrimed } from "./NiceActionPrimed";
6
- export declare class NiceActionResponse<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string, SCH extends DOM["actions"][ID]> implements Omit<INiceAction<DOM, ID>, "schema" | "cuid" | "timeCreated"> {
7
- readonly type = EActionState.response;
8
+ export declare class NiceActionResponse<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string = keyof DOM["actions"] & string, SCH extends DOM["actions"][ID] = DOM["actions"][ID]> implements INiceAction<DOM, ID> {
9
+ readonly type = EActionState.resolved;
8
10
  readonly domain: DOM["domain"];
9
11
  readonly allDomains: DOM["allDomains"];
10
12
  readonly id: ID;
11
13
  readonly primed: NiceActionPrimed<DOM, ID, SCH>;
12
- readonly result: NiceActionResult<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>>;
14
+ readonly result: TNiceActionResult<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>>;
13
15
  readonly timeResponded: number;
14
- constructor(primed: NiceActionPrimed<DOM, ID, SCH>, result: NiceActionResult<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>>, hydrationData?: Pick<TNiceActionResponse_JsonObject<DOM, ID>, "timeResponded">);
16
+ readonly cuid: string;
17
+ readonly schema: SCH;
18
+ readonly timeCreated: number;
19
+ constructor(primed: NiceActionPrimed<DOM, ID, SCH>, result: TNiceActionResult<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>>, hydrationData?: Pick<TNiceActionResponse_JsonObject<DOM, ID>, "timeResponded">);
20
+ getEnvironmentMeta(): IRuntimeEnvironmentMeta;
15
21
  /**
16
22
  * Serialize this response to a JSON-safe wire format.
17
23
  *
@@ -21,7 +27,10 @@ export declare class NiceActionResponse<DOM extends INiceActionDomain, ID extend
21
27
  */
22
28
  toJsonObject(): TNiceActionResponse_JsonObject;
23
29
  toJsonString(): string;
24
- toHttpResponse(): Response;
30
+ hydrateResponseJson(wire: TNiceActionResponse_JsonObject<DOM, ID>): NiceActionResponse<DOM, ID, SCH>;
31
+ toHttpResponse({ useErrorStatus }?: {
32
+ useErrorStatus?: boolean;
33
+ }): Response;
25
34
  }
26
35
  /**
27
36
  * Reconstruct a loosely-typed NiceActionResponse from its wire format.
@@ -0,0 +1,3 @@
1
+ import type { INiceAction } from "../NiceAction.types";
2
+ import type { TNarrowActionType } from "../NiceActionCombined.types";
3
+ export declare function isNiceActionInstance<ACT extends INiceAction<any>>(value: unknown | ACT): value is TNarrowActionType<ACT, any, any>;
@@ -1,16 +1,20 @@
1
- import type { EActionState } from "../NiceAction/NiceAction.types";
1
+ import type { EActionState } from "../NiceAction/NiceAction.enums";
2
2
  export declare enum EErrId_NiceAction {
3
3
  action_id_not_in_domain = "action_id_not_in_domain",
4
- domain_action_requester_conflict = "domain_action_handler_conflict",
4
+ domain_already_exists_in_hierarchy = "domain_already_exists_in_hierarchy",
5
5
  domain_no_handler = "domain_no_handler",
6
6
  hydration_domain_mismatch = "hydration_domain_mismatch",
7
7
  hydration_action_state_mismatch = "hydration_action_state_mismatch",
8
8
  hydration_action_id_not_found = "hydration_action_id_not_found",
9
- resolver_domain_not_registered = "resolver_domain_not_registered",
10
- resolver_action_not_registered = "resolver_action_not_registered",
11
- action_environment_not_found = "action_environment_not_found",
9
+ no_action_execution_handler = "no_action_execution_handler",
10
+ wire_action_not_primed_or_response = "wire_action_not_primed_or_response",
11
+ wire_not_action_data = "wire_not_action_data",
12
+ action_tag_handler_not_found = "action_tag_handler_not_found",
12
13
  environment_already_registered = "environment_already_registered",
13
- action_input_validation_failed = "action_input_validation_failed"
14
+ action_input_validation_failed = "action_input_validation_failed",
15
+ action_input_validation_promise = "action_input_validation_promise",
16
+ action_output_validation_failed = "action_output_validation_failed",
17
+ action_output_validation_promise = "action_output_validation_promise"
14
18
  }
15
19
  export declare const err_nice_action: import("@nice-code/error").NiceErrorDomain<{
16
20
  domain: string;
@@ -20,8 +24,10 @@ export declare const err_nice_action: import("@nice-code/error").NiceErrorDomain
20
24
  domain: string;
21
25
  actionId: string;
22
26
  }, import("@nice-code/error").JSONSerializableValue>;
23
- domain_action_handler_conflict: import("@nice-code/error").INiceErrorIdMetadata<{
27
+ domain_already_exists_in_hierarchy: import("@nice-code/error").INiceErrorIdMetadata<{
24
28
  domain: string;
29
+ allParentDomains: string[];
30
+ parentDomain: string;
25
31
  }, import("@nice-code/error").JSONSerializableValue>;
26
32
  domain_no_handler: import("@nice-code/error").INiceErrorIdMetadata<{
27
33
  domain: string;
@@ -38,25 +44,41 @@ export declare const err_nice_action: import("@nice-code/error").NiceErrorDomain
38
44
  domain: string;
39
45
  actionId: string;
40
46
  }, import("@nice-code/error").JSONSerializableValue>;
41
- resolver_domain_not_registered: import("@nice-code/error").INiceErrorIdMetadata<{
47
+ no_action_execution_handler: import("@nice-code/error").INiceErrorIdMetadata<{
42
48
  domain: string;
49
+ actionId: string;
43
50
  }, import("@nice-code/error").JSONSerializableValue>;
44
- resolver_action_not_registered: import("@nice-code/error").INiceErrorIdMetadata<{
51
+ wire_action_not_primed_or_response: import("@nice-code/error").INiceErrorIdMetadata<{
45
52
  domain: string;
46
53
  actionId: string;
54
+ actionState: EActionState | undefined;
47
55
  }, import("@nice-code/error").JSONSerializableValue>;
48
- action_environment_not_found: import("@nice-code/error").INiceErrorIdMetadata<{
56
+ wire_not_action_data: import("@nice-code/error").INiceErrorIdMetadata<any, import("@nice-code/error").JSONSerializableValue>;
57
+ action_tag_handler_not_found: import("@nice-code/error").INiceErrorIdMetadata<{
49
58
  domain: string;
50
- envId: string;
59
+ matchTag: string;
51
60
  }, import("@nice-code/error").JSONSerializableValue>;
52
61
  environment_already_registered: import("@nice-code/error").INiceErrorIdMetadata<{
53
62
  domain: string;
54
- envId: string;
63
+ matchTag: string;
55
64
  }, import("@nice-code/error").JSONSerializableValue>;
56
65
  action_input_validation_failed: import("@nice-code/error").INiceErrorIdMetadata<{
57
66
  domain: string;
58
67
  actionId: string;
59
68
  validationMessage: string;
60
69
  }, import("@nice-code/error").JSONSerializableValue>;
70
+ action_input_validation_promise: import("@nice-code/error").INiceErrorIdMetadata<{
71
+ domain: string;
72
+ actionId: string;
73
+ }, import("@nice-code/error").JSONSerializableValue>;
74
+ action_output_validation_failed: import("@nice-code/error").INiceErrorIdMetadata<{
75
+ domain: string;
76
+ actionId: string;
77
+ validationMessage: string;
78
+ }, import("@nice-code/error").JSONSerializableValue>;
79
+ action_output_validation_promise: import("@nice-code/error").INiceErrorIdMetadata<{
80
+ domain: string;
81
+ actionId: string;
82
+ }, import("@nice-code/error").JSONSerializableValue>;
61
83
  };
62
84
  }>;
@@ -1,17 +1,31 @@
1
- export { createActionDomain } from "./ActionDomain/createActionDomain";
1
+ export { createActionRootDomain } from "./ActionDomain/helpers/createRootActionDomain";
2
2
  export { NiceActionDomain } from "./ActionDomain/NiceActionDomain";
3
- export type { INiceActionDomain, INiceActionDomainChildOptions, MaybePromise, TActionHandlerForDomain, TActionIdHandlerForDomain, TActionListener, TDomainActionId, TInferInputFromSchema, TInferOutputFromSchema, TNiceActionDomainChildDef, TNiceActionDomainSchema, TPossibleDomainId, TPossibleDomainIdList, } from "./ActionDomain/NiceActionDomain.types";
4
- export { NiceActionRequester } from "./ActionRequestResponse/ActionRequester/NiceActionRequester";
5
- export { createDomainResolver, NiceActionDomainResponder, } from "./ActionRequestResponse/ActionResponder/NiceActionResponder";
6
- export type { TActionResponderFn } from "./ActionRequestResponse/ActionResponder/NiceActionResponder.types";
7
- export { createResponderEnvironment, NiceActionResponderEnvironment, } from "./ActionRequestResponse/ActionResponder/NiceActionResponderEnvironment";
3
+ export type { INiceActionDomain, INiceActionDomainChildOptions, INiceActionRootDomain, MaybePromise, TDomainActionId, TInferInputFromSchema, TInferOutputFromSchema, TNiceActionDomainChildDef, TNiceActionDomainSchema, TPossibleDomainId, TPossibleDomainIdList, } from "./ActionDomain/NiceActionDomain.types";
4
+ export { NiceActionRootDomain } from "./ActionDomain/RootDomain/NiceActionRootDomain";
5
+ export { ActionConnect } from "./ActionRuntimeEnvironment/ActionConnect/ActionConnect";
6
+ export * from "./ActionRuntimeEnvironment/ActionConnect/ActionConnect.types";
7
+ export { ConnectionConfig } from "./ActionRuntimeEnvironment/ActionConnect/ConnectionConfig/ConnectionConfig";
8
+ export * from "./ActionRuntimeEnvironment/ActionConnect/ConnectionConfig/ConnectionConfig.types";
9
+ export * from "./ActionRuntimeEnvironment/ActionConnect/err_nice_connect";
10
+ export * from "./ActionRuntimeEnvironment/ActionConnect/Transport/err_nice_transport";
11
+ export * from "./ActionRuntimeEnvironment/ActionConnect/Transport/err_nice_transport_ws";
12
+ export * from "./ActionRuntimeEnvironment/ActionConnect/Transport/Transport";
13
+ export * from "./ActionRuntimeEnvironment/ActionConnect/Transport/Transport.types";
14
+ export * from "./ActionRuntimeEnvironment/ActionConnect/Transport/TransportHttp";
15
+ export * from "./ActionRuntimeEnvironment/ActionConnect/Transport/TransportWebSocket";
16
+ export { ActionHandler, createHandler, } from "./ActionRuntimeEnvironment/ActionHandler/ActionHandler";
17
+ export type { IActionHandlerInputs, TAtLeastOne, TExecutionAndResponseHandlers, THandleActionExecutionFn, THandleActionResponseFn, THandleActionResult, } from "./ActionRuntimeEnvironment/ActionHandler/ActionHandler.types";
18
+ export { ActionRuntimeEnvironment, createActionRuntime, } from "./ActionRuntimeEnvironment/ActionRuntimeEnvironment";
19
+ export type { IActionRuntimeEnvironment_JsonObject } from "./ActionRuntimeEnvironment/ActionRuntimeEnvironment.types";
8
20
  export { action } from "./ActionSchema/action";
9
21
  export type { TInferActionError } from "./ActionSchema/NiceActionSchema";
10
22
  export { NiceActionSchema } from "./ActionSchema/NiceActionSchema";
11
- export type { TNiceActionSerializationDefinition, TNiceActonSchemaInputOptions, TTransportedValue, } from "./ActionSchema/NiceActionSchema.types";
23
+ export type { TNiceActionSerializationDefinition, TNiceActonSchemaOptions as TNiceActonSchemaInputOptions, TTransportedValue, } from "./ActionSchema/NiceActionSchema.types";
12
24
  export { EErrId_NiceAction, err_nice_action } from "./errors/err_nice_action";
25
+ export { matchAction } from "./NiceAction/MatchAction/MatchAction";
13
26
  export { NiceAction } from "./NiceAction/NiceAction";
14
- export type { INiceAction, INiceAction_JsonObject, INiceActionPrimed_JsonObject, NiceActionResult, TNiceActionResponse_JsonObject, } from "./NiceAction/NiceAction.types";
27
+ export { EActionState } from "./NiceAction/NiceAction.enums";
28
+ export type { INiceAction, INiceAction_JsonObject, INiceActionPrimed_JsonObject, TNiceActionResponse_JsonObject, TNiceActionResult as NiceActionResult, } from "./NiceAction/NiceAction.types";
15
29
  export { NiceActionPrimed } from "./NiceAction/NiceActionPrimed";
16
30
  export { NiceActionResponse } from "./NiceAction/NiceActionResponse";
17
31
  export * from "./utils/isActionResponseJsonObject";
@@ -1,5 +1,6 @@
1
1
  import type { QueryKey, UseMutationOptions, UseMutationResult, UseQueryOptions, UseQueryResult } from "@tanstack/react-query";
2
2
  import type { INiceActionDomain, TInferInputFromSchema, TInferOutputFromSchema } from "../ActionDomain/NiceActionDomain.types";
3
+ import type { IActionMetaInputs } from "../ActionRuntimeEnvironment/ActionHandler/ActionHandler.types";
3
4
  import type { TInferActionError } from "../ActionSchema/NiceActionSchema";
4
5
  import type { NiceAction } from "../NiceAction/NiceAction";
5
6
  /**
@@ -19,19 +20,16 @@ import type { NiceAction } from "../NiceAction/NiceAction";
19
20
  * queryClient.invalidateQueries({ queryKey: niceActionQueryKey(domain.action("getUser"), { userId: "123" }) });
20
21
  */
21
22
  export declare function niceActionQueryKey<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string>(action: NiceAction<DOM, ID, DOM["actions"][ID]>): readonly ["nice-action", DOM["domain"], DOM["allDomains"], ID];
22
- export declare function niceActionQueryKey<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string>(action: NiceAction<DOM, ID, DOM["actions"][ID]>, input: TInferInputFromSchema<DOM["actions"][ID]>["Input"]): readonly [
23
+ export declare function niceActionQueryKey<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string>(action: NiceAction<DOM, ID, DOM["actions"][ID]>, input: TInferInputFromSchema<DOM["actions"][ID]>["Input"], meta?: IActionMetaInputs): readonly [
23
24
  "nice-action",
24
25
  DOM["domain"],
25
26
  DOM["allDomains"],
26
27
  ID,
27
- TInferInputFromSchema<DOM["actions"][ID]>["Input"]
28
+ TInferInputFromSchema<DOM["actions"][ID]>["Input"],
29
+ string | undefined
28
30
  ];
29
- export type TUseNiceQueryOptions<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string, SCH extends DOM["actions"][ID] = DOM["actions"][ID], TSelect = TInferOutputFromSchema<SCH>["Output"]> = Omit<UseQueryOptions<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>, TSelect, QueryKey>, "queryKey" | "queryFn"> & {
30
- envId?: string;
31
- };
32
- export type TUseNiceMutationOptions<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string, SCH extends DOM["actions"][ID] = DOM["actions"][ID], TContext = unknown> = Omit<UseMutationOptions<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>, TInferInputFromSchema<SCH>["Input"], TContext>, "mutationFn"> & {
33
- envId?: string;
34
- };
31
+ export type TUseNiceQueryOptions<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string, SCH extends DOM["actions"][ID] = DOM["actions"][ID], TSelect = TInferOutputFromSchema<SCH>["Output"]> = Omit<UseQueryOptions<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>, TSelect, QueryKey>, "queryKey" | "queryFn"> & IActionMetaInputs;
32
+ export type TUseNiceMutationOptions<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string, SCH extends DOM["actions"][ID] = DOM["actions"][ID], TContext = unknown> = Omit<UseMutationOptions<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>, TInferInputFromSchema<SCH>["Input"], TContext>, "mutationFn"> & IActionMetaInputs;
35
33
  /**
36
34
  * Execute a Nice Action as a TanStack Query.
37
35
  *
@@ -39,7 +37,7 @@ export type TUseNiceMutationOptions<DOM extends INiceActionDomain, ID extends ke
39
37
  * Passing `null` or `undefined` as `input` disables the query (sets `enabled: false`),
40
38
  * which allows conditional execution while respecting React's rules of hooks.
41
39
  *
42
- * The `envId` option targets a specific named handler/resolver registered on the domain.
40
+ * The `tag` option targets a specific named handler registered on the runtime environment.
43
41
  *
44
42
  * Supports TanStack Query's `select` option with full type inference — if you pass a
45
43
  * `select` transformer, `data` will be typed as the transformer's return type.
@@ -61,7 +59,7 @@ export declare function useNiceQuery<DOM extends INiceActionDomain, ID extends k
61
59
  * Ideal for actions that change server state — form submissions, updates, deletes, etc.
62
60
  * The input is provided at call time via `mutation.mutate(input)` or `mutation.mutateAsync(input)`.
63
61
  *
64
- * The `envId` option targets a specific named handler/resolver registered on the domain.
62
+ * The `tag` option targets a specific named handler registered on the runtime environment.
65
63
  *
66
64
  * @example
67
65
  * const mutation = useNiceMutation(domain.action("createUser"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nice-code/action",
3
- "version": "0.0.21",
3
+ "version": "0.1.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -32,17 +32,19 @@
32
32
  "build-types": "tsc --project tsconfig.build.json"
33
33
  },
34
34
  "dependencies": {
35
- "@nice-code/error": "0.0.21",
36
- "@nice-code/common-errors": "0.0.21",
35
+ "@nice-code/error": "0.1.1",
36
+ "@nice-code/common-errors": "0.1.1",
37
37
  "@standard-schema/spec": "^1.1.0",
38
38
  "http-status-codes": "^2.3.0",
39
- "nanoid": "^5.1.9"
39
+ "nanoid": "^5.1.9",
40
+ "std-env": "^4.1.0"
40
41
  },
41
42
  "devDependencies": {
42
- "@tanstack/react-query": "^5.99.0"
43
+ "@tanstack/react-query": "^5.100.3",
44
+ "msw": "^2.13.6"
43
45
  },
44
46
  "peerDependencies": {
45
- "@tanstack/react-query": "^5.99.0",
47
+ "@tanstack/react-query": "^5.100.3",
46
48
  "react": ">=18",
47
49
  "valibot": "^1.3.1"
48
50
  }
@@ -1,5 +0,0 @@
1
- import { NiceActionDomain } from "./NiceActionDomain";
2
- import type { INiceActionDomain } from "./NiceActionDomain.types";
3
- export declare const createActionDomain: <ACT_DOM extends Omit<INiceActionDomain, "allDomains">>(definition: ACT_DOM) => NiceActionDomain<ACT_DOM & {
4
- allDomains: [string];
5
- }>;
@@ -1,31 +0,0 @@
1
- import type { NiceActionDomain } from "../../ActionDomain/NiceActionDomain";
2
- import type { INiceActionDomain, TActionHandlerForDomain, TActionIdHandlerForDomain, TBroadActionRequester } from "../../ActionDomain/NiceActionDomain.types";
3
- import type { NiceActionPrimed } from "../../NiceAction/NiceActionPrimed";
4
- export declare class NiceActionRequester {
5
- private cases;
6
- private _defaultRequester?;
7
- handleAction(action: NiceActionPrimed<any, any, any>): Promise<unknown>;
8
- /**
9
- * Register a handler that fires for **any** action whose domain matches `domain`.
10
- * `act.input` is typed as the union of input types for all actions in `domain`.
11
- * First matching case wins.
12
- */
13
- forDomain<FOR_DOM extends INiceActionDomain>(domain: NiceActionDomain<FOR_DOM>, handler: TActionHandlerForDomain<FOR_DOM>): this;
14
- /**
15
- * Register a handler that fires only for the specific action `id`.
16
- * The handler's `action.input` is narrowed to the schema for that ID.
17
- * First matching case wins.
18
- */
19
- forActionId<ACT_DOM extends INiceActionDomain, ID extends keyof ACT_DOM["actions"] & string>(domain: NiceActionDomain<ACT_DOM>, id: ID, handler: TActionIdHandlerForDomain<ACT_DOM, ID>): this;
20
- /**
21
- * Register a handler that fires for any action whose id is in `ids`.
22
- * The handler's `action.input` is narrowed to the union of those IDs' schemas.
23
- * First matching case wins.
24
- */
25
- forActionIds<ACT_DOM extends INiceActionDomain, IDS extends ReadonlyArray<keyof ACT_DOM["actions"] & string>>(domain: NiceActionDomain<ACT_DOM>, ids: IDS, handler: TActionIdHandlerForDomain<ACT_DOM, IDS[number]>): this;
26
- /**
27
- * Register a fallback handler that fires when no other case matches.
28
- * Only one default handler can be registered — calling this twice replaces the previous one.
29
- */
30
- setDefaultHandler(handler: TBroadActionRequester<NiceActionPrimed<any, any, any>>): this;
31
- }
@@ -1,49 +0,0 @@
1
- import type { NiceActionDomain } from "../../ActionDomain/NiceActionDomain";
2
- import type { INiceActionDomain } from "../../ActionDomain/NiceActionDomain.types";
3
- import type { INiceActionPrimed_JsonObject } from "../../NiceAction/NiceAction.types";
4
- import type { NiceActionPrimed } from "../../NiceAction/NiceActionPrimed";
5
- import { NiceActionResponse } from "../../NiceAction/NiceActionResponse";
6
- import type { TActionResponderFn } from "./NiceActionResponder.types";
7
- export declare class NiceActionDomainResponder<DOM extends INiceActionDomain> {
8
- private _domain;
9
- private _responders;
10
- constructor(domain: NiceActionDomain<DOM>);
11
- get domainId(): DOM["domain"];
12
- /**
13
- * Register a responder function for a specific action ID in this domain.
14
- * The input and output types are inferred from the domain's schema for that action ID.
15
- *
16
- * @example
17
- * ```ts
18
- * createDomainResponder(myDomain)
19
- * .resolve("myAction", async (input) => {
20
- * return { result: await db.query(input.id) };
21
- * });
22
- * ```
23
- */
24
- resolveAction<ID extends keyof DOM["actions"] & string>(actionId: ID, fn: TActionResponderFn<DOM["actions"][ID]>): this;
25
- /**
26
- * Internal: called by `NiceActionDomain._dispatchAction` when this resolver is registered
27
- * as the domain's fallback. Calls the registered fn directly — no re-serialization.
28
- * Errors from the fn propagate naturally (consistent with handler dispatch).
29
- *
30
- * Throws `resolver_action_not_registered` if no fn was registered for the action ID.
31
- */
32
- _resolvePrimed(primed: NiceActionPrimed<any, any, any>): Promise<unknown>;
33
- /**
34
- * Internal: hydrate the wire action, call the registered resolver fn, and return a
35
- * `NiceActionResponse`. Any error thrown by the resolver fn is caught and wrapped in the
36
- * response as `{ ok: false }` via `castNiceError`.
37
- *
38
- * Throws `resolver_action_not_registered` if no fn was registered for the action ID.
39
- * Throws `hydration_*` errors (from `NiceActionDomain.hydrateAction`) if the action ID
40
- * is not part of this domain's schema.
41
- */
42
- _dispatch<P extends INiceActionPrimed_JsonObject<DOM, string>>(wire: P): Promise<NiceActionResponse<DOM, P["id"], DOM["actions"][P["id"]]>>;
43
- }
44
- /**
45
- * Create a `NiceActionDomainResolver` for `domain`.
46
- * Chain `.resolve(actionId, fn)` calls to register typed resolver functions,
47
- * then pass the resolver to `createResolverEnvironment`.
48
- */
49
- export declare function createDomainResolver<DOM extends INiceActionDomain>(domain: NiceActionDomain<DOM>): NiceActionDomainResponder<DOM>;
@@ -1,7 +0,0 @@
1
- import type { MaybePromise, TInferInputFromSchema, TInferOutputFromSchema } from "../../ActionDomain/NiceActionDomain.types";
2
- import type { NiceActionSchema } from "../../ActionSchema/NiceActionSchema";
3
- /**
4
- * A resolver function for a specific action.
5
- * Receives the deserialized input and must return (or resolve to) the deserialized output.
6
- */
7
- export type TActionResponderFn<SCH extends NiceActionSchema<any, any, any>> = (input: TInferInputFromSchema<SCH>["Input"]) => MaybePromise<TInferOutputFromSchema<SCH>["Output"]>;