* Remove isWorkflowSdkFile serde exclusion
The SWC detect mode's AST-level manifest (hasManifestEntries) already
correctly filters files without serde class definitions. The broad
isWorkflowSdkFile path exclusion is redundant and was preventing
class definitions in SDK packages from being discovered.
Removed from: builders, next, rollup
* Address review feedback: major semver bump, fix doc comment, add tests
- Bump changeset to major (removing exported APIs is breaking)
- Fix misleading doc comment referencing 'detect mode' in shouldTransformFile
- Add unit tests for shouldTransformFile covering all code paths
* Add AST-level serde filtering to Next.js deferred builder
The isWorkflowSdkFile path-based exclusion was removed from all paths,
but the Next.js deferred builder (collectTransitiveSerdeFiles) was still
using regexp-only detection, causing SDK internal files to be bundled
into the workflow sandbox and triggering stack overflows.
Fix: add applySwcTransform('detect', ...) verification at the end of
collectTransitiveSerdeFiles(). Regex-matched serde candidates are now
verified via the SWC plugin's AST-level manifest to confirm they
actually define serde classes before inclusion in the bundle.
Added automatic discovery for custom classes with workflow serialization, allowing serialization classes to be defined in separate files without requiring explicit directives.
### What changed?
- Added detection for files containing custom class serialization patterns:
- Files importing from `@workflow/serde`
- Files using `Symbol.for('workflow-serialize')` or `Symbol.for('workflow-deserialize')`
- Created shared utilities in `transform-utils.ts` for consistent pattern detection across all build tools
- Updated Next.js, Nitro, Rollup, and Vite plugins to use the new detection patterns
- Added exclusion logic to prevent re-processing of generated workflow files
- Added tests to verify the pattern detection works correctly
- Updated documentation in the SWC plugin spec to explain the new discovery mechanism
### How to test?
1. Create a class with custom serialization in a separate file:
```js
// models/point.js
export class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static [Symbol.for('workflow-serialize')](instance) {
return { x: instance.x, y: instance.y };
}
static [Symbol.for('workflow-deserialize')](data) {
return new Point(data.x, data.y);
}
}
```
1. Import and use this class in a workflow or step file:
```js
'use workflow';
import { Point } from '../models/point';
export function myWorkflow() {
const point = new Point(10, 20);
return point;
}
```
1. Verify the class is properly serialized when passed between client and server
### Why make this change?
Previously, files containing custom serialization classes needed to include a `'use step'` directive to be discovered and transformed, even if they weren't actual step functions. This was unintuitive and could lead to confusion.
This change allows for a more natural code organization pattern where model classes with serialization can be defined in their own files without requiring directives. The build system will automatically discover and transform these files to ensure the serialization works correctly when the classes are used in workflows or steps.