workflow 4.2.0-beta.74 → 4.2.0-beta.75
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/docs/api-reference/workflow/create-webhook.mdx +4 -0
- package/docs/api-reference/workflow-api/get-world.mdx +33 -157
- package/docs/api-reference/workflow-api/index.mdx +3 -0
- package/docs/api-reference/workflow-api/world/events.mdx +227 -0
- package/docs/api-reference/workflow-api/world/hooks.mdx +181 -0
- package/docs/api-reference/workflow-api/world/index.mdx +67 -0
- package/docs/api-reference/workflow-api/world/meta.json +12 -0
- package/docs/api-reference/workflow-api/world/observability.mdx +289 -0
- package/docs/api-reference/workflow-api/world/queue.mdx +127 -0
- package/docs/api-reference/workflow-api/world/runs.mdx +223 -0
- package/docs/api-reference/workflow-api/world/steps.mdx +216 -0
- package/docs/api-reference/workflow-api/world/streams.mdx +152 -0
- package/docs/foundations/hooks.mdx +4 -0
- package/docs/foundations/streaming.mdx +1 -0
- package/package.json +11 -11
|
@@ -13,6 +13,10 @@ Creates a webhook that can be used to suspend and resume a workflow run upon rec
|
|
|
13
13
|
|
|
14
14
|
Webhooks provide a way for external systems to send HTTP requests directly to your workflow. Unlike hooks which accept arbitrary payloads, webhooks work with standard HTTP `Request` objects and can return HTTP `Response` objects.
|
|
15
15
|
|
|
16
|
+
<Callout type="warn">
|
|
17
|
+
`createWebhook()` creates a public endpoint at `/.well-known/workflow/v1/webhook/:token`, and the token in that URL is the only authorization performed for incoming requests resuming that webhook. This is convenient for prototypes and simple resume links because it avoids creating another route, but if you need stronger security, prefer [`createHook()`](/docs/api-reference/workflow/create-hook) behind your own route and authorize the request before calling [`resumeHook()`](/docs/api-reference/workflow-api/resume-hook) to avoid unauthenticated workflow resumptions.
|
|
18
|
+
</Callout>
|
|
19
|
+
|
|
16
20
|
```ts lineNumbers
|
|
17
21
|
import { createWebhook } from "workflow"
|
|
18
22
|
|
|
@@ -14,7 +14,7 @@ Use this function when you need direct access to the underlying workflow infrast
|
|
|
14
14
|
```typescript lineNumbers
|
|
15
15
|
import { getWorld } from "workflow/runtime";
|
|
16
16
|
|
|
17
|
-
const world = getWorld();
|
|
17
|
+
const world = getWorld(); // [!code highlight]
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
## API Signature
|
|
@@ -34,167 +34,43 @@ export default World;`}
|
|
|
34
34
|
showSections={["returns"]}
|
|
35
35
|
/>
|
|
36
36
|
|
|
37
|
-
##
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
### Cancel a Workflow Run
|
|
67
|
-
|
|
68
|
-
Cancel a running workflow:
|
|
69
|
-
|
|
70
|
-
```typescript lineNumbers
|
|
71
|
-
import { getWorld } from "workflow/runtime";
|
|
72
|
-
|
|
73
|
-
export async function POST(req: Request) {
|
|
74
|
-
const { runId } = await req.json();
|
|
75
|
-
|
|
76
|
-
if (!runId) {
|
|
77
|
-
return Response.json({ error: "No runId provided" }, { status: 400 });
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
const world = getWorld(); // [!code highlight]
|
|
82
|
-
const run = await world.runs.cancel(runId); // [!code highlight]
|
|
83
|
-
|
|
84
|
-
return Response.json({ status: run.status });
|
|
85
|
-
} catch (error) {
|
|
86
|
-
return Response.json(
|
|
87
|
-
{ error: "Failed to cancel workflow run" },
|
|
88
|
-
{ status: 500 }
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### List Steps for a Run (Without Data)
|
|
95
|
-
|
|
96
|
-
List steps for a workflow run with `resolveData: 'none'` to efficiently get step metadata without fetching serialized input/output. Use `parseStepName` to extract user-friendly display names:
|
|
37
|
+
## World SDK
|
|
38
|
+
|
|
39
|
+
The World object provides access to several entity interfaces. See the [World SDK](/docs/api-reference/workflow-api/world) reference for complete documentation:
|
|
40
|
+
|
|
41
|
+
<Cards>
|
|
42
|
+
<Card href="/docs/api-reference/workflow-api/world/runs" title="world.runs">
|
|
43
|
+
List, filter, and inspect workflow runs.
|
|
44
|
+
</Card>
|
|
45
|
+
<Card href="/docs/api-reference/workflow-api/world/steps" title="world.steps">
|
|
46
|
+
List and inspect step execution data.
|
|
47
|
+
</Card>
|
|
48
|
+
<Card href="/docs/api-reference/workflow-api/world/hooks" title="world.hooks">
|
|
49
|
+
Look up hooks by ID or token.
|
|
50
|
+
</Card>
|
|
51
|
+
<Card href="/docs/api-reference/workflow-api/world/events" title="world.events">
|
|
52
|
+
Query the append-only event log.
|
|
53
|
+
</Card>
|
|
54
|
+
<Card href="/docs/api-reference/workflow-api/world/streams" title="world.streams">
|
|
55
|
+
Read, write, and manage data streams.
|
|
56
|
+
</Card>
|
|
57
|
+
<Card href="/docs/api-reference/workflow-api/world/queue" title="world.queue">
|
|
58
|
+
Enqueue runs and create queue handlers.
|
|
59
|
+
</Card>
|
|
60
|
+
</Cards>
|
|
61
|
+
|
|
62
|
+
## Data Hydration
|
|
63
|
+
|
|
64
|
+
Step and run data is serialized using the [devalue](https://github.com/Rich-Harris/devalue) format. Use `workflow/observability` to hydrate it for display:
|
|
97
65
|
|
|
98
66
|
```typescript lineNumbers
|
|
99
|
-
import {
|
|
100
|
-
import { parseStepName } from "@workflow/utils/parse-name"; // [!code highlight]
|
|
101
|
-
|
|
102
|
-
export async function GET(req: Request) {
|
|
103
|
-
const url = new URL(req.url);
|
|
104
|
-
const runId = url.searchParams.get("runId");
|
|
105
|
-
|
|
106
|
-
if (!runId) {
|
|
107
|
-
return Response.json({ error: "No runId provided" }, { status: 400 });
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
const world = getWorld(); // [!code highlight]
|
|
112
|
-
const steps = await world.steps.list({ // [!code highlight]
|
|
113
|
-
runId, // [!code highlight]
|
|
114
|
-
resolveData: "none", // Skip fetching input/output for performance // [!code highlight]
|
|
115
|
-
}); // [!code highlight]
|
|
116
|
-
|
|
117
|
-
// Map steps to a progress view using parseStepName for display
|
|
118
|
-
const progress = steps.data.map((step) => {
|
|
119
|
-
const parsed = parseStepName(step.stepName); // [!code highlight]
|
|
120
|
-
return {
|
|
121
|
-
stepId: step.stepId,
|
|
122
|
-
// Use shortName for UI display (e.g., "fetchUserData") // [!code highlight]
|
|
123
|
-
displayName: parsed?.shortName ?? step.stepName, // [!code highlight]
|
|
124
|
-
// Module info available for debugging // [!code highlight]
|
|
125
|
-
module: parsed?.moduleSpecifier, // [!code highlight]
|
|
126
|
-
status: step.status,
|
|
127
|
-
startedAt: step.startedAt,
|
|
128
|
-
completedAt: step.completedAt,
|
|
129
|
-
};
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
return Response.json({ progress, cursor: steps.cursor });
|
|
133
|
-
} catch (error) {
|
|
134
|
-
return Response.json(
|
|
135
|
-
{ error: "Failed to list steps" },
|
|
136
|
-
{ status: 500 }
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### Get Step with Hydrated Input/Output
|
|
143
|
-
|
|
144
|
-
Retrieve a step with its serialized data and hydrate it for display. This example shows how to decrypt and deserialize step input/output:
|
|
67
|
+
import { hydrateResourceIO, observabilityRevivers } from "workflow/observability"; // [!code highlight]
|
|
145
68
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
import { parseStepName } from "@workflow/utils/parse-name"; // [!code highlight]
|
|
149
|
-
import { // [!code highlight]
|
|
150
|
-
hydrateResourceIO, // [!code highlight]
|
|
151
|
-
observabilityRevivers, // [!code highlight]
|
|
152
|
-
} from "@workflow/core/serialization-format"; // [!code highlight]
|
|
153
|
-
|
|
154
|
-
export async function GET(req: Request) {
|
|
155
|
-
const url = new URL(req.url);
|
|
156
|
-
const runId = url.searchParams.get("runId");
|
|
157
|
-
const stepId = url.searchParams.get("stepId");
|
|
158
|
-
|
|
159
|
-
if (!runId || !stepId) {
|
|
160
|
-
return Response.json({ error: "runId and stepId required" }, { status: 400 });
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
try {
|
|
164
|
-
const world = getWorld(); // [!code highlight]
|
|
165
|
-
// Fetch step with data (default resolveData behavior) // [!code highlight]
|
|
166
|
-
const step = await world.steps.get(runId, stepId); // [!code highlight]
|
|
167
|
-
|
|
168
|
-
// Hydrate serialized input/output for display // [!code highlight]
|
|
169
|
-
const hydrated = hydrateResourceIO(step, observabilityRevivers); // [!code highlight]
|
|
170
|
-
|
|
171
|
-
// Parse the stepName for user-friendly display
|
|
172
|
-
const parsed = parseStepName(step.stepName);
|
|
173
|
-
|
|
174
|
-
return Response.json({
|
|
175
|
-
stepId: hydrated.stepId,
|
|
176
|
-
displayName: parsed?.shortName ?? step.stepName, // [!code highlight]
|
|
177
|
-
module: parsed?.moduleSpecifier, // [!code highlight]
|
|
178
|
-
status: hydrated.status,
|
|
179
|
-
attempt: hydrated.attempt,
|
|
180
|
-
// Hydrated input/output ready for rendering // [!code highlight]
|
|
181
|
-
input: hydrated.input, // [!code highlight]
|
|
182
|
-
output: hydrated.output, // [!code highlight]
|
|
183
|
-
});
|
|
184
|
-
} catch (error) {
|
|
185
|
-
return Response.json(
|
|
186
|
-
{ error: "Step not found" },
|
|
187
|
-
{ status: 404 }
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
69
|
+
const step = await world.steps.get(runId, stepId);
|
|
70
|
+
const hydrated = hydrateResourceIO(step, observabilityRevivers); // [!code highlight]
|
|
191
71
|
```
|
|
192
72
|
|
|
193
|
-
|
|
194
|
-
The `stepName` field contains a machine-readable identifier like `step//./src/workflows/order//processPayment`.
|
|
195
|
-
Use `parseStepName()` from `@workflow/utils/parse-name` to extract the `shortName` (e.g., `"processPayment"`)
|
|
196
|
-
and `moduleSpecifier` for display in your UI.
|
|
197
|
-
</Callout>
|
|
73
|
+
See [Observability Utilities](/docs/api-reference/workflow-api/world/observability) for the full hydration, parsing, and encryption API.
|
|
198
74
|
|
|
199
75
|
## Related Functions
|
|
200
76
|
|
|
@@ -30,4 +30,7 @@ The API package is for access and introspection of workflow data to inspect runs
|
|
|
30
30
|
<Card href="/docs/api-reference/workflow-api/get-world" title="getWorld()">
|
|
31
31
|
Get direct access to workflow storage, queuing, and streaming backends.
|
|
32
32
|
</Card>
|
|
33
|
+
<Card href="/docs/api-reference/workflow-api/world" title="World SDK">
|
|
34
|
+
Low-level API for inspecting runs, steps, events, hooks, streams, and queues.
|
|
35
|
+
</Card>
|
|
33
36
|
</Cards>
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: world.events
|
|
3
|
+
description: Query the append-only event log for workflow state changes, audit trails, and run cancellation.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: "Methods: create(), get(), list(), listByCorrelationId(). The event log is the source of truth for all workflow state."
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/api-reference/workflow-api/get-world
|
|
8
|
+
related:
|
|
9
|
+
- /docs/api-reference/workflow-api/world/runs
|
|
10
|
+
- /docs/api-reference/workflow-api/world/steps
|
|
11
|
+
keywords:
|
|
12
|
+
- world.events
|
|
13
|
+
- world.events.create
|
|
14
|
+
- world.events.get
|
|
15
|
+
- world.events.list
|
|
16
|
+
- world.events.listByCorrelationId
|
|
17
|
+
- event log
|
|
18
|
+
- audit trail
|
|
19
|
+
- run_cancelled
|
|
20
|
+
- event types
|
|
21
|
+
- correlation ID
|
|
22
|
+
- cancel workflow run
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
The `world.events` interface provides access to the append-only event log that drives all workflow state. Runs, steps, and hooks are materialized views derived from events. Use this interface for audit trails, debugging, and programmatic run cancellation.
|
|
26
|
+
|
|
27
|
+
## Import
|
|
28
|
+
|
|
29
|
+
```typescript lineNumbers
|
|
30
|
+
import { getWorld } from "workflow/runtime";
|
|
31
|
+
|
|
32
|
+
const world = getWorld();
|
|
33
|
+
const events = world.events; // [!code highlight]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Methods
|
|
37
|
+
|
|
38
|
+
### create()
|
|
39
|
+
|
|
40
|
+
Create a new event for a workflow run. Most commonly used to cancel a run.
|
|
41
|
+
|
|
42
|
+
```typescript lineNumbers
|
|
43
|
+
await world.events.create(runId, { // [!code highlight]
|
|
44
|
+
eventType: "run_cancelled", // [!code highlight]
|
|
45
|
+
}); // [!code highlight]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Parameters:**
|
|
49
|
+
|
|
50
|
+
| Parameter | Type | Description |
|
|
51
|
+
|-----------|------|-------------|
|
|
52
|
+
| `runId` | `string` | The workflow run ID |
|
|
53
|
+
| `data` | `object` | Event data including `eventType` |
|
|
54
|
+
| `params` | `object` | Optional parameters |
|
|
55
|
+
|
|
56
|
+
**Returns:** `Event`
|
|
57
|
+
|
|
58
|
+
### get()
|
|
59
|
+
|
|
60
|
+
Retrieve a single event by run ID and event ID.
|
|
61
|
+
|
|
62
|
+
```typescript lineNumbers
|
|
63
|
+
const event = await world.events.get(runId, eventId); // [!code highlight]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Parameters:**
|
|
67
|
+
|
|
68
|
+
| Parameter | Type | Description |
|
|
69
|
+
|-----------|------|-------------|
|
|
70
|
+
| `runId` | `string` | The workflow run ID |
|
|
71
|
+
| `eventId` | `string` | The event ID |
|
|
72
|
+
| `params` | `object` | Optional parameters |
|
|
73
|
+
|
|
74
|
+
**Returns:** `Event`
|
|
75
|
+
|
|
76
|
+
### list()
|
|
77
|
+
|
|
78
|
+
List events with cursor pagination.
|
|
79
|
+
|
|
80
|
+
```typescript lineNumbers
|
|
81
|
+
const result = await world.events.list({ // [!code highlight]
|
|
82
|
+
runId,
|
|
83
|
+
pagination: { cursor },
|
|
84
|
+
}); // [!code highlight]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Parameters:**
|
|
88
|
+
|
|
89
|
+
| Parameter | Type | Description |
|
|
90
|
+
|-----------|------|-------------|
|
|
91
|
+
| `params.runId` | `string` | Filter events by run ID |
|
|
92
|
+
| `params.pagination.cursor` | `string` | Cursor for the next page |
|
|
93
|
+
|
|
94
|
+
**Returns:** `{ data: Event[], cursor?: string }`
|
|
95
|
+
|
|
96
|
+
### listByCorrelationId()
|
|
97
|
+
|
|
98
|
+
List events that share a correlation ID, useful for tracing related events across runs.
|
|
99
|
+
|
|
100
|
+
```typescript lineNumbers
|
|
101
|
+
const result = await world.events.listByCorrelationId({ // [!code highlight]
|
|
102
|
+
correlationId: "order-123",
|
|
103
|
+
}); // [!code highlight]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Parameters:**
|
|
107
|
+
|
|
108
|
+
| Parameter | Type | Description |
|
|
109
|
+
|-----------|------|-------------|
|
|
110
|
+
| `params.correlationId` | `string` | The correlation ID to filter by |
|
|
111
|
+
| `params.pagination.cursor` | `string` | Cursor for the next page |
|
|
112
|
+
|
|
113
|
+
**Returns:** `{ data: Event[], cursor?: string }`
|
|
114
|
+
|
|
115
|
+
## Event Types
|
|
116
|
+
|
|
117
|
+
Events are grouped by the entity they affect:
|
|
118
|
+
|
|
119
|
+
### Run Events
|
|
120
|
+
|
|
121
|
+
| Event Type | Description |
|
|
122
|
+
|-----------|-------------|
|
|
123
|
+
| `run_created` | Workflow run was created |
|
|
124
|
+
| `run_started` | Workflow run execution began |
|
|
125
|
+
| `run_completed` | Workflow run completed successfully |
|
|
126
|
+
| `run_failed` | Workflow run failed with an error |
|
|
127
|
+
| `run_cancelled` | Workflow run was cancelled |
|
|
128
|
+
|
|
129
|
+
### Step Events
|
|
130
|
+
|
|
131
|
+
| Event Type | Description |
|
|
132
|
+
|-----------|-------------|
|
|
133
|
+
| `step_created` | Step was created |
|
|
134
|
+
| `step_started` | Step execution began |
|
|
135
|
+
| `step_completed` | Step completed successfully |
|
|
136
|
+
| `step_failed` | Step failed with an error |
|
|
137
|
+
| `step_retrying` | Step scheduled for retry |
|
|
138
|
+
|
|
139
|
+
### Hook Events
|
|
140
|
+
|
|
141
|
+
| Event Type | Description |
|
|
142
|
+
|-----------|-------------|
|
|
143
|
+
| `hook_created` | Hook was created (workflow paused) |
|
|
144
|
+
| `hook_received` | Hook received a payload |
|
|
145
|
+
| `hook_disposed` | Hook was disposed (workflow reached terminal state) |
|
|
146
|
+
| `hook_conflict` | Hook token conflict detected |
|
|
147
|
+
|
|
148
|
+
### Wait Events
|
|
149
|
+
|
|
150
|
+
| Event Type | Description |
|
|
151
|
+
|-----------|-------------|
|
|
152
|
+
| `wait_created` | Workflow entered a wait state (e.g., `sleep()`) |
|
|
153
|
+
| `wait_completed` | Wait state completed |
|
|
154
|
+
|
|
155
|
+
<Callout type="info">
|
|
156
|
+
Events are the append-only source of truth for all workflow state. `WorkflowRun`, `Step`, and `Hook` objects are materialized views derived from these events.
|
|
157
|
+
</Callout>
|
|
158
|
+
|
|
159
|
+
## Examples
|
|
160
|
+
|
|
161
|
+
### List Events for a Run as Audit Trail
|
|
162
|
+
|
|
163
|
+
```typescript lineNumbers
|
|
164
|
+
// app/api/workflow-events/route.ts
|
|
165
|
+
import { getWorld } from "workflow/runtime";
|
|
166
|
+
|
|
167
|
+
export async function GET(req: Request) {
|
|
168
|
+
const url = new URL(req.url);
|
|
169
|
+
const runId = url.searchParams.get("runId");
|
|
170
|
+
|
|
171
|
+
if (!runId) {
|
|
172
|
+
return Response.json({ error: "runId required" }, { status: 400 });
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const world = getWorld();
|
|
176
|
+
const events = await world.events.list({ runId }); // [!code highlight]
|
|
177
|
+
|
|
178
|
+
return Response.json(events);
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Cancel a Run via Event Creation
|
|
183
|
+
|
|
184
|
+
Cancelling a run is done by creating a `run_cancelled` event:
|
|
185
|
+
|
|
186
|
+
```typescript lineNumbers
|
|
187
|
+
// app/api/workflow-runs/cancel/route.ts
|
|
188
|
+
import { getWorld } from "workflow/runtime";
|
|
189
|
+
|
|
190
|
+
export async function POST(req: Request) {
|
|
191
|
+
const { runId } = await req.json();
|
|
192
|
+
|
|
193
|
+
const world = getWorld();
|
|
194
|
+
await world.events.create(runId, { // [!code highlight]
|
|
195
|
+
eventType: "run_cancelled", // [!code highlight]
|
|
196
|
+
}); // [!code highlight]
|
|
197
|
+
|
|
198
|
+
return Response.json({ cancelled: true });
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
<Callout type="info">
|
|
203
|
+
`world.runs.cancel(runId)` is a convenience wrapper around this event creation pattern. Use `world.events.create()` directly when you need to attach custom data to the cancellation event.
|
|
204
|
+
</Callout>
|
|
205
|
+
|
|
206
|
+
### List Events by Correlation ID
|
|
207
|
+
|
|
208
|
+
Trace related events across workflow runs using a shared correlation ID:
|
|
209
|
+
|
|
210
|
+
```typescript lineNumbers
|
|
211
|
+
import { getWorld } from "workflow/runtime";
|
|
212
|
+
|
|
213
|
+
const world = getWorld();
|
|
214
|
+
const events = await world.events.listByCorrelationId({ // [!code highlight]
|
|
215
|
+
correlationId: "order-123", // [!code highlight]
|
|
216
|
+
}); // [!code highlight]
|
|
217
|
+
|
|
218
|
+
for (const event of events.data) {
|
|
219
|
+
console.log(event.eventType, event.runId, event.createdAt);
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Related
|
|
224
|
+
|
|
225
|
+
- [world.runs](/docs/api-reference/workflow-api/world/runs) — Inspect runs (materialized from events)
|
|
226
|
+
- [world.steps](/docs/api-reference/workflow-api/world/steps) — Inspect steps (materialized from events)
|
|
227
|
+
- [world.hooks](/docs/api-reference/workflow-api/world/hooks) — Inspect hooks (materialized from events)
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: world.hooks
|
|
3
|
+
description: Look up workflow hooks by ID or token for webhook resume flows and metadata inspection.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: "Methods: get(), getByToken(), list(). Query hook details for resume flows."
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/api-reference/workflow-api/get-world
|
|
8
|
+
related:
|
|
9
|
+
- /docs/api-reference/workflow-api/world/events
|
|
10
|
+
- /docs/api-reference/workflow-api/resume-hook
|
|
11
|
+
- /docs/api-reference/workflow-api/resume-webhook
|
|
12
|
+
keywords:
|
|
13
|
+
- world.hooks
|
|
14
|
+
- world.hooks.get
|
|
15
|
+
- world.hooks.getByToken
|
|
16
|
+
- world.hooks.list
|
|
17
|
+
- Hook
|
|
18
|
+
- webhook token
|
|
19
|
+
- hook metadata
|
|
20
|
+
- resume flow
|
|
21
|
+
- pending approvals
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
The `world.hooks` interface provides access to workflow hook data. Hooks are pause points in workflows that wait for external input. Use this interface to look up hooks by ID or token, inspect metadata, and build admin UIs for pending approvals.
|
|
25
|
+
|
|
26
|
+
## Import
|
|
27
|
+
|
|
28
|
+
```typescript lineNumbers
|
|
29
|
+
import { getWorld } from "workflow/runtime";
|
|
30
|
+
|
|
31
|
+
const world = getWorld();
|
|
32
|
+
const hooks = world.hooks; // [!code highlight]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Methods
|
|
36
|
+
|
|
37
|
+
### get()
|
|
38
|
+
|
|
39
|
+
Retrieve a hook by its ID.
|
|
40
|
+
|
|
41
|
+
```typescript lineNumbers
|
|
42
|
+
const hook = await world.hooks.get(hookId); // [!code highlight]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Parameters:**
|
|
46
|
+
|
|
47
|
+
| Parameter | Type | Description |
|
|
48
|
+
|-----------|------|-------------|
|
|
49
|
+
| `hookId` | `string` | The hook ID |
|
|
50
|
+
| `params` | `object` | Optional parameters |
|
|
51
|
+
|
|
52
|
+
**Returns:** `Hook`
|
|
53
|
+
|
|
54
|
+
### getByToken()
|
|
55
|
+
|
|
56
|
+
Look up a hook by its token. Useful in webhook resume flows where you receive a token in the callback URL.
|
|
57
|
+
|
|
58
|
+
```typescript lineNumbers
|
|
59
|
+
const hook = await world.hooks.getByToken(token); // [!code highlight]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Parameters:**
|
|
63
|
+
|
|
64
|
+
| Parameter | Type | Description |
|
|
65
|
+
|-----------|------|-------------|
|
|
66
|
+
| `token` | `string` | The hook token |
|
|
67
|
+
| `params` | `object` | Optional parameters |
|
|
68
|
+
|
|
69
|
+
**Returns:** `Hook`
|
|
70
|
+
|
|
71
|
+
### list()
|
|
72
|
+
|
|
73
|
+
List hooks with cursor pagination.
|
|
74
|
+
|
|
75
|
+
```typescript lineNumbers
|
|
76
|
+
const result = await world.hooks.list({ // [!code highlight]
|
|
77
|
+
pagination: { cursor },
|
|
78
|
+
}); // [!code highlight]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Parameters:**
|
|
82
|
+
|
|
83
|
+
| Parameter | Type | Description |
|
|
84
|
+
|-----------|------|-------------|
|
|
85
|
+
| `params.pagination.cursor` | `string` | Cursor for the next page |
|
|
86
|
+
|
|
87
|
+
**Returns:** `{ data: Hook[], cursor?: string }`
|
|
88
|
+
|
|
89
|
+
## Types
|
|
90
|
+
|
|
91
|
+
### Hook
|
|
92
|
+
|
|
93
|
+
| Field | Type | Description |
|
|
94
|
+
|-------|------|-------------|
|
|
95
|
+
| `runId` | `string` | Parent workflow run ID |
|
|
96
|
+
| `hookId` | `string` | Unique hook identifier |
|
|
97
|
+
| `token` | `string` | Hook token for resuming |
|
|
98
|
+
| `ownerId` | `string` | Owner (team/user) ID |
|
|
99
|
+
| `projectId` | `string` | Project ID |
|
|
100
|
+
| `environment` | `string` | Deployment environment |
|
|
101
|
+
| `metadata` | `object` | Custom metadata attached to the hook |
|
|
102
|
+
| `isWebhook` | `boolean` | Whether this is a webhook-style hook |
|
|
103
|
+
|
|
104
|
+
## Examples
|
|
105
|
+
|
|
106
|
+
### Look Up Hook by ID
|
|
107
|
+
|
|
108
|
+
```typescript lineNumbers
|
|
109
|
+
// app/api/workflow-hooks/route.ts
|
|
110
|
+
import { getWorld } from "workflow/runtime";
|
|
111
|
+
|
|
112
|
+
export async function GET(req: Request) {
|
|
113
|
+
const url = new URL(req.url);
|
|
114
|
+
const hookId = url.searchParams.get("hookId");
|
|
115
|
+
|
|
116
|
+
if (!hookId) {
|
|
117
|
+
return Response.json({ error: "hookId required" }, { status: 400 });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const world = getWorld();
|
|
121
|
+
const hook = await world.hooks.get(hookId); // [!code highlight]
|
|
122
|
+
|
|
123
|
+
return Response.json({
|
|
124
|
+
hookId: hook.hookId,
|
|
125
|
+
runId: hook.runId,
|
|
126
|
+
token: hook.token,
|
|
127
|
+
metadata: hook.metadata,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Look Up Hook by Token for Webhook Resume
|
|
133
|
+
|
|
134
|
+
When you receive a webhook callback with a token, look up the hook to inspect metadata before resuming:
|
|
135
|
+
|
|
136
|
+
```typescript lineNumbers
|
|
137
|
+
// app/api/workflow-hooks/resume/route.ts
|
|
138
|
+
import { getWorld } from "workflow/runtime";
|
|
139
|
+
|
|
140
|
+
export async function POST(req: Request) {
|
|
141
|
+
const { token } = await req.json();
|
|
142
|
+
|
|
143
|
+
const world = getWorld();
|
|
144
|
+
const hook = await world.hooks.getByToken(token); // [!code highlight]
|
|
145
|
+
|
|
146
|
+
// Inspect hook metadata before deciding to resume
|
|
147
|
+
console.log(hook.runId, hook.metadata); // [!code highlight]
|
|
148
|
+
|
|
149
|
+
return Response.json({
|
|
150
|
+
runId: hook.runId,
|
|
151
|
+
hookId: hook.hookId,
|
|
152
|
+
metadata: hook.metadata,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### List All Hooks for Pending Approvals Dashboard
|
|
158
|
+
|
|
159
|
+
```typescript lineNumbers
|
|
160
|
+
// app/api/workflow-hooks/pending/route.ts
|
|
161
|
+
import { getWorld } from "workflow/runtime";
|
|
162
|
+
|
|
163
|
+
export async function GET(req: Request) {
|
|
164
|
+
const url = new URL(req.url);
|
|
165
|
+
const cursor = url.searchParams.get("cursor") ?? undefined;
|
|
166
|
+
|
|
167
|
+
const world = getWorld();
|
|
168
|
+
const hooks = await world.hooks.list({ // [!code highlight]
|
|
169
|
+
pagination: { cursor },
|
|
170
|
+
}); // [!code highlight]
|
|
171
|
+
|
|
172
|
+
return Response.json(hooks);
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Related
|
|
177
|
+
|
|
178
|
+
- [resumeHook()](/docs/api-reference/workflow-api/resume-hook) — Resume a workflow by sending a payload to a hook
|
|
179
|
+
- [resumeWebhook()](/docs/api-reference/workflow-api/resume-webhook) — Resume a workflow via webhook
|
|
180
|
+
- [getHookByToken()](/docs/api-reference/workflow-api/get-hook-by-token) — Higher-level API for hook lookup
|
|
181
|
+
- [Hooks](/docs/foundations/hooks) — Core concepts for hooks and pause points
|