@nwire/forge 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/__tests__/actor-methods.test.d.ts +9 -0
- package/dist/__tests__/actor-methods.test.d.ts.map +1 -0
- package/dist/__tests__/actor-methods.test.js +210 -0
- package/dist/__tests__/actor-methods.test.js.map +1 -0
- package/dist/__tests__/actor-schema-bound.test.d.ts +6 -0
- package/dist/__tests__/actor-schema-bound.test.d.ts.map +1 -0
- package/dist/__tests__/actor-schema-bound.test.js +112 -0
- package/dist/__tests__/actor-schema-bound.test.js.map +1 -0
- package/dist/__tests__/app-capabilities.test.d.ts +19 -0
- package/dist/__tests__/app-capabilities.test.d.ts.map +1 -0
- package/dist/__tests__/app-capabilities.test.js +57 -0
- package/dist/__tests__/app-capabilities.test.js.map +1 -0
- package/dist/__tests__/cli-runner.test.d.ts +6 -0
- package/dist/__tests__/cli-runner.test.d.ts.map +1 -0
- package/dist/__tests__/cli-runner.test.js +158 -0
- package/dist/__tests__/cli-runner.test.js.map +1 -0
- package/dist/__tests__/create-app.test.d.ts +18 -0
- package/dist/__tests__/create-app.test.d.ts.map +1 -0
- package/dist/__tests__/create-app.test.js +189 -0
- package/dist/__tests__/create-app.test.js.map +1 -0
- package/dist/__tests__/cross-service-bus.test.d.ts +8 -0
- package/dist/__tests__/cross-service-bus.test.d.ts.map +1 -0
- package/dist/__tests__/cross-service-bus.test.js +139 -0
- package/dist/__tests__/cross-service-bus.test.js.map +1 -0
- package/dist/__tests__/define-schema.test.d.ts +5 -0
- package/dist/__tests__/define-schema.test.d.ts.map +1 -0
- package/dist/__tests__/define-schema.test.js +83 -0
- package/dist/__tests__/define-schema.test.js.map +1 -0
- package/dist/__tests__/dev-logger.test.d.ts +9 -0
- package/dist/__tests__/dev-logger.test.d.ts.map +1 -0
- package/dist/__tests__/dev-logger.test.js +126 -0
- package/dist/__tests__/dev-logger.test.js.map +1 -0
- package/dist/__tests__/external-call.test.d.ts +14 -0
- package/dist/__tests__/external-call.test.d.ts.map +1 -0
- package/dist/__tests__/external-call.test.js +99 -0
- package/dist/__tests__/external-call.test.js.map +1 -0
- package/dist/__tests__/framework-events.test.d.ts +13 -0
- package/dist/__tests__/framework-events.test.d.ts.map +1 -0
- package/dist/__tests__/framework-events.test.js +204 -0
- package/dist/__tests__/framework-events.test.js.map +1 -0
- package/dist/__tests__/inline-handler.test.d.ts +8 -0
- package/dist/__tests__/inline-handler.test.d.ts.map +1 -0
- package/dist/__tests__/inline-handler.test.js +101 -0
- package/dist/__tests__/inline-handler.test.js.map +1 -0
- package/dist/__tests__/lifecycle-logging.test.d.ts +12 -0
- package/dist/__tests__/lifecycle-logging.test.d.ts.map +1 -0
- package/dist/__tests__/lifecycle-logging.test.js +112 -0
- package/dist/__tests__/lifecycle-logging.test.js.map +1 -0
- package/dist/__tests__/middleware.test.d.ts +7 -0
- package/dist/__tests__/middleware.test.d.ts.map +1 -0
- package/dist/__tests__/middleware.test.js +109 -0
- package/dist/__tests__/middleware.test.js.map +1 -0
- package/dist/__tests__/module-needs.test.d.ts +10 -0
- package/dist/__tests__/module-needs.test.d.ts.map +1 -0
- package/dist/__tests__/module-needs.test.js +77 -0
- package/dist/__tests__/module-needs.test.js.map +1 -0
- package/dist/__tests__/module-topo-sort.test.d.ts +15 -0
- package/dist/__tests__/module-topo-sort.test.d.ts.map +1 -0
- package/dist/__tests__/module-topo-sort.test.js +105 -0
- package/dist/__tests__/module-topo-sort.test.js.map +1 -0
- package/dist/__tests__/multi-tenancy.test.d.ts +10 -0
- package/dist/__tests__/multi-tenancy.test.d.ts.map +1 -0
- package/dist/__tests__/multi-tenancy.test.js +122 -0
- package/dist/__tests__/multi-tenancy.test.js.map +1 -0
- package/dist/__tests__/needs-topology.test.d.ts +11 -0
- package/dist/__tests__/needs-topology.test.d.ts.map +1 -0
- package/dist/__tests__/needs-topology.test.js +82 -0
- package/dist/__tests__/needs-topology.test.js.map +1 -0
- package/dist/__tests__/plugin-closure.test.d.ts +15 -0
- package/dist/__tests__/plugin-closure.test.d.ts.map +1 -0
- package/dist/__tests__/plugin-closure.test.js +140 -0
- package/dist/__tests__/plugin-closure.test.js.map +1 -0
- package/dist/__tests__/plugin.test.d.ts +10 -0
- package/dist/__tests__/plugin.test.d.ts.map +1 -0
- package/dist/__tests__/plugin.test.js +225 -0
- package/dist/__tests__/plugin.test.js.map +1 -0
- package/dist/__tests__/primitives.test.d.ts +9 -0
- package/dist/__tests__/primitives.test.d.ts.map +1 -0
- package/dist/__tests__/primitives.test.js +434 -0
- package/dist/__tests__/primitives.test.js.map +1 -0
- package/dist/__tests__/production-readiness.test.d.ts +22 -0
- package/dist/__tests__/production-readiness.test.d.ts.map +1 -0
- package/dist/__tests__/production-readiness.test.js +196 -0
- package/dist/__tests__/production-readiness.test.js.map +1 -0
- package/dist/__tests__/provider.test.d.ts +6 -0
- package/dist/__tests__/provider.test.d.ts.map +1 -0
- package/dist/__tests__/provider.test.js +122 -0
- package/dist/__tests__/provider.test.js.map +1 -0
- package/dist/__tests__/public-marker.test.d.ts +7 -0
- package/dist/__tests__/public-marker.test.d.ts.map +1 -0
- package/dist/__tests__/public-marker.test.js +54 -0
- package/dist/__tests__/public-marker.test.js.map +1 -0
- package/dist/__tests__/retry-dlq.test.d.ts +6 -0
- package/dist/__tests__/retry-dlq.test.d.ts.map +1 -0
- package/dist/__tests__/retry-dlq.test.js +68 -0
- package/dist/__tests__/retry-dlq.test.js.map +1 -0
- package/dist/__tests__/validate.test.d.ts +5 -0
- package/dist/__tests__/validate.test.d.ts.map +1 -0
- package/dist/__tests__/validate.test.js +53 -0
- package/dist/__tests__/validate.test.js.map +1 -0
- package/dist/__tests__/workflow-saga.test.d.ts +7 -0
- package/dist/__tests__/workflow-saga.test.d.ts.map +1 -0
- package/dist/__tests__/workflow-saga.test.js +239 -0
- package/dist/__tests__/workflow-saga.test.js.map +1 -0
- package/dist/actor-store.d.ts +83 -0
- package/dist/actor-store.d.ts.map +1 -0
- package/dist/actor-store.js +85 -0
- package/dist/actor-store.js.map +1 -0
- package/dist/cli-runner.d.ts +46 -0
- package/dist/cli-runner.d.ts.map +1 -0
- package/dist/cli-runner.js +164 -0
- package/dist/cli-runner.js.map +1 -0
- package/dist/create-app.d.ts +131 -0
- package/dist/create-app.d.ts.map +1 -0
- package/dist/create-app.js +593 -0
- package/dist/create-app.js.map +1 -0
- package/dist/define-action.d.ts +148 -0
- package/dist/define-action.d.ts.map +1 -0
- package/dist/define-action.js +52 -0
- package/dist/define-action.js.map +1 -0
- package/dist/define-actor.d.ts +302 -0
- package/dist/define-actor.d.ts.map +1 -0
- package/dist/define-actor.js +294 -0
- package/dist/define-actor.js.map +1 -0
- package/dist/define-app.d.ts +104 -0
- package/dist/define-app.d.ts.map +1 -0
- package/dist/define-app.js +49 -0
- package/dist/define-app.js.map +1 -0
- package/dist/define-cron.d.ts +50 -0
- package/dist/define-cron.d.ts.map +1 -0
- package/dist/define-cron.js +34 -0
- package/dist/define-cron.js.map +1 -0
- package/dist/define-error.d.ts +10 -0
- package/dist/define-error.d.ts.map +1 -0
- package/dist/define-error.js +10 -0
- package/dist/define-error.js.map +1 -0
- package/dist/define-external-call.d.ts +85 -0
- package/dist/define-external-call.d.ts.map +1 -0
- package/dist/define-external-call.js +38 -0
- package/dist/define-external-call.js.map +1 -0
- package/dist/define-handler.d.ts +98 -0
- package/dist/define-handler.d.ts.map +1 -0
- package/dist/define-handler.js +29 -0
- package/dist/define-handler.js.map +1 -0
- package/dist/define-inbound-webhook.d.ts +82 -0
- package/dist/define-inbound-webhook.d.ts.map +1 -0
- package/dist/define-inbound-webhook.js +42 -0
- package/dist/define-inbound-webhook.js.map +1 -0
- package/dist/define-inbox.d.ts +40 -0
- package/dist/define-inbox.d.ts.map +1 -0
- package/dist/define-inbox.js +31 -0
- package/dist/define-inbox.js.map +1 -0
- package/dist/define-initializer.d.ts +54 -0
- package/dist/define-initializer.d.ts.map +1 -0
- package/dist/define-initializer.js +38 -0
- package/dist/define-initializer.js.map +1 -0
- package/dist/define-middleware.d.ts +8 -0
- package/dist/define-middleware.d.ts.map +1 -0
- package/dist/define-middleware.js +8 -0
- package/dist/define-middleware.js.map +1 -0
- package/dist/define-model.d.ts +10 -0
- package/dist/define-model.d.ts.map +1 -0
- package/dist/define-model.js +13 -0
- package/dist/define-model.js.map +1 -0
- package/dist/define-module.d.ts +157 -0
- package/dist/define-module.d.ts.map +1 -0
- package/dist/define-module.js +60 -0
- package/dist/define-module.js.map +1 -0
- package/dist/define-outbox.d.ts +47 -0
- package/dist/define-outbox.d.ts.map +1 -0
- package/dist/define-outbox.js +36 -0
- package/dist/define-outbox.js.map +1 -0
- package/dist/define-plugin.d.ts +171 -0
- package/dist/define-plugin.d.ts.map +1 -0
- package/dist/define-plugin.js +134 -0
- package/dist/define-plugin.js.map +1 -0
- package/dist/define-projection.d.ts +56 -0
- package/dist/define-projection.d.ts.map +1 -0
- package/dist/define-projection.js +44 -0
- package/dist/define-projection.js.map +1 -0
- package/dist/define-provider.d.ts +49 -0
- package/dist/define-provider.d.ts.map +1 -0
- package/dist/define-provider.js +45 -0
- package/dist/define-provider.js.map +1 -0
- package/dist/define-query.d.ts +50 -0
- package/dist/define-query.d.ts.map +1 -0
- package/dist/define-query.js +33 -0
- package/dist/define-query.js.map +1 -0
- package/dist/define-resolver.d.ts +111 -0
- package/dist/define-resolver.d.ts.map +1 -0
- package/dist/define-resolver.js +146 -0
- package/dist/define-resolver.js.map +1 -0
- package/dist/define-schema.d.ts +88 -0
- package/dist/define-schema.d.ts.map +1 -0
- package/dist/define-schema.js +72 -0
- package/dist/define-schema.js.map +1 -0
- package/dist/define-workflow.d.ts +193 -0
- package/dist/define-workflow.d.ts.map +1 -0
- package/dist/define-workflow.js +345 -0
- package/dist/define-workflow.js.map +1 -0
- package/dist/dev-logger.d.ts +41 -0
- package/dist/dev-logger.d.ts.map +1 -0
- package/dist/dev-logger.js +135 -0
- package/dist/dev-logger.js.map +1 -0
- package/dist/event-message.d.ts +37 -0
- package/dist/event-message.d.ts.map +1 -0
- package/dist/event-message.js +51 -0
- package/dist/event-message.js.map +1 -0
- package/dist/foundation.d.ts +14 -0
- package/dist/foundation.d.ts.map +1 -0
- package/dist/foundation.js +14 -0
- package/dist/foundation.js.map +1 -0
- package/dist/framework-event-bus.d.ts +13 -0
- package/dist/framework-event-bus.d.ts.map +1 -0
- package/dist/framework-event-bus.js +13 -0
- package/dist/framework-event-bus.js.map +1 -0
- package/dist/framework-events.d.ts +121 -0
- package/dist/framework-events.d.ts.map +1 -0
- package/dist/framework-events.js +67 -0
- package/dist/framework-events.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/module-surface.d.ts +47 -0
- package/dist/module-surface.d.ts.map +1 -0
- package/dist/module-surface.js +65 -0
- package/dist/module-surface.js.map +1 -0
- package/dist/projection-store.d.ts +26 -0
- package/dist/projection-store.d.ts.map +1 -0
- package/dist/projection-store.js +28 -0
- package/dist/projection-store.js.map +1 -0
- package/dist/public-marker.d.ts +35 -0
- package/dist/public-marker.d.ts.map +1 -0
- package/dist/public-marker.js +45 -0
- package/dist/public-marker.js.map +1 -0
- package/dist/response.d.ts +8 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/response.js +8 -0
- package/dist/response.js.map +1 -0
- package/dist/runtime.d.ts +497 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1083 -0
- package/dist/runtime.js.map +1 -0
- package/dist/validate.d.ts +33 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +48 -0
- package/dist/validate.js.map +1 -0
- package/dist/when.d.ts +101 -0
- package/dist/when.d.ts.map +1 -0
- package/dist/when.js +57 -0
- package/dist/when.js.map +1 -0
- package/dist/workflow-timer-store.d.ts +78 -0
- package/dist/workflow-timer-store.d.ts.map +1 -0
- package/dist/workflow-timer-store.js +56 -0
- package/dist/workflow-timer-store.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `defineAction` — declares a typed message the system can handle. Actions
|
|
3
|
+
* are the framework's center of gravity: named intent, typed input, no
|
|
4
|
+
* transport concerns. Resolvers wrap actions for HTTP/GraphQL/CLI; workflows
|
|
5
|
+
* dispatch actions in response to events.
|
|
6
|
+
*
|
|
7
|
+
* export const submitAnswer = defineAction({
|
|
8
|
+
* name: 'submissions.submit-answer',
|
|
9
|
+
* description: 'Avi submits his answer to an exercise.',
|
|
10
|
+
* schema: SubmitAnswerInput,
|
|
11
|
+
* })
|
|
12
|
+
*
|
|
13
|
+
* An action carries a `name` (its routing key) and a `schema` (input type).
|
|
14
|
+
* Pass it by reference to `defineHandler(action, fn)`, `ctx.request(action, ...)`,
|
|
15
|
+
* or `ctx.send(action, ...)`. The name is the identity everywhere — Studio,
|
|
16
|
+
* telemetry, OpenAPI, and the event graph all key off it.
|
|
17
|
+
*
|
|
18
|
+
* Inline shorthand: `defineAction({ ..., handler })` synthesizes a handler
|
|
19
|
+
* alongside the contract. For cross-module orchestration where the handler
|
|
20
|
+
* lives elsewhere, leave `handler` undefined and wire via `defineHandler`.
|
|
21
|
+
*/
|
|
22
|
+
import type { z } from "zod";
|
|
23
|
+
import type { ZodTypeAny } from "@nwire/messages";
|
|
24
|
+
import type { EventDefinition } from "@nwire/messages";
|
|
25
|
+
import type { HandlerDefinition, HandlerReturn, HandlerContext } from "./define-handler.js";
|
|
26
|
+
import { type PublicMarker } from "./public-marker.js";
|
|
27
|
+
/**
|
|
28
|
+
* Retry policy for an action's handler. When a handler throws, the runtime
|
|
29
|
+
* retries up to `max` times with `backoff` strategy between attempts. After
|
|
30
|
+
* `max` attempts fail, the failure goes to the DLQ (dead-letter queue —
|
|
31
|
+
* currently a sink in the runtime; production wires plug in BullMQ DLQ).
|
|
32
|
+
*/
|
|
33
|
+
export interface RetryPolicy {
|
|
34
|
+
/** Maximum retry attempts after the initial try. Default: 0 (no retry). */
|
|
35
|
+
readonly max: number;
|
|
36
|
+
/** Backoff strategy. Default: `'exponential'`. */
|
|
37
|
+
readonly backoff?: "exponential" | "fixed";
|
|
38
|
+
/** Base delay in ms for backoff (default 100ms). */
|
|
39
|
+
readonly baseDelayMs?: number;
|
|
40
|
+
/** Cap on the per-attempt delay (default 30s). */
|
|
41
|
+
readonly maxDelayMs?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Service-level objective declaration for an action. Studio shows the
|
|
45
|
+
* declared target side-by-side with observed reality (p95 latency from the
|
|
46
|
+
* telemetry stream, success rate from action.completed vs .failed counts).
|
|
47
|
+
* All fields optional; missing fields just don't get scored.
|
|
48
|
+
*/
|
|
49
|
+
export interface ActionSlo {
|
|
50
|
+
/** Declared p95 latency target in milliseconds. */
|
|
51
|
+
readonly p95LatencyMs?: number;
|
|
52
|
+
/** Declared success rate target (0–1). */
|
|
53
|
+
readonly successRate?: number;
|
|
54
|
+
}
|
|
55
|
+
export interface ActionDefinition<TSchema extends ZodTypeAny = ZodTypeAny> extends PublicMarker {
|
|
56
|
+
readonly $kind: "action";
|
|
57
|
+
readonly name: string;
|
|
58
|
+
readonly description?: string;
|
|
59
|
+
readonly schema: TSchema;
|
|
60
|
+
readonly retry?: RetryPolicy;
|
|
61
|
+
/**
|
|
62
|
+
* Optional policy tag(s) consumed by authz middleware (`@nwire/auth`).
|
|
63
|
+
* The framework treats this as an opaque string — interpretation is
|
|
64
|
+
* the authorizer's job. Examples: `'admin-only'`, `['student', 'self']`.
|
|
65
|
+
*/
|
|
66
|
+
readonly policy?: string | readonly string[];
|
|
67
|
+
/**
|
|
68
|
+
* Named persona who triggers this action. Studio uses it to build
|
|
69
|
+
* persona-grouped journey views ("show me Avi's full flow"). Free-form
|
|
70
|
+
* label — typically the persona's name with a short qualifier:
|
|
71
|
+
* `'Avi (9, beginner)'`, `'Dina (curriculum designer)'`.
|
|
72
|
+
*/
|
|
73
|
+
readonly persona?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Journey step identifier this action belongs to. Lets Studio reconstruct
|
|
76
|
+
* the user journey across BCs. Free-form — by convention an id + label:
|
|
77
|
+
* `'J3-submit-exercise'`.
|
|
78
|
+
*/
|
|
79
|
+
readonly journeyStep?: string;
|
|
80
|
+
/**
|
|
81
|
+
* High-level capability name (UDOO-framework concept). Groups actions
|
|
82
|
+
* by what they enable. Example: `'submit-answer'`, `'review-flagged'`.
|
|
83
|
+
*/
|
|
84
|
+
readonly capability?: string;
|
|
85
|
+
/** Declared SLO target — Studio scores observed reality against this. */
|
|
86
|
+
readonly slo?: ActionSlo;
|
|
87
|
+
/** Free-form tags for filtering / grouping in Studio. */
|
|
88
|
+
readonly tags?: readonly string[];
|
|
89
|
+
/**
|
|
90
|
+
* Inline handler synthesized when `defineAction({..., handler})` was used.
|
|
91
|
+
* `createApp` walks `manifest.actions` and auto-registers this handler if
|
|
92
|
+
* present. For action contracts that have NO handler in the current module
|
|
93
|
+
* (cross-module dispatch, public schema-only declarations), leave this
|
|
94
|
+
* undefined and register the handler separately via `manifest.handlers`.
|
|
95
|
+
*
|
|
96
|
+
* Typed as `HandlerDefinition<ZodTypeAny>` (not `HandlerDefinition<TSchema>`)
|
|
97
|
+
* to preserve ActionDefinition's covariance over TSchema — without this,
|
|
98
|
+
* `ActionDefinition<MySchema>` would not be assignable to
|
|
99
|
+
* `ActionDefinition<ZodTypeAny>` (the abstract action reference used by
|
|
100
|
+
* the runtime, `defineHandler`, ctx.request, etc.).
|
|
101
|
+
*/
|
|
102
|
+
readonly handler?: HandlerDefinition;
|
|
103
|
+
/**
|
|
104
|
+
* Declared events this action emits. The handler's runtime return is the
|
|
105
|
+
* source of truth; this field is the *declared intent* — what the system
|
|
106
|
+
* promises to emit. The scanner reads it into the static graph so Studio
|
|
107
|
+
* (and any audit tooling) can draw causation chains at design time, and
|
|
108
|
+
* runtime observers can detect drift (emitted-but-not-declared or
|
|
109
|
+
* declared-but-never-fired).
|
|
110
|
+
*
|
|
111
|
+
* Carries event names only (event refs are erased to `{ name }` to avoid
|
|
112
|
+
* coupling the action definition to its event modules at the type level).
|
|
113
|
+
*/
|
|
114
|
+
readonly emits?: readonly EventDefinition[];
|
|
115
|
+
}
|
|
116
|
+
export interface ActionMeta<TSchema extends ZodTypeAny = ZodTypeAny> {
|
|
117
|
+
readonly name: string;
|
|
118
|
+
readonly description?: string;
|
|
119
|
+
readonly schema: TSchema;
|
|
120
|
+
readonly retry?: RetryPolicy;
|
|
121
|
+
readonly policy?: string | readonly string[];
|
|
122
|
+
/** See `ActionDefinition.persona`. */
|
|
123
|
+
readonly persona?: string;
|
|
124
|
+
/** See `ActionDefinition.journeyStep`. */
|
|
125
|
+
readonly journeyStep?: string;
|
|
126
|
+
/** See `ActionDefinition.capability`. */
|
|
127
|
+
readonly capability?: string;
|
|
128
|
+
/** See `ActionDefinition.slo`. */
|
|
129
|
+
readonly slo?: ActionSlo;
|
|
130
|
+
/** See `ActionDefinition.tags`. */
|
|
131
|
+
readonly tags?: readonly string[];
|
|
132
|
+
/** Declared events this action emits. See `ActionDefinition.emits`. */
|
|
133
|
+
readonly emits?: readonly EventDefinition[];
|
|
134
|
+
/**
|
|
135
|
+
* Optional inline handler. When set, `defineAction` synthesizes a
|
|
136
|
+
* `HandlerDefinition` linked to this action and attaches it to the
|
|
137
|
+
* returned `ActionDefinition.handler`. Use this for the common CRUD case
|
|
138
|
+
* where contract and handler live together. For cross-module orchestration
|
|
139
|
+
* (handler wired separately, action referenced from another module),
|
|
140
|
+
* declare the action without `handler` and use `defineHandler(action, fn)`
|
|
141
|
+
* in the owning module.
|
|
142
|
+
*/
|
|
143
|
+
readonly handler?: (input: z.output<TSchema>, ctx: HandlerContext) => Promise<HandlerReturn> | HandlerReturn;
|
|
144
|
+
}
|
|
145
|
+
export declare function defineAction<TSchema extends ZodTypeAny>(meta: ActionMeta<TSchema>): ActionDefinition<TSchema>;
|
|
146
|
+
export declare function defineAction<TSchema extends ZodTypeAny>(name: string, meta: Omit<ActionMeta<TSchema>, "name">): ActionDefinition<TSchema>;
|
|
147
|
+
export type ActionInput<A> = A extends ActionDefinition<infer S> ? z.output<S> : never;
|
|
148
|
+
//# sourceMappingURL=define-action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-action.d.ts","sourceRoot":"","sources":["../src/define-action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAY,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC;IAC3C,oDAAoD;IACpD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,kDAAkD;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,mDAAmD;IACnD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,0CAA0C;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB,CAAC,OAAO,SAAS,UAAU,GAAG,UAAU,CAAE,SAAQ,YAAY;IAC7F,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IACrC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,UAAU,CAAC,OAAO,SAAS,UAAU,GAAG,UAAU;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IAC7C,sCAAsC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,0CAA0C;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,yCAAyC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,kCAAkC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC;IACzB,mCAAmC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,uEAAuE;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CACjB,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EACxB,GAAG,EAAE,cAAc,KAChB,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC;CAC7C;AAKD,wBAAgB,YAAY,CAAC,OAAO,SAAS,UAAU,EACrD,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GACxB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAE7B,wBAAgB,YAAY,CAAC,OAAO,SAAS,UAAU,EACrD,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,GACtC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAqC7B,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `defineAction` — declares a typed message the system can handle. Actions
|
|
3
|
+
* are the framework's center of gravity: named intent, typed input, no
|
|
4
|
+
* transport concerns. Resolvers wrap actions for HTTP/GraphQL/CLI; workflows
|
|
5
|
+
* dispatch actions in response to events.
|
|
6
|
+
*
|
|
7
|
+
* export const submitAnswer = defineAction({
|
|
8
|
+
* name: 'submissions.submit-answer',
|
|
9
|
+
* description: 'Avi submits his answer to an exercise.',
|
|
10
|
+
* schema: SubmitAnswerInput,
|
|
11
|
+
* })
|
|
12
|
+
*
|
|
13
|
+
* An action carries a `name` (its routing key) and a `schema` (input type).
|
|
14
|
+
* Pass it by reference to `defineHandler(action, fn)`, `ctx.request(action, ...)`,
|
|
15
|
+
* or `ctx.send(action, ...)`. The name is the identity everywhere — Studio,
|
|
16
|
+
* telemetry, OpenAPI, and the event graph all key off it.
|
|
17
|
+
*
|
|
18
|
+
* Inline shorthand: `defineAction({ ..., handler })` synthesizes a handler
|
|
19
|
+
* alongside the contract. For cross-module orchestration where the handler
|
|
20
|
+
* lives elsewhere, leave `handler` undefined and wire via `defineHandler`.
|
|
21
|
+
*/
|
|
22
|
+
import { markable } from "./public-marker.js";
|
|
23
|
+
export function defineAction(nameOrMeta, maybeMeta) {
|
|
24
|
+
const meta = typeof nameOrMeta === "string"
|
|
25
|
+
? { ...(maybeMeta ?? {}), name: nameOrMeta }
|
|
26
|
+
: nameOrMeta;
|
|
27
|
+
const action = {
|
|
28
|
+
$kind: "action",
|
|
29
|
+
name: meta.name,
|
|
30
|
+
description: meta.description,
|
|
31
|
+
schema: meta.schema,
|
|
32
|
+
retry: meta.retry,
|
|
33
|
+
policy: meta.policy,
|
|
34
|
+
persona: meta.persona,
|
|
35
|
+
journeyStep: meta.journeyStep,
|
|
36
|
+
capability: meta.capability,
|
|
37
|
+
slo: meta.slo,
|
|
38
|
+
tags: meta.tags,
|
|
39
|
+
emits: meta.emits,
|
|
40
|
+
};
|
|
41
|
+
if (meta.handler) {
|
|
42
|
+
const userFn = meta.handler;
|
|
43
|
+
const handler = {
|
|
44
|
+
$kind: "v3-handler",
|
|
45
|
+
action: action,
|
|
46
|
+
handler: userFn,
|
|
47
|
+
};
|
|
48
|
+
return markable({ ...action, handler });
|
|
49
|
+
}
|
|
50
|
+
return markable(action);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=define-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-action.js","sourceRoot":"","sources":["../src/define-action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH,OAAO,EAAE,QAAQ,EAAqB,MAAM,iBAAiB,CAAC;AA2I9D,MAAM,UAAU,YAAY,CAC1B,UAAwC,EACxC,SAA6C;IAE7C,MAAM,IAAI,GACR,OAAO,UAAU,KAAK,QAAQ;QAC5B,CAAC,CAAE,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAA0B;QACrE,CAAC,CAAC,UAAU,CAAC;IAEjB,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,QAAiB;QACxB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC;IACF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,MAAM,OAAO,GAAsB;YACjC,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,MAAmC;YAC3C,OAAO,EAAE,MAAsC;SAChD,CAAC;QACF,OAAO,QAAQ,CAAC,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,CAA8B,CAAC;IACvE,CAAC;IACD,OAAO,QAAQ,CAAC,MAAM,CAA8B,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `defineActor` — the primitive for entities that carry state, transitions,
|
|
3
|
+
* and timers. The actor is data + state machine in one declaration.
|
|
4
|
+
*
|
|
5
|
+
* export const Submission = defineActor('submission', {
|
|
6
|
+
* schema: SubmissionSchema,
|
|
7
|
+
* key: 'submissionId',
|
|
8
|
+
* initial: 'submitted',
|
|
9
|
+
* states: {
|
|
10
|
+
* submitted: {
|
|
11
|
+
* on: {
|
|
12
|
+
* [AnswerFlaggedEvent.name]: {
|
|
13
|
+
* target: 'under-review',
|
|
14
|
+
* assign: (ctx, event) => ({ confidence: event.confidence })
|
|
15
|
+
* },
|
|
16
|
+
* [AnswerAutoGradedEvent.name]: {
|
|
17
|
+
* target: 'graded',
|
|
18
|
+
* assign: (ctx, event) => ({
|
|
19
|
+
* verdict: event.verdict,
|
|
20
|
+
* confidence: event.confidence,
|
|
21
|
+
* gradedAt: event.gradedAt
|
|
22
|
+
* })
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* },
|
|
26
|
+
* 'under-review': {
|
|
27
|
+
* on: {
|
|
28
|
+
* [SubmissionManuallyGradedEvent.name]: {
|
|
29
|
+
* target: 'graded',
|
|
30
|
+
* assign: (ctx, event) => ({ verdict: event.verdict })
|
|
31
|
+
* }
|
|
32
|
+
* },
|
|
33
|
+
* after: {
|
|
34
|
+
* '3d': sendReviewReminder
|
|
35
|
+
* }
|
|
36
|
+
* },
|
|
37
|
+
* graded: { final: true }
|
|
38
|
+
* }
|
|
39
|
+
* })
|
|
40
|
+
*
|
|
41
|
+
* See:
|
|
42
|
+
* - `__docs__/framework/foundation-v3-spec.md` — design rationale
|
|
43
|
+
* - `ADR-006-actors-vs-reactions.md` — when to use defineActor vs `when`
|
|
44
|
+
* - `ADR-007-declarative-state-via-assign.md` — why `assign` returns partials
|
|
45
|
+
*/
|
|
46
|
+
import type { z } from "zod";
|
|
47
|
+
import type { ZodTypeAny } from "@nwire/messages";
|
|
48
|
+
import type { EventDefinition } from "@nwire/messages";
|
|
49
|
+
import { type SchemaDefinition } from "./define-schema.js";
|
|
50
|
+
/**
|
|
51
|
+
* Reaction to one event in one state.
|
|
52
|
+
*
|
|
53
|
+
* - `target` — name of the state to transition to (omit to stay in this state).
|
|
54
|
+
* - `assign` — pure function returning a partial to merge into ctx.
|
|
55
|
+
* MUST be synchronous, MUST NOT mutate ctx, MUST NOT do I/O.
|
|
56
|
+
*/
|
|
57
|
+
export interface ActorReaction<TCtx, TEvent> {
|
|
58
|
+
readonly target?: string;
|
|
59
|
+
readonly assign?: (ctx: Readonly<TCtx>, event: TEvent) => Partial<TCtx>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Spec for one timer in a state's `after` block. `'3d'` = key, value is the
|
|
63
|
+
* action to send when the timer fires (or an `{ delay, action }` form when the
|
|
64
|
+
* timer name and the delay differ).
|
|
65
|
+
*/
|
|
66
|
+
export interface ActorTimerSpec {
|
|
67
|
+
readonly delay: string;
|
|
68
|
+
/** The action name to dispatch when the timer fires. */
|
|
69
|
+
readonly action: string;
|
|
70
|
+
/**
|
|
71
|
+
* Optional: a function that builds the action's input from the actor's
|
|
72
|
+
* current ctx + key. Defaults to `{ <key>: actorKey }`.
|
|
73
|
+
*/
|
|
74
|
+
readonly buildInput?: (ctx: unknown, key: string) => unknown;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Configuration for one state of an actor.
|
|
78
|
+
*/
|
|
79
|
+
export interface ActorStateConfig<TCtx> {
|
|
80
|
+
/** Reactions to events while in this state. Keyed by event name. */
|
|
81
|
+
readonly on?: Readonly<Record<string, ActorReaction<TCtx, unknown>>>;
|
|
82
|
+
/**
|
|
83
|
+
* Timers scheduled on entry to this state, cancelled on exit.
|
|
84
|
+
* Keyed by timer name. Value is either a delay string + action name,
|
|
85
|
+
* or just an action name with the timer name used as the delay key.
|
|
86
|
+
*/
|
|
87
|
+
readonly after?: Readonly<Record<string, string | ActorTimerSpec>>;
|
|
88
|
+
/** Mark this state as the lifecycle end. */
|
|
89
|
+
readonly final?: boolean;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A pure invariant-enforcer + event-minter method. Methods take the actor's
|
|
93
|
+
* current state (read-only) plus method args, and either return an event
|
|
94
|
+
* (or events), throw on invariant violation, or return a read-only value
|
|
95
|
+
* (for queries like `isGradable()`). Methods MUST NOT do I/O or read other
|
|
96
|
+
* actors — that lives in the handler.
|
|
97
|
+
*
|
|
98
|
+
* methods: {
|
|
99
|
+
* flagForReview(state, reason: string): EventMessage {
|
|
100
|
+
* if (state.status !== 'pending') throw new Error('only pending')
|
|
101
|
+
* return FlaggedForReviewEvent({ reason, flaggedAt: ... })
|
|
102
|
+
* },
|
|
103
|
+
* isGradable(state): boolean {
|
|
104
|
+
* return state.status === 'pending' && state.flags === 0
|
|
105
|
+
* }
|
|
106
|
+
* }
|
|
107
|
+
*/
|
|
108
|
+
export type ActorMethod<TCtx> = (state: TCtx, ...args: any[]) => any;
|
|
109
|
+
/**
|
|
110
|
+
* `defineActor` options. `TSchema` typically a `z.ZodObject` describing the
|
|
111
|
+
* actor's data shape — every field of the schema is part of the actor's `ctx`.
|
|
112
|
+
*/
|
|
113
|
+
/**
|
|
114
|
+
* Per-state "stuck" thresholds (milliseconds). When an actor instance has
|
|
115
|
+
* been in this state for >= the threshold, Studio surfaces it in the
|
|
116
|
+
* stuck-state inbox. Use this to declare "if a submission is in
|
|
117
|
+
* under-review for >48h, something needs Dina's attention."
|
|
118
|
+
*/
|
|
119
|
+
export type ActorStuckThresholds = Readonly<Record<string, number>>;
|
|
120
|
+
/**
|
|
121
|
+
* Per-state SLA declaration. `maxDurationMs` is the hard limit; once
|
|
122
|
+
* crossed, Studio raises an alert. `escalateTo` is a free-form audience tag
|
|
123
|
+
* (consumed by alerting integrations).
|
|
124
|
+
*/
|
|
125
|
+
export interface ActorSlaConfig {
|
|
126
|
+
readonly maxDurationMs: number;
|
|
127
|
+
readonly escalateTo?: string;
|
|
128
|
+
}
|
|
129
|
+
export type ActorSlas = Readonly<Record<string, ActorSlaConfig>>;
|
|
130
|
+
export interface ActorOptions<TSchema extends ZodTypeAny, TMethods extends Readonly<Record<string, ActorMethod<z.output<TSchema>>>> = Readonly<Record<string, ActorMethod<z.output<TSchema>>>>> {
|
|
131
|
+
readonly schema: TSchema;
|
|
132
|
+
/** Field path in event payloads used to look up the actor instance. */
|
|
133
|
+
readonly key: string;
|
|
134
|
+
/** Initial state name. The first event for an unknown key starts here. */
|
|
135
|
+
readonly initial: string;
|
|
136
|
+
/** State machine configuration. */
|
|
137
|
+
readonly states: Readonly<Record<string, ActorStateConfig<z.output<TSchema>>>>;
|
|
138
|
+
/**
|
|
139
|
+
* Optional pure methods callable from a handler via `ctx.use(Actor, id)`.
|
|
140
|
+
* Each method receives the current state pre-bound; it returns event(s)
|
|
141
|
+
* (which the handler returns to the runtime), throws on invariant
|
|
142
|
+
* violation, or returns a non-event read value.
|
|
143
|
+
*/
|
|
144
|
+
readonly methods?: TMethods;
|
|
145
|
+
/**
|
|
146
|
+
* Studio-aware: stuck-state thresholds in ms. Studio surfaces actor
|
|
147
|
+
* instances exceeding the threshold. Example for Submission actor:
|
|
148
|
+
* `{ 'under-review': 3 * 24 * 60 * 60 * 1000 }` (3 days).
|
|
149
|
+
*/
|
|
150
|
+
readonly stuckThresholds?: ActorStuckThresholds;
|
|
151
|
+
/**
|
|
152
|
+
* Studio-aware: per-state hard SLAs with escalation hints.
|
|
153
|
+
* `{ 'under-review': { maxDurationMs: 7 * 24 * 60 * 60 * 1000, escalateTo: 'curriculum-lead' } }`.
|
|
154
|
+
*/
|
|
155
|
+
readonly slas?: ActorSlas;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* A typed state reference produced by `states.<name>` inside the closure
|
|
159
|
+
* form. Returning a StateRef from a transition tells the runtime which state
|
|
160
|
+
* to transition into.
|
|
161
|
+
*/
|
|
162
|
+
export interface StateRef {
|
|
163
|
+
readonly $kind: "state-ref";
|
|
164
|
+
readonly name: string;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Closure-form context — what the actor body receives when called as
|
|
168
|
+
* `defineActor(schema, ({data, id, validate, recordThat, states, when, methods}) => ...)`.
|
|
169
|
+
* At define time `data`/`id` are placeholders; at each `use()` call the
|
|
170
|
+
* closure is re-invoked with the live instance state + key.
|
|
171
|
+
*/
|
|
172
|
+
export interface ActorClosureContext<TState> {
|
|
173
|
+
readonly data: TState;
|
|
174
|
+
readonly id: string;
|
|
175
|
+
readonly validate: <TIn>(input: TIn, predicates: ReadonlyArray<(input: TIn, state?: TState) => true | string>, state?: TState) => void;
|
|
176
|
+
readonly recordThat: (event: {
|
|
177
|
+
eventName: string;
|
|
178
|
+
payload: unknown;
|
|
179
|
+
}) => void;
|
|
180
|
+
readonly states: Record<string, StateRef>;
|
|
181
|
+
readonly when: <E extends {
|
|
182
|
+
name: string;
|
|
183
|
+
}>(event: E, fn: (payload: any, ctx: {
|
|
184
|
+
assign: (delta: Partial<TState>) => void;
|
|
185
|
+
}) => StateRef | void) => void;
|
|
186
|
+
readonly methods: <T extends Record<string, (...args: never[]) => unknown>>(obj: T) => T;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* `ActorDefinition` is the data the runtime registers and dispatches against.
|
|
190
|
+
* `defineActor` returns this; consumers should not construct it manually.
|
|
191
|
+
*/
|
|
192
|
+
export interface ActorDefinition<TSchema extends ZodTypeAny = ZodTypeAny, TMethods extends Readonly<Record<string, ActorMethod<z.output<TSchema>>>> = Readonly<Record<string, ActorMethod<z.output<TSchema>>>>> {
|
|
193
|
+
readonly $kind: "actor";
|
|
194
|
+
readonly name: string;
|
|
195
|
+
readonly schema: TSchema;
|
|
196
|
+
readonly key: string;
|
|
197
|
+
readonly initial: string;
|
|
198
|
+
readonly states: Readonly<Record<string, ActorStateConfig<z.output<TSchema>>>>;
|
|
199
|
+
readonly methods?: TMethods;
|
|
200
|
+
readonly stuckThresholds?: ActorStuckThresholds;
|
|
201
|
+
readonly slas?: ActorSlas;
|
|
202
|
+
/**
|
|
203
|
+
* Quick-lookup index: every event name this actor reacts to in any state,
|
|
204
|
+
* with the list of (stateName, reaction) entries that handle it. Built at
|
|
205
|
+
* definition time so dispatch is O(1) per event.
|
|
206
|
+
*/
|
|
207
|
+
readonly eventIndex: ReadonlyMap<string, ReadonlyArray<{
|
|
208
|
+
state: string;
|
|
209
|
+
reaction: ActorReaction<z.output<TSchema>, unknown>;
|
|
210
|
+
}>>;
|
|
211
|
+
/**
|
|
212
|
+
* Closure-form binder. When set, `runtime.use(Actor, id)` calls this with
|
|
213
|
+
* the live `state` + `id` to produce the bound methods. Methods record
|
|
214
|
+
* events via `recordThat`, which the framework collects after the method
|
|
215
|
+
* returns. Methods may also return a value to the caller.
|
|
216
|
+
*
|
|
217
|
+
* `null` for classic / schema-bound-object actors.
|
|
218
|
+
*/
|
|
219
|
+
readonly closureBinder?: (state: z.output<TSchema>, id: string) => {
|
|
220
|
+
methods: Record<string, (...args: unknown[]) => unknown>;
|
|
221
|
+
/** Events emitted by the most recent method call. Cleared each call. */
|
|
222
|
+
recorded: ReadonlyArray<{
|
|
223
|
+
eventName: string;
|
|
224
|
+
payload: unknown;
|
|
225
|
+
}>;
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* The shape returned by `ctx.use(Actor, id)`: the loaded `state` plus every
|
|
230
|
+
* method from the actor definition, pre-bound to that state.
|
|
231
|
+
*/
|
|
232
|
+
export type ActorInstanceView<TActor> = TActor extends ActorDefinition<infer TSchema, infer TMethods> ? {
|
|
233
|
+
readonly state: Readonly<z.output<TSchema>>;
|
|
234
|
+
readonly key: string;
|
|
235
|
+
readonly stateName: string;
|
|
236
|
+
} & {
|
|
237
|
+
readonly [K in keyof TMethods]: TMethods[K] extends (state: z.output<TSchema>, ...args: infer A) => infer R ? (...args: A) => R : never;
|
|
238
|
+
} : never;
|
|
239
|
+
/**
|
|
240
|
+
* Schema-bound form: the actor borrows `key`, `initial`, and the set of valid
|
|
241
|
+
* state names from a `SchemaDefinition`. Per-state `on`/`after` transitions are
|
|
242
|
+
* still declared here, but only for states declared in the schema. States the
|
|
243
|
+
* schema marks `final: true` cannot have `on:` reactions.
|
|
244
|
+
*
|
|
245
|
+
* const Submission = defineActor({
|
|
246
|
+
* schema: SubmissionData, // SchemaDefinition
|
|
247
|
+
* states: {
|
|
248
|
+
* submitted: { on: { ... } },
|
|
249
|
+
* "under-review": { on: { ... }, after: { ... } },
|
|
250
|
+
* // graded is final in the schema — omit it
|
|
251
|
+
* },
|
|
252
|
+
* methods: { ... },
|
|
253
|
+
* });
|
|
254
|
+
*/
|
|
255
|
+
export interface ActorOptionsBound<TFields extends Readonly<Record<string, ZodTypeAny>>, TMethods extends Readonly<Record<string, ActorMethod<z.output<z.ZodObject<TFields>>>>> = Readonly<Record<string, ActorMethod<z.output<z.ZodObject<TFields>>>>>> {
|
|
256
|
+
/** Optional — defaults to `schema.name`. */
|
|
257
|
+
readonly name?: string;
|
|
258
|
+
readonly schema: SchemaDefinition<TFields>;
|
|
259
|
+
/** Per-state transition tables. Only states declared in the schema are valid. */
|
|
260
|
+
readonly states?: Readonly<Record<string, ActorStateConfig<z.output<z.ZodObject<TFields>>>>>;
|
|
261
|
+
readonly methods?: TMethods;
|
|
262
|
+
readonly stuckThresholds?: ActorStuckThresholds;
|
|
263
|
+
readonly slas?: ActorSlas;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Closure form options — what `defineActor(schema, fn, options?)` accepts
|
|
267
|
+
* for stuckThresholds + slas + name override. The transitions + methods
|
|
268
|
+
* live in the closure body.
|
|
269
|
+
*/
|
|
270
|
+
export interface ActorOptionsClosure {
|
|
271
|
+
readonly name?: string;
|
|
272
|
+
readonly stuckThresholds?: ActorStuckThresholds;
|
|
273
|
+
readonly slas?: ActorSlas;
|
|
274
|
+
}
|
|
275
|
+
export declare function defineActor<TSchema extends ZodTypeAny, TMethods extends Readonly<Record<string, ActorMethod<z.output<TSchema>>>> = Readonly<Record<string, ActorMethod<z.output<TSchema>>>>>(name: string, options: ActorOptions<TSchema, TMethods>): ActorDefinition<TSchema, TMethods>;
|
|
276
|
+
export declare function defineActor<TFields extends Readonly<Record<string, ZodTypeAny>>, TMethods extends Readonly<Record<string, ActorMethod<z.output<z.ZodObject<TFields>>>>> = Readonly<Record<string, ActorMethod<z.output<z.ZodObject<TFields>>>>>>(options: ActorOptionsBound<TFields, TMethods>): ActorDefinition<z.ZodObject<TFields>, TMethods>;
|
|
277
|
+
/**
|
|
278
|
+
* Closure form:
|
|
279
|
+
*
|
|
280
|
+
* const Station = defineActor(StationData,
|
|
281
|
+
* ({ data, id, validate, recordThat, states, when, methods }) => {
|
|
282
|
+
* const { active, decommissioned } = states
|
|
283
|
+
* const create = (input) => { validate(...); recordThat(Created({...})); }
|
|
284
|
+
* when(Created, (e, { assign }) => { assign({...}) })
|
|
285
|
+
* when(Deleted, (e, { assign }) => { assign({...}); return decommissioned })
|
|
286
|
+
* return methods({ create })
|
|
287
|
+
* },
|
|
288
|
+
* { stuckThresholds: { ... } },
|
|
289
|
+
* )
|
|
290
|
+
*
|
|
291
|
+
* The closure runs once at define time to register transitions + capture
|
|
292
|
+
* method names; the runtime re-runs it per `use(Actor, id)` call to produce
|
|
293
|
+
* bound methods over the live state.
|
|
294
|
+
*/
|
|
295
|
+
export declare function defineActor<TFields extends Readonly<Record<string, ZodTypeAny>>>(schema: SchemaDefinition<TFields>, body: (ctx: ActorClosureContext<z.output<z.ZodObject<TFields>>>) => Record<string, (...args: never[]) => unknown> | void, options?: ActorOptionsClosure): ActorDefinition<z.ZodObject<TFields>, any>;
|
|
296
|
+
/**
|
|
297
|
+
* Helper: turn an `EventDefinition` reference into a string suitable for the
|
|
298
|
+
* `on` map key. Equivalent to `Event.name` but reads as `eventKey(Event)` at
|
|
299
|
+
* call sites where the import is shorter.
|
|
300
|
+
*/
|
|
301
|
+
export declare function eventKey(event: EventDefinition): string;
|
|
302
|
+
//# sourceMappingURL=define-actor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-actor.d.ts","sourceRoot":"","sources":["../src/define-actor.ts"],"names":[],"mappings":"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"}
|