Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 33 additions & 157 deletions docs/content/docs/api-reference/workflow-api/get-world.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Use this function when you need direct access to the underlying workflow infrast
```typescript lineNumbers
import { getWorld } from "workflow/runtime";

const world = getWorld();
const world = getWorld(); // [!code highlight]
```

## API Signature
Expand All @@ -34,167 +34,43 @@ export default World;`}
showSections={["returns"]}
/>

## Examples

### List Workflow Runs

List all workflow runs with pagination:

```typescript lineNumbers
import { getWorld } from "workflow/runtime";

export async function GET(req: Request) {
const url = new URL(req.url);
const cursor = url.searchParams.get("cursor") ?? undefined;

try {
const world = getWorld(); // [!code highlight]
const runs = await world.runs.list({
pagination: { cursor },
});

return Response.json(runs);
} catch (error) {
return Response.json(
{ error: "Failed to list workflow runs" },
{ status: 500 }
);
}
}
```

### Cancel a Workflow Run

Cancel a running workflow:

```typescript lineNumbers
import { getWorld } from "workflow/runtime";

export async function POST(req: Request) {
const { runId } = await req.json();

if (!runId) {
return Response.json({ error: "No runId provided" }, { status: 400 });
}

try {
const world = getWorld(); // [!code highlight]
const run = await world.runs.cancel(runId); // [!code highlight]

return Response.json({ status: run.status });
} catch (error) {
return Response.json(
{ error: "Failed to cancel workflow run" },
{ status: 500 }
);
}
}
```

### List Steps for a Run (Without Data)

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:
## World SDK

The World object provides access to several entity interfaces. See the [World SDK](/docs/api-reference/workflow-api/world) reference for complete documentation:

<Cards>
<Card href="/docs/api-reference/workflow-api/world/runs" title="world.runs">
List, filter, and inspect workflow runs.
</Card>
<Card href="/docs/api-reference/workflow-api/world/steps" title="world.steps">
List and inspect step execution data.
</Card>
<Card href="/docs/api-reference/workflow-api/world/hooks" title="world.hooks">
Look up hooks by ID or token.
</Card>
<Card href="/docs/api-reference/workflow-api/world/events" title="world.events">
Query the append-only event log.
</Card>
<Card href="/docs/api-reference/workflow-api/world/streams" title="world.streams">
Read, write, and manage data streams.
</Card>
<Card href="/docs/api-reference/workflow-api/world/queue" title="world.queue">
Enqueue runs and create queue handlers.
</Card>
</Cards>

## Data Hydration

Step and run data is serialized using the [devalue](https://github.com/Rich-Harris/devalue) format. Use `workflow/observability` to hydrate it for display:

```typescript lineNumbers
import { getWorld } from "workflow/runtime";
import { parseStepName } from "@workflow/utils/parse-name"; // [!code highlight]

export async function GET(req: Request) {
const url = new URL(req.url);
const runId = url.searchParams.get("runId");

if (!runId) {
return Response.json({ error: "No runId provided" }, { status: 400 });
}

try {
const world = getWorld(); // [!code highlight]
const steps = await world.steps.list({ // [!code highlight]
runId, // [!code highlight]
resolveData: "none", // Skip fetching input/output for performance // [!code highlight]
}); // [!code highlight]

// Map steps to a progress view using parseStepName for display
const progress = steps.data.map((step) => {
const parsed = parseStepName(step.stepName); // [!code highlight]
return {
stepId: step.stepId,
// Use shortName for UI display (e.g., "fetchUserData") // [!code highlight]
displayName: parsed?.shortName ?? step.stepName, // [!code highlight]
// Module info available for debugging // [!code highlight]
module: parsed?.moduleSpecifier, // [!code highlight]
status: step.status,
startedAt: step.startedAt,
completedAt: step.completedAt,
};
});

return Response.json({ progress, cursor: steps.cursor });
} catch (error) {
return Response.json(
{ error: "Failed to list steps" },
{ status: 500 }
);
}
}
```

### Get Step with Hydrated Input/Output

Retrieve a step with its serialized data and hydrate it for display. This example shows how to decrypt and deserialize step input/output:
import { hydrateResourceIO, observabilityRevivers } from "workflow/observability"; // [!code highlight]

```typescript lineNumbers
import { getWorld } from "workflow/runtime";
import { parseStepName } from "@workflow/utils/parse-name"; // [!code highlight]
import { // [!code highlight]
hydrateResourceIO, // [!code highlight]
observabilityRevivers, // [!code highlight]
} from "@workflow/core/serialization-format"; // [!code highlight]

export async function GET(req: Request) {
const url = new URL(req.url);
const runId = url.searchParams.get("runId");
const stepId = url.searchParams.get("stepId");

if (!runId || !stepId) {
return Response.json({ error: "runId and stepId required" }, { status: 400 });
}

try {
const world = getWorld(); // [!code highlight]
// Fetch step with data (default resolveData behavior) // [!code highlight]
const step = await world.steps.get(runId, stepId); // [!code highlight]

// Hydrate serialized input/output for display // [!code highlight]
const hydrated = hydrateResourceIO(step, observabilityRevivers); // [!code highlight]

// Parse the stepName for user-friendly display
const parsed = parseStepName(step.stepName);

return Response.json({
stepId: hydrated.stepId,
displayName: parsed?.shortName ?? step.stepName, // [!code highlight]
module: parsed?.moduleSpecifier, // [!code highlight]
status: hydrated.status,
attempt: hydrated.attempt,
// Hydrated input/output ready for rendering // [!code highlight]
input: hydrated.input, // [!code highlight]
output: hydrated.output, // [!code highlight]
});
} catch (error) {
return Response.json(
{ error: "Step not found" },
{ status: 404 }
);
}
}
const step = await world.steps.get(runId, stepId);
const hydrated = hydrateResourceIO(step, observabilityRevivers); // [!code highlight]
```

<Callout type="info">
The `stepName` field contains a machine-readable identifier like `step//./src/workflows/order//processPayment`.
Use `parseStepName()` from `@workflow/utils/parse-name` to extract the `shortName` (e.g., `"processPayment"`)
and `moduleSpecifier` for display in your UI.
</Callout>
See [Observability Utilities](/docs/api-reference/workflow-api/world/observability) for the full hydration, parsing, and encryption API.

## Related Functions

Expand Down
3 changes: 3 additions & 0 deletions docs/content/docs/api-reference/workflow-api/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ The API package is for access and introspection of workflow data to inspect runs
<Card href="/docs/api-reference/workflow-api/get-world" title="getWorld()">
Get direct access to workflow storage, queuing, and streaming backends.
</Card>
<Card href="/docs/api-reference/workflow-api/world" title="World SDK">
Low-level API for inspecting runs, steps, events, hooks, streams, and queues.
</Card>
</Cards>
Loading
Loading