Pass class as this context to custom serializer/deserializer methods#947
Pass class as this context to custom serializer/deserializer methods#947TooTallNate merged 4 commits intomainfrom
this context to custom serializer/deserializer methods#947Conversation
…hods When calling WORKFLOW_SERIALIZE and WORKFLOW_DESERIALIZE static methods, use .call(ctor, value) and .call(cls, data) respectively to ensure the class is passed as 'this' context. This is necessary for serializers that access static properties or methods via 'this'. Adds test case to verify this behavior.
🦋 Changeset detectedLatest commit: bc1dca2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 15 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests🌍 Community Worlds (169 failed)mongodb (42 failed):
redis (42 failed):
starter (43 failed):
turso (42 failed):
Details by Category✅ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
❌ 🌍 Community Worlds
✅ 📋 Other
|
📊 Benchmark Results
workflow with no steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express workflow with 1 step💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) workflow with 10 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) workflow with 25 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) workflow with 50 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.all with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro Promise.all with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.all with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) Promise.race with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro Promise.race with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.race with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Nitro | Next.js (Turbopack) Stream Benchmarks (includes TTFB metrics)workflow with stream💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Express | Nitro SummaryFastest Framework by WorldWinner determined by most benchmark wins
Fastest World by FrameworkWinner determined by most benchmark wins
Column Definitions
Worlds:
|
There was a problem hiding this comment.
Pull request overview
This pull request fixes a limitation in the custom class serialization system by ensuring that the class constructor is passed as the this context when calling static WORKFLOW_SERIALIZE and WORKFLOW_DESERIALIZE methods. This enables serializers/deserializers to access static properties or methods via this.
Changes:
- Modified
serializecall to use.call(ctor, value)to pass the constructor asthiscontext - Modified
deserializecall to use.call(cls, data)to pass the class asthiscontext - Added comprehensive test case to verify the
thiscontext is correctly passed
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/core/src/serialization.ts | Updated serialization and deserialization logic to pass class as this context using .call() |
| packages/core/src/serialization.test.ts | Added test case verifying that static methods receive correct this context during serialization/deserialization |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
this context to custom serializer/deserializer methods
- Fix test to actually use `this` instead of `Counter` directly, which properly validates the fix - Standardize variable naming: rename `ctor` to `cls` in the Instance reducer for consistency with the reviver
|
Addressed review feedback in commit 3282f26:
|
The test now properly uses `this.serializedCount` and `this.deserializedCount` to validate the fix. Added biome-ignore comments to prevent the linter from auto-fixing `this` back to the class name.

Summary
thiscontext.call(ctor, value)for serialization and.call(cls, data)for deserializationthiscontext is correctly passed to custom serializers/deserializersProblem
When calling static serializer/deserializer methods, the previous implementation called them directly without setting the
thiscontext. This caused issues when the serializer/deserializer methods needed to access static properties or methods viathis.Solution
Changed:
serialize(value)→serialize.call(ctor, value)deserialize(data)→deserialize.call(cls, data)Test Plan
Added unit test that verifies:
thisis correctly bound to the class in WORKFLOW_SERIALIZEthisis correctly bound to the class in WORKFLOW_DESERIALIZEthisin both methods