From 479f817abfc9dbc541d9b8344cacb72f9bb245d3 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Mon, 16 Mar 2026 16:50:49 -0700 Subject: [PATCH 1/2] refactor: use `this` value serialization for builtin step functions Refactor builtin step functions (__builtin_response_json, _text, _array_buffer) to use `this` instead of an explicit parameter, leveraging the useStep() proxy's this value serialization support. - Assign useStep() proxies directly onto Request.prototype and Response.prototype instead of wrapping them in class methods - Update builtin function signatures to use `this: Request | Response` - Remove unused duplicate builtins file from @workflow/core (the canonical copy lives in workflow/src/internal/builtins.ts) --- .changeset/hungry-spoons-attack.md | 6 +++ packages/core/package.json | 4 -- packages/core/src/builtins.ts | 14 ------- packages/core/src/workflow.ts | 45 +++++++++------------- packages/workflow/src/internal/builtins.ts | 14 ++++--- 5 files changed, 32 insertions(+), 51 deletions(-) create mode 100644 .changeset/hungry-spoons-attack.md delete mode 100644 packages/core/src/builtins.ts diff --git a/.changeset/hungry-spoons-attack.md b/.changeset/hungry-spoons-attack.md new file mode 100644 index 0000000000..3a0b1b8304 --- /dev/null +++ b/.changeset/hungry-spoons-attack.md @@ -0,0 +1,6 @@ +--- +"@workflow/core": patch +"workflow": patch +--- + +Refactor builtin step functions to use `this` value serialization instead of explicit parameter passing. Remove unused duplicate builtins file from `@workflow/core`. diff --git a/packages/core/package.json b/packages/core/package.json index a698622340..2145ab08b8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -52,10 +52,6 @@ "types": "./dist/class-serialization.d.ts", "default": "./dist/class-serialization.js" }, - "./builtins": { - "types": "./dist/builtins.d.ts", - "default": "./dist/builtins.js" - }, "./serialization": { "types": "./dist/serialization.d.ts", "default": "./dist/serialization.js" diff --git a/packages/core/src/builtins.ts b/packages/core/src/builtins.ts deleted file mode 100644 index 56a30a1ad2..0000000000 --- a/packages/core/src/builtins.ts +++ /dev/null @@ -1,14 +0,0 @@ -export async function __builtin_response_array_buffer(res: Response) { - 'use step'; - return res.arrayBuffer(); -} - -export async function __builtin_response_json(res: Response) { - 'use step'; - return res.json(); -} - -export async function __builtin_response_text(res: Response) { - 'use step'; - return res.text(); -} diff --git a/packages/core/src/workflow.ts b/packages/core/src/workflow.ts index b84bb6e85a..f5b3694a46 100644 --- a/packages/core/src/workflow.ts +++ b/packages/core/src/workflow.ts @@ -454,29 +454,22 @@ export async function runWorkflow( blob!: () => Promise; formData!: () => Promise; - async arrayBuffer() { - return resArrayBuffer(this); - } + arrayBuffer!: () => Promise; + json!: () => Promise; + text!: () => Promise; async bytes() { - return new Uint8Array(await resArrayBuffer(this)); - } - - async json() { - return resJson(this); - } - - async text() { - return resText(this); + return new Uint8Array(await this.arrayBuffer()); } } vmGlobalThis.Request = Request; - const resJson = useStep<[any], any>('__builtin_response_json'); - const resText = useStep<[any], string>('__builtin_response_text'); - const resArrayBuffer = useStep<[any], ArrayBuffer>( + Request.prototype.arrayBuffer = useStep<[], ArrayBuffer>( '__builtin_response_array_buffer' ); + Request.prototype.json = useStep<[], any>('__builtin_response_json'); + Request.prototype.text = useStep<[], string>('__builtin_response_text'); + class Response implements globalThis.Response { type!: globalThis.Response['type']; url!: string; @@ -534,16 +527,12 @@ export async function runWorkflow( return false; } - async arrayBuffer() { - return resArrayBuffer(this); - } + arrayBuffer!: () => Promise; + json!: () => Promise; + text!: () => Promise; async bytes() { - return new Uint8Array(await resArrayBuffer(this)); - } - - async json() { - return resJson(this); + return new Uint8Array(await this.arrayBuffer()); } static json(data: any, init?: ResponseInit): Response { @@ -555,10 +544,6 @@ export async function runWorkflow( return new Response(body, { ...init, headers }); } - async text() { - return resText(this); - } - static error(): Response { ENOTSUP(); } @@ -589,6 +574,12 @@ export async function runWorkflow( } vmGlobalThis.Response = Response; + Response.prototype.arrayBuffer = useStep<[], ArrayBuffer>( + '__builtin_response_array_buffer' + ); + Response.prototype.json = useStep<[], any>('__builtin_response_json'); + Response.prototype.text = useStep<[], string>('__builtin_response_text'); + class ReadableStream implements globalThis.ReadableStream { constructor() { ENOTSUP(); diff --git a/packages/workflow/src/internal/builtins.ts b/packages/workflow/src/internal/builtins.ts index 5510c1fad0..886686e50e 100644 --- a/packages/workflow/src/internal/builtins.ts +++ b/packages/workflow/src/internal/builtins.ts @@ -4,17 +4,19 @@ * alongside user defined steps. They are used internally by the runtime */ -export async function __builtin_response_array_buffer(res: Response) { +export async function __builtin_response_array_buffer( + this: Request | Response +) { 'use step'; - return res.arrayBuffer(); + return this.arrayBuffer(); } -export async function __builtin_response_json(res: Response) { +export async function __builtin_response_json(this: Request | Response) { 'use step'; - return res.json(); + return this.json(); } -export async function __builtin_response_text(res: Response) { +export async function __builtin_response_text(this: Request | Response) { 'use step'; - return res.text(); + return this.text(); } From 5ac88afb21c01dc4a3fd5f505a2ed9716c795cd3 Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Mon, 16 Mar 2026 17:13:57 -0700 Subject: [PATCH 2/2] use Object.defineProperties for non-enumerable prototype methods --- packages/core/src/workflow.ts | 44 +++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/packages/core/src/workflow.ts b/packages/core/src/workflow.ts index f5b3694a46..5d18c085b4 100644 --- a/packages/core/src/workflow.ts +++ b/packages/core/src/workflow.ts @@ -464,11 +464,23 @@ export async function runWorkflow( } vmGlobalThis.Request = Request; - Request.prototype.arrayBuffer = useStep<[], ArrayBuffer>( - '__builtin_response_array_buffer' - ); - Request.prototype.json = useStep<[], any>('__builtin_response_json'); - Request.prototype.text = useStep<[], string>('__builtin_response_text'); + Object.defineProperties(Request.prototype, { + arrayBuffer: { + value: useStep<[], ArrayBuffer>('__builtin_response_array_buffer'), + writable: true, + configurable: true, + }, + json: { + value: useStep<[], any>('__builtin_response_json'), + writable: true, + configurable: true, + }, + text: { + value: useStep<[], string>('__builtin_response_text'), + writable: true, + configurable: true, + }, + }); class Response implements globalThis.Response { type!: globalThis.Response['type']; @@ -574,11 +586,23 @@ export async function runWorkflow( } vmGlobalThis.Response = Response; - Response.prototype.arrayBuffer = useStep<[], ArrayBuffer>( - '__builtin_response_array_buffer' - ); - Response.prototype.json = useStep<[], any>('__builtin_response_json'); - Response.prototype.text = useStep<[], string>('__builtin_response_text'); + Object.defineProperties(Response.prototype, { + arrayBuffer: { + value: useStep<[], ArrayBuffer>('__builtin_response_array_buffer'), + writable: true, + configurable: true, + }, + json: { + value: useStep<[], any>('__builtin_response_json'), + writable: true, + configurable: true, + }, + text: { + value: useStep<[], string>('__builtin_response_text'), + writable: true, + configurable: true, + }, + }); class ReadableStream implements globalThis.ReadableStream { constructor() {