Skip to content
Merged
2 changes: 2 additions & 0 deletions .changeset/smooth-nails-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
3 changes: 3 additions & 0 deletions docs/content/docs/api-reference/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ All the functions and primitives that come with Workflow DevKit by package.
<Card title="workflow/next" href="/docs/api-reference/workflow-next">
Next.js integration for Workflow DevKit that automatically configures bundling and runtime support.
</Card>
<Card title="@workflow/serde" href="/docs/api-reference/workflow-serde">
Serialization symbols for custom class serialization in workflows.
</Card>
<Card title="@workflow/ai" href="/docs/api-reference/workflow-ai">
Helpers for integrating AI SDK for building AI-powered workflows.
</Card>
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/api-reference/meta.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"title": "API Reference",
"pages": ["...", "workflow-ai", "vitest"]
"pages": ["...", "workflow-serde", "workflow-ai", "vitest"]
}
52 changes: 52 additions & 0 deletions docs/content/docs/api-reference/workflow-serde/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: "@workflow/serde"
---

Serialization symbols for custom class serialization in Workflow DevKit.

## Installation

```package-install
npm i @workflow/serde
```

## Overview

By default, Workflow DevKit can serialize standard JavaScript types like primitives, objects, arrays, `Date`, `Map`, `Set`, and more. However, custom class instances are not serializable by default because the serialization system doesn't know how to reconstruct them.

The `@workflow/serde` package provides two symbols that allow you to define custom serialization and deserialization logic for your classes, enabling them to be passed between workflow and step functions.

## Symbols

<Cards>
<Card href="/docs/api-reference/workflow-serde/workflow-serialize" title="WORKFLOW_SERIALIZE">
Symbol for defining how to serialize a class instance to plain data.
</Card>
<Card href="/docs/api-reference/workflow-serde/workflow-deserialize" title="WORKFLOW_DESERIALIZE">
Symbol for defining how to reconstruct a class instance from plain data.
</Card>
</Cards>

## Quick Example

{/* @expect-error:2351 */}

```typescript lineNumbers
import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from "@workflow/serde";

class Point {
constructor(public x: number, public y: number) {}

static [WORKFLOW_SERIALIZE](instance: Point) {
return { x: instance.x, y: instance.y };
}

static [WORKFLOW_DESERIALIZE](data: { x: number; y: number }) {
return new Point(data.x, data.y);
}
}
```

<Callout>
For a complete guide on custom class serialization, see the [Serialization documentation](/docs/foundations/serialization#custom-class-serialization).
</Callout>
3 changes: 3 additions & 0 deletions docs/content/docs/api-reference/workflow-serde/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"pages": ["...", "workflow-serialize", "workflow-deserialize"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
title: WORKFLOW_DESERIALIZE
---

A symbol used to define custom deserialization for user-defined class instances. The static method should accept serialized data and return a new class instance.

## Usage

{/* @expect-error:2351 */}

```typescript lineNumbers
import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from "@workflow/serde";

class Point {
constructor(public x: number, public y: number) {}

static [WORKFLOW_SERIALIZE](instance: Point) {
return { x: instance.x, y: instance.y };
}

static [WORKFLOW_DESERIALIZE](data: { x: number; y: number }) {
return new Point(data.x, data.y);
}
}
```

## API Signature

{/* @skip-typecheck */}

```typescript
static [WORKFLOW_DESERIALIZE](data: SerializableData): T
```

### Parameters

<TSDoc
definition={`
interface Parameters {
/**
* The serialized data to reconstruct into a class instance.
* This is the same data that was returned by WORKFLOW_SERIALIZE.
*/
data: SerializableData;
}
export default Parameters;`}
/>

### Returns

The method should return a new instance of the class, reconstructed from the serialized data.

## Requirements

<Callout type="warn">
The method must be implemented as a **static** method on the class. Instance methods are not supported.
</Callout>

- Both `WORKFLOW_SERIALIZE` and `WORKFLOW_DESERIALIZE` must be implemented together
- The method receives the exact data that was returned by `WORKFLOW_SERIALIZE`
- If `WORKFLOW_SERIALIZE` returns complex types (like `Map` or `Date`), they will be properly deserialized before being passed to this method

<Callout type="warn">
This method runs inside the workflow context and is subject to the same constraints as `"use workflow"` functions:
- No Node.js-specific APIs (like `fs`, `path`, `crypto`, etc.)
- No non-deterministic operations (like `Math.random()` or `Date.now()`)
- No external network calls

Keep this method simple and focused on reconstructing the instance from the provided data.
</Callout>
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: WORKFLOW_SERIALIZE
---

A symbol used to define custom serialization for user-defined class instances. The static method should accept an instance and return serializable data.

## Usage

{/* @expect-error:2351 */}

```typescript lineNumbers
import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from "@workflow/serde";

class Point {
constructor(public x: number, public y: number) {}

static [WORKFLOW_SERIALIZE](instance: Point) {
return { x: instance.x, y: instance.y };
}

static [WORKFLOW_DESERIALIZE](data: { x: number; y: number }) {
return new Point(data.x, data.y);
}
}
```

## API Signature

{/* @skip-typecheck */}

```typescript
static [WORKFLOW_SERIALIZE](instance: T): SerializableData
```

### Parameters

<TSDoc
definition={`
interface Parameters {
/**
* The class instance to serialize.
*/
instance: T;
}
export default Parameters;`}
/>

### Returns

The method should return serializable data. This can be:

- Primitives (`string`, `number`, `boolean`, `null`, `undefined`, `bigint`)
- Plain objects with serializable values
- Arrays of serializable values
- Built-in serializable types (`Date`, `Map`, `Set`, `RegExp`, `URL`, etc.)
- Other custom classes that implement serialization

## Requirements

<Callout type="warn">
The method must be implemented as a **static** method on the class. Instance methods are not supported.
</Callout>

- Both `WORKFLOW_SERIALIZE` and `WORKFLOW_DESERIALIZE` must be implemented together
- The returned data must itself be serializable
- The SWC compiler plugin automatically detects and registers classes that implement these symbols

<Callout type="warn">
This method runs inside the workflow context and is subject to the same constraints as `"use workflow"` functions:
- No Node.js-specific APIs (like `fs`, `path`, `crypto`, etc.)
- No non-deterministic operations (like `Math.random()` or `Date.now()`)
- No external network calls

Keep this method simple and focused on extracting data from the instance.
</Callout>
Loading
Loading