Files
Nathan Rajlich 1843704b83 Add support for custom class instance serialization (#762)
Added support for custom class instance serialization across workflow/step boundaries.

### What changed?

- Introduced a new `@workflow/serde` package with `WORKFLOW_SERIALIZE` and `WORKFLOW_DESERIALIZE` symbols
- Enhanced the serialization system to handle custom class instances using these symbols
- Updated the SWC plugin to detect classes with serialization methods and register them
- Added class registry mechanism that works in both step and workflow contexts
- Implemented comprehensive tests for various serialization scenarios

### How to test?

The PR includes a new e2e test `customSerializationWorkflow` that demonstrates the feature:

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

// Define a class with custom serialization
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);
  }
}

// Use in workflow and steps
export async function customSerializationWorkflow(x: number, y: number) {
  'use workflow';
  const point = new Point(x, y);
  const scaled = await transformPoint(point, 2);
  // ...
}
```

Run the e2e test to verify that class instances are properly serialized and deserialized.

### Why make this change?

Previously, user-defined class instances couldn't be passed between workflows and steps without losing their prototype chain and methods. This change allows developers to define custom serialization/deserialization logic for their classes, enabling proper reconstruction of instances with their full functionality intact when crossing workflow/step boundaries.
2026-01-19 15:38:19 -08:00
..