@rotorsoft/act-http 1.10.22 → 1.10.23

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.
@@ -0,0 +1,44 @@
1
+ import type { Actor, Target } from "@rotorsoft/act";
2
+ import type { IdempotencyStore } from "@rotorsoft/act-ops/idempotency";
3
+ /**
4
+ * The Act surface the generated transports walk: the registry's action
5
+ * name → owning-state map and `do(...)`. A structural bound lets `TApp`
6
+ * infer to the caller's concrete `Act<...>` without leaking the variance of
7
+ * its nested types, and without `any`.
8
+ */
9
+ export type ActSurface = {
10
+ readonly registry: {
11
+ actions: Record<string, {
12
+ readonly name: string;
13
+ readonly actions: Record<string, unknown>;
14
+ }>;
15
+ };
16
+ do(action: string, target: Target, payload: unknown): Promise<unknown>;
17
+ };
18
+ /** The target resolvers a generated transport takes, over its own context. */
19
+ type TargetResolvers<C> = {
20
+ readonly stream: (action_name: string, input: unknown, ctx: C) => string | Promise<string>;
21
+ readonly expectedVersion?: (action_name: string, input: unknown, ctx: C) => number | undefined | Promise<number | undefined>;
22
+ };
23
+ /** What one generated action call came to; each transport maps the refusals. */
24
+ export type Dispatched = {
25
+ kind: "done";
26
+ result: unknown;
27
+ } | {
28
+ kind: "missing-key";
29
+ } | {
30
+ kind: "in-flight";
31
+ } | {
32
+ kind: "conflict";
33
+ };
34
+ /**
35
+ * One generated action call: resolve the target from the validated input,
36
+ * then run `app.do` on the raw payload (it parses again itself, and a second
37
+ * parse of the parsed value would run every `.transform()` twice), under
38
+ * `Idempotency-Key` dedup when a store is set. A duplicate of a key still
39
+ * running is `in-flight`, since the original may yet fail and release it;
40
+ * one already committed is `conflict`.
41
+ */
42
+ export declare function make_dispatch<C>(app: ActSurface, resolvers: TargetResolvers<C>, store: IdempotencyStore | undefined): (action_name: string, input: unknown, payload: unknown, ctx: C, actor: Actor, key: () => string | undefined) => Promise<Dispatched>;
43
+ export {};
44
+ //# sourceMappingURL=dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../../src/api/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAIvE;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,QAAQ,EAAE;QACjB,OAAO,EAAE,MAAM,CACb,MAAM,EACN;YACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SAC3C,CACF,CAAC;KACH,CAAC;IACF,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE,CAAC;AAEF,8EAA8E;AAC9E,KAAK,eAAe,CAAC,CAAC,IAAI;IACxB,QAAQ,CAAC,MAAM,EAAE,CACf,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,CAAC,KACH,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,CACzB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,CAAC,KACH,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACvD,CAAC;AAEF,gFAAgF;AAChF,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;AAEzB;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,eAAe,CAAC,CAAC,CAAC,EAC7B,KAAK,EAAE,gBAAgB,GAAG,SAAS,iBAKpB,MAAM,SACZ,OAAO,WACL,OAAO,OACX,CAAC,SACC,KAAK,OACP,MAAM,MAAM,GAAG,SAAS,KAC5B,OAAO,CAAC,UAAU,CAAC,CAevB"}
@@ -1,7 +1,8 @@
1
- import type { Actor, Target } from "@rotorsoft/act";
1
+ import type { Actor } from "@rotorsoft/act";
2
2
  import type { IdempotencyStore } from "@rotorsoft/act-ops/idempotency";
3
3
  import type { Context, MiddlewareHandler } from "hono";
4
4
  import { Hono } from "hono";
5
+ import { type ActSurface } from "../api/dispatch.js";
5
6
  import { type ActorExtractor, type SseOptions } from "../api/index.js";
6
7
  /**
7
8
  * Hono context variables this subpath contributes. The generic on
@@ -92,24 +93,6 @@ export type HonoOptions = {
92
93
  export declare function authenticated(extractor: ActorExtractor): MiddlewareHandler<{
93
94
  Variables: ActMiddlewareVariables;
94
95
  }>;
95
- /**
96
- * Structural shape of the Act surface this generator walks at
97
- * runtime — the registry's action-name → owning-state map plus the
98
- * `do(...)` dispatch. Letting TApp infer to the caller's concrete
99
- * `Act<...>` against this structural bound keeps nested variance
100
- * out of the signature and avoids `any` in either direction.
101
- *
102
- * @internal
103
- */
104
- type ActSurface = {
105
- readonly registry: {
106
- actions: Record<string, {
107
- readonly name: string;
108
- readonly actions: Record<string, unknown>;
109
- }>;
110
- };
111
- do(action: string, target: Target, payload: unknown): Promise<unknown>;
112
- };
113
96
  /**
114
97
  * Build a typed Hono REST surface from a built `Act` instance.
115
98
  *
@@ -145,5 +128,4 @@ type ActSurface = {
145
128
  export declare function hono<TApp extends ActSurface = ActSurface>(app: TApp, options: HonoOptions): Hono<{
146
129
  Variables: ActMiddlewareVariables;
147
130
  }>;
148
- export {};
149
131
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hono/index.ts"],"names":[],"mappings":"AAgDA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,EACL,KAAK,cAAc,EAMnB,KAAK,UAAU,EAGhB,MAAM,iBAAiB,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,CACf,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,CAAC,EAAE,OAAO,KACP,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,CACzB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,CAAC,EAAE,OAAO,KACP,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;QACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;KACvD,CAAC;IACF;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,GACxB,iBAAiB,CAAC;IAAE,SAAS,EAAE,sBAAsB,CAAA;CAAE,CAAC,CAe1D;AAKD;;;;;;;;GAQG;AACH,KAAK,UAAU,GAAG;IAChB,QAAQ,CAAC,QAAQ,EAAE;QACjB,OAAO,EAAE,MAAM,CACb,MAAM,EACN;YACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SAC3C,CACF,CAAC;KACH,CAAC;IACF,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,IAAI,CAAC,IAAI,SAAS,UAAU,GAAG,UAAU,EACvD,GAAG,EAAE,IAAI,EACT,OAAO,EAAE,WAAW,GACnB,IAAI,CAAC;IAAE,SAAS,EAAE,sBAAsB,CAAA;CAAE,CAAC,CA8L7C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hono/index.ts"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,KAAK,UAAU,EAAiB,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,KAAK,cAAc,EAMnB,KAAK,UAAU,EAEhB,MAAM,iBAAiB,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,CACf,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,CAAC,EAAE,OAAO,KACP,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,CACzB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,CAAC,EAAE,OAAO,KACP,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;QACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;KACvD,CAAC;IACF;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,GACxB,iBAAiB,CAAC;IAAE,SAAS,EAAE,sBAAsB,CAAA;CAAE,CAAC,CAe1D;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,IAAI,CAAC,IAAI,SAAS,UAAU,GAAG,UAAU,EACvD,GAAG,EAAE,IAAI,EACT,OAAO,EAAE,WAAW,GACnB,IAAI,CAAC;IAAE,SAAS,EAAE,sBAAsB,CAAA;CAAE,CAAC,CA2K7C"}
@@ -1,3 +1,4 @@
1
+ import type { ActSurface } from "../api/dispatch.js";
1
2
  /**
2
3
  * Minimal OpenAPI 3.1 document type. The emitter targets the 3.1
3
4
  * spec; the type is intentionally a structural subset rather than
@@ -103,23 +104,6 @@ export type OpenAPIComponents = {
103
104
  readonly schemas: Record<string, Record<string, unknown>>;
104
105
  readonly responses: Record<string, OpenAPIResponse>;
105
106
  };
106
- /**
107
- * Structural shape of the Act surface this emitter walks. Letting
108
- * TApp infer to the caller's concrete `Act<TSchemaReg, ...>` instead
109
- * of forcing it to fit a narrow framework-typed upper bound keeps
110
- * the caller's variance from leaking — and avoids `any` in the
111
- * signature.
112
- *
113
- * @internal
114
- */
115
- type ActRegistryView = {
116
- readonly registry: {
117
- actions: Record<string, {
118
- readonly name: string;
119
- readonly actions: Record<string, unknown>;
120
- }>;
121
- };
122
- };
123
107
  /**
124
108
  * Build an OpenAPI 3.1 document describing a built `Act` instance's
125
109
  * action surface.
@@ -145,6 +129,5 @@ type ActRegistryView = {
145
129
  * empty, or if any `servers[].url` fails URL parsing after
146
130
  * `{variable}` substitution.
147
131
  */
148
- export declare function openapi<TApp extends ActRegistryView>(app: TApp, options: OpenAPIOptions): OpenAPIDocument;
149
- export {};
132
+ export declare function openapi<TApp extends Pick<ActSurface, "registry">>(app: TApp, options: OpenAPIOptions): OpenAPIDocument;
150
133
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/openapi/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/openapi/index.ts"],"names":[],"mappings":"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"}
@@ -1,58 +1,6 @@
1
- /**
2
- * @packageDocumentation
3
- * @module act-http/trpc
4
- *
5
- * tRPC subpath for the auto-generated API epic (#835). Walks the
6
- * registry of a built `Act` once at function call and emits a typed
7
- * router that exposes every registered action as a flat `mutation`,
8
- * matching the shape hand-written tRPC routers in the Act ecosystem
9
- * already use.
10
- *
11
- * Usage:
12
- *
13
- * ```ts
14
- * import { trpc } from "@rotorsoft/act-http/trpc";
15
- *
16
- * const router = trpc(app, {
17
- * actor: (ctx) => ({ id: ctx.user.id, name: ctx.user.name }),
18
- * stream: (action, input, ctx) => input.stream ?? ctx.tenant,
19
- * });
20
- *
21
- * // Client sees:
22
- * // appRouter.PressKey.mutate({ key: "5" })
23
- * // appRouter.OpenTicket.mutate({ title: "..." })
24
- * ```
25
- *
26
- * The route shape is flat: one procedure per registered action at
27
- * the top level. Action names are the unique identifiers across
28
- * the registry (the framework already enforces no duplicates), so
29
- * an extra namespace tier would be overhead in the common case.
30
- * Pure mutations for this slice; query/projection wiring lives in
31
- * a follow-up. See `libs/act-http/README.md` for the full surface
32
- * walkthrough.
33
- *
34
- * **Actor lives on the context.** The generator wires an internal
35
- * tRPC middleware that runs the host's
36
- * {@link TrpcOptions.actor | actor extractor} once per call and
37
- * injects the resolved {@link Actor} onto the downstream context as
38
- * `ctx.actor`. Every generated mutation reads from there — auth
39
- * resolves at the procedure boundary, not inside each action body,
40
- * and any composed middleware (logging, tracing) sees the same
41
- * `ctx.actor`. The middleware factory is also exported as
42
- * {@link authenticated} for hosts that need to compose it into
43
- * their own procedure chain.
44
- *
45
- * Composes the shared utilities at `@rotorsoft/act-http/api`:
46
- * {@link ActorExtractor} for the auth seam, {@link toApiError} for
47
- * the uniform error→status/code mapping, {@link withIdempotency}
48
- * for `Idempotency-Key` dedup. Three transports (this one, Hono,
49
- * OpenAPI) ride the same utilities so a client talking to two
50
- * transports never sees two error shapes for the same framework
51
- * error.
52
- */
53
- import { type Target } from "@rotorsoft/act";
54
1
  import type { IdempotencyStore } from "@rotorsoft/act-ops/idempotency";
55
2
  import { type AnyTRPCMiddlewareFunction, type AnyTRPCMutationProcedure, type AnyTRPCRootTypes, type TRPCBuiltRouter } from "@trpc/server";
3
+ import { type ActSurface } from "../api/dispatch.js";
56
4
  import { type ActorExtractor, type SseOptions } from "../api/index.js";
57
5
  /**
58
6
  * Per-call options for {@link trpc}. The host supplies the three
@@ -147,26 +95,6 @@ export type TrpcOptions<Ctx> = {
147
95
  * in the extractor body).
148
96
  */
149
97
  export declare function authenticated(extractor: ActorExtractor): AnyTRPCMiddlewareFunction;
150
- /**
151
- * Structural shape of the Act surface this generator walks at
152
- * runtime — the registry's action-name → owning-state map plus the
153
- * `do(...)` dispatch. Letting TApp infer to the caller's concrete
154
- * `Act<...>` against this structural bound (instead of forcing it
155
- * to fit a narrow framework-typed upper bound) keeps the variance
156
- * of nested types like `PatchHandler` from leaking — and avoids
157
- * `any` in the signature.
158
- *
159
- * @internal
160
- */
161
- type ActSurface = {
162
- readonly registry: {
163
- actions: Record<string, {
164
- readonly name: string;
165
- readonly actions: Record<string, unknown>;
166
- }>;
167
- };
168
- do(action: string, target: Target, payload: unknown): Promise<unknown>;
169
- };
170
98
  /**
171
99
  * Generated router type — one mutation procedure per action name in
172
100
  * `TApp`'s registry. Mapped over the concrete action keys so
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/trpc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,OAAO,EAAc,KAAK,MAAM,EAAY,MAAM,gBAAgB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EAErB,KAAK,eAAe,EAErB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,KAAK,cAAc,EAInB,KAAK,UAAU,EAGhB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,MAAM,WAAW,CAAC,GAAG,IAAI;IAC7B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,CACf,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,GAAG,KACL,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,CACzB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,GAAG,KACL,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;QACjC,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,SAAS,CAAC;KACpD,CAAC;IACF;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,GACxB,yBAAyB,CAmB3B;AAuDD;;;;;;;;;;GAUG;AACH,KAAK,UAAU,GAAG;IAChB,QAAQ,CAAC,QAAQ,EAAE;QACjB,OAAO,EAAE,MAAM,CACb,MAAM,EACN;YACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SAC3C,CACF,CAAC;KACH,CAAC;IACF,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,KAAK,eAAe,CAAC,IAAI,IAAI,eAAe,CAC1C,gBAAgB,EAChB,IAAI,SAAS;IAAE,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;KAAE,CAAA;CAAE,GAClD;KAAG,CAAC,IAAI,MAAM,QAAQ,GAAG,wBAAwB;CAAE,GACnD,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAC7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,IAAI,CAClB,GAAG,SAAS,MAAM,GAAG,MAAM,EAC3B,IAAI,SAAS,UAAU,GAAG,UAAU,EACpC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CA6K7D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/trpc/index.ts"],"names":[],"mappings":"AA0DA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EAErB,KAAK,eAAe,EAErB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,KAAK,UAAU,EAAiB,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,KAAK,cAAc,EAInB,KAAK,UAAU,EAEhB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,MAAM,WAAW,CAAC,GAAG,IAAI;IAC7B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,CACf,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,GAAG,KACL,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,CACzB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,GAAG,KACL,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;QACjC,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,SAAS,CAAC;KACpD,CAAC;IACF;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,GACxB,yBAAyB,CAmB3B;AAuDD;;;;;;;;;;GAUG;AACH,KAAK,eAAe,CAAC,IAAI,IAAI,eAAe,CAC1C,gBAAgB,EAChB,IAAI,SAAS;IAAE,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;KAAE,CAAA;CAAE,GAClD;KAAG,CAAC,IAAI,MAAM,QAAQ,GAAG,wBAAwB;CAAE,GACnD,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAC7C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,IAAI,CAClB,GAAG,SAAS,MAAM,GAAG,MAAM,EAC3B,IAAI,SAAS,UAAU,GAAG,UAAU,EACpC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAsJ7D"}
@@ -0,0 +1,28 @@
1
+ import {
2
+ withIdempotency
3
+ } from "./chunk-ZQGGGU4E.js";
4
+ import {
5
+ track_in_flight
6
+ } from "./chunk-EERALS5E.js";
7
+
8
+ // src/api/dispatch.ts
9
+ function make_dispatch(app, resolvers, store) {
10
+ const tracker = store && track_in_flight(store);
11
+ return async (action_name, input, payload, ctx, actor, key) => {
12
+ const stream = await resolvers.stream(action_name, input, ctx);
13
+ const expected = await resolvers.expectedVersion?.(action_name, input, ctx);
14
+ const target = expected === void 0 ? { stream, actor } : { stream, actor, expectedVersion: expected };
15
+ const run = () => app.do(action_name, target, payload);
16
+ if (!tracker) return { kind: "done", result: await run() };
17
+ const k = key();
18
+ if (!k) return { kind: "missing-key" };
19
+ const outcome = await withIdempotency(tracker.store, k, run);
20
+ if (!outcome.deduped) return { kind: "done", result: outcome.result };
21
+ return { kind: tracker.in_flight(k) ? "in-flight" : "conflict" };
22
+ };
23
+ }
24
+
25
+ export {
26
+ make_dispatch
27
+ };
28
+ //# sourceMappingURL=chunk-H545LMMV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/dispatch.ts"],"sourcesContent":["import type { Actor, Target } from \"@rotorsoft/act\";\nimport type { IdempotencyStore } from \"@rotorsoft/act-ops/idempotency\";\nimport { withIdempotency } from \"./idempotency.js\";\nimport { track_in_flight } from \"./in-flight.js\";\n\n/**\n * The Act surface the generated transports walk: the registry's action\n * name → owning-state map and `do(...)`. A structural bound lets `TApp`\n * infer to the caller's concrete `Act<...>` without leaking the variance of\n * its nested types, and without `any`.\n */\nexport type ActSurface = {\n readonly registry: {\n actions: Record<\n string,\n {\n readonly name: string;\n readonly actions: Record<string, unknown>;\n }\n >;\n };\n do(action: string, target: Target, payload: unknown): Promise<unknown>;\n};\n\n/** The target resolvers a generated transport takes, over its own context. */\ntype TargetResolvers<C> = {\n readonly stream: (\n action_name: string,\n input: unknown,\n ctx: C\n ) => string | Promise<string>;\n readonly expectedVersion?: (\n action_name: string,\n input: unknown,\n ctx: C\n ) => number | undefined | Promise<number | undefined>;\n};\n\n/** What one generated action call came to; each transport maps the refusals. */\nexport type Dispatched =\n | { kind: \"done\"; result: unknown }\n | { kind: \"missing-key\" }\n | { kind: \"in-flight\" }\n | { kind: \"conflict\" };\n\n/**\n * One generated action call: resolve the target from the validated input,\n * then run `app.do` on the raw payload (it parses again itself, and a second\n * parse of the parsed value would run every `.transform()` twice), under\n * `Idempotency-Key` dedup when a store is set. A duplicate of a key still\n * running is `in-flight`, since the original may yet fail and release it;\n * one already committed is `conflict`.\n */\nexport function make_dispatch<C>(\n app: ActSurface,\n resolvers: TargetResolvers<C>,\n store: IdempotencyStore | undefined\n) {\n // Counts claims per key, to tell the two kinds of duplicate apart.\n const tracker = store && track_in_flight(store);\n return async (\n action_name: string,\n input: unknown,\n payload: unknown,\n ctx: C,\n actor: Actor,\n key: () => string | undefined\n ): Promise<Dispatched> => {\n const stream = await resolvers.stream(action_name, input, ctx);\n const expected = await resolvers.expectedVersion?.(action_name, input, ctx);\n const target =\n expected === undefined\n ? { stream, actor }\n : { stream, actor, expectedVersion: expected };\n const run = () => app.do(action_name, target, payload);\n if (!tracker) return { kind: \"done\", result: await run() };\n const k = key();\n if (!k) return { kind: \"missing-key\" };\n const outcome = await withIdempotency(tracker.store, k, run);\n if (!outcome.deduped) return { kind: \"done\", result: outcome.result };\n return { kind: tracker.in_flight(k) ? \"in-flight\" : \"conflict\" };\n };\n}\n"],"mappings":";;;;;;;;AAqDO,SAAS,cACd,KACA,WACA,OACA;AAEA,QAAM,UAAU,SAAS,gBAAgB,KAAK;AAC9C,SAAO,OACL,aACA,OACA,SACA,KACA,OACA,QACwB;AACxB,UAAM,SAAS,MAAM,UAAU,OAAO,aAAa,OAAO,GAAG;AAC7D,UAAM,WAAW,MAAM,UAAU,kBAAkB,aAAa,OAAO,GAAG;AAC1E,UAAM,SACJ,aAAa,SACT,EAAE,QAAQ,MAAM,IAChB,EAAE,QAAQ,OAAO,iBAAiB,SAAS;AACjD,UAAM,MAAM,MAAM,IAAI,GAAG,aAAa,QAAQ,OAAO;AACrD,QAAI,CAAC,QAAS,QAAO,EAAE,MAAM,QAAQ,QAAQ,MAAM,IAAI,EAAE;AACzD,UAAM,IAAI,IAAI;AACd,QAAI,CAAC,EAAG,QAAO,EAAE,MAAM,cAAc;AACrC,UAAM,UAAU,MAAM,gBAAgB,QAAQ,OAAO,GAAG,GAAG;AAC3D,QAAI,CAAC,QAAQ,QAAS,QAAO,EAAE,MAAM,QAAQ,QAAQ,QAAQ,OAAO;AACpE,WAAO,EAAE,MAAM,QAAQ,UAAU,CAAC,IAAI,cAAc,WAAW;AAAA,EACjE;AACF;","names":[]}
@@ -54,6 +54,23 @@ var zValidator = zValidatorFunction;
54
54
  var import_hono = require("hono");
55
55
  var import_streaming = require("hono/streaming");
56
56
 
57
+ // src/api/idempotency.ts
58
+ async function withIdempotency(store, key, handler) {
59
+ const fresh = await store.claim(key);
60
+ if (!fresh) {
61
+ return { deduped: true };
62
+ }
63
+ let result;
64
+ try {
65
+ result = await handler();
66
+ } catch (err) {
67
+ await store.release(key);
68
+ throw err;
69
+ }
70
+ await store.commit(key);
71
+ return { deduped: false, result };
72
+ }
73
+
57
74
  // src/api/in-flight.ts
58
75
  function track_in_flight(store) {
59
76
  let tracker = trackers.get(store);
@@ -114,6 +131,23 @@ function make_tracker(store) {
114
131
  };
115
132
  }
116
133
 
134
+ // src/api/dispatch.ts
135
+ function make_dispatch(app, resolvers, store) {
136
+ const tracker = store && track_in_flight(store);
137
+ return async (action_name, input2, payload, ctx, actor, key) => {
138
+ const stream = await resolvers.stream(action_name, input2, ctx);
139
+ const expected = await resolvers.expectedVersion?.(action_name, input2, ctx);
140
+ const target = expected === void 0 ? { stream, actor } : { stream, actor, expectedVersion: expected };
141
+ const run = () => app.do(action_name, target, payload);
142
+ if (!tracker) return { kind: "done", result: await run() };
143
+ const k = key();
144
+ if (!k) return { kind: "missing-key" };
145
+ const outcome = await withIdempotency(tracker.store, k, run);
146
+ if (!outcome.deduped) return { kind: "done", result: outcome.result };
147
+ return { kind: tracker.in_flight(k) ? "in-flight" : "conflict" };
148
+ };
149
+ }
150
+
117
151
  // src/api/errors.ts
118
152
  var import_act = require("@rotorsoft/act");
119
153
  var ERROR_MAP = {
@@ -156,23 +190,6 @@ function toApiError(err) {
156
190
  };
157
191
  }
158
192
 
159
- // src/api/idempotency.ts
160
- async function withIdempotency(store, key, handler) {
161
- const fresh = await store.claim(key);
162
- if (!fresh) {
163
- return { deduped: true };
164
- }
165
- let result;
166
- try {
167
- result = await handler();
168
- } catch (err) {
169
- await store.release(key);
170
- throw err;
171
- }
172
- await store.commit(key);
173
- return { deduped: false, result };
174
- }
175
-
176
193
  // ../../node_modules/.pnpm/zod@4.6.7/node_modules/zod/v4/classic/external.js
177
194
  var external_exports = {};
178
195
  __export(external_exports, {
@@ -20028,14 +20045,17 @@ function hono(app, options) {
20028
20045
  );
20029
20046
  api.use("*", authenticated(options.actor));
20030
20047
  const key_from = options.idempotency?.keyFrom ?? default_key_from;
20031
- const tracker = options.idempotency ? track_in_flight(options.idempotency.store) : void 0;
20048
+ const dispatch = make_dispatch(
20049
+ app,
20050
+ options,
20051
+ options.idempotency?.store
20052
+ );
20032
20053
  if (options.sse) {
20033
20054
  const sse_config = resolveSseConfig(options.sse);
20034
20055
  const sse_counter = new SseConnectionCounter(sse_config.maxConnections);
20035
- const state_names = /* @__PURE__ */ new Set();
20036
- for (const action of Object.values(app.registry.actions)) {
20037
- state_names.add(action.name);
20038
- }
20056
+ const state_names = new Set(
20057
+ Object.values(app.registry.actions).map((a) => a.name)
20058
+ );
20039
20059
  for (const state_name of state_names) {
20040
20060
  api.get(`/sse/${state_name}`, async (c) => {
20041
20061
  const stream_id = c.req.query("stream");
@@ -20120,50 +20140,38 @@ function hono(app, options) {
20120
20140
  try {
20121
20141
  const input2 = c.req.valid("json");
20122
20142
  const raw = is_json(c.req.header("content-type")) ? await c.req.json() : {};
20123
- const actor = c.get("actor");
20124
- const stream = await options.stream(action_name, input2, c);
20125
- const expected_version = options.expectedVersion ? await options.expectedVersion(action_name, input2, c) : void 0;
20126
- const target = expected_version === void 0 ? { stream, actor } : { stream, actor, expectedVersion: expected_version };
20127
- if (options.idempotency) {
20128
- const key = key_from(c);
20129
- if (!key) {
20130
- const body = {
20131
- error: "BadRequest",
20132
- detail: "Idempotency-Key required",
20133
- code: "BAD_REQUEST"
20134
- };
20135
- return c.json(body, 400);
20136
- }
20137
- const outcome = await withIdempotency(
20138
- tracker.store,
20139
- key,
20140
- () => app.do(action_name, target, raw)
20141
- );
20142
- if (outcome.deduped && tracker.in_flight(key)) {
20143
- const body = {
20144
- error: "ServiceUnavailable",
20145
- detail: "Idempotency-Key in flight; the original request has not finished, retry later",
20146
- code: "IN_FLIGHT"
20147
- };
20148
- c.header("Retry-After", "1");
20149
- return c.json(body, 503);
20150
- }
20151
- if (outcome.deduped) {
20152
- const body = {
20153
- error: "Conflict",
20154
- detail: "Idempotency-Key already used; original result not cached",
20155
- code: "CONFLICT"
20156
- };
20157
- return c.json(body, 409);
20158
- }
20159
- return c.json(outcome.result);
20160
- }
20161
- const snapshots = await app.do(
20143
+ const outcome = await dispatch(
20162
20144
  action_name,
20163
- target,
20164
- raw
20145
+ input2,
20146
+ raw,
20147
+ c,
20148
+ c.get("actor"),
20149
+ () => key_from(c)
20165
20150
  );
20166
- return c.json(snapshots);
20151
+ if (outcome.kind === "done") return c.json(outcome.result);
20152
+ if (outcome.kind === "missing-key") {
20153
+ const body2 = {
20154
+ error: "BadRequest",
20155
+ detail: "Idempotency-Key required",
20156
+ code: "BAD_REQUEST"
20157
+ };
20158
+ return c.json(body2, 400);
20159
+ }
20160
+ if (outcome.kind === "in-flight") {
20161
+ const body2 = {
20162
+ error: "ServiceUnavailable",
20163
+ detail: "Idempotency-Key in flight; the original request has not finished, retry later",
20164
+ code: "IN_FLIGHT"
20165
+ };
20166
+ c.header("Retry-After", "1");
20167
+ return c.json(body2, 503);
20168
+ }
20169
+ const body = {
20170
+ error: "Conflict",
20171
+ detail: "Idempotency-Key already used; original result not cached",
20172
+ code: "CONFLICT"
20173
+ };
20174
+ return c.json(body, 409);
20167
20175
  } catch (err) {
20168
20176
  const { status, body } = toApiError(err);
20169
20177
  return c.json(body, status);