Skip to content

Commit ce96566

Browse files
authored
[PHP WASM] Transfer ArrayBuffer instead of cloning in PHPResponse serialization (#3036)
Fix DataCloneError when handling large files by transferring the ArrayBuffer instead of cloning it. This is more efficient and works with detached buffers. ## Motivation for the change, related issues STU-73 ## Implementation details Modified the `PHPResponse` transfer handler's `serialize` method in `api.ts` to explicitly transfer the underlying `ArrayBuffer` instead of cloning it. Previously, the method returned an empty transferables array, causing Comlink to clone the response data. For large files (e.g., 4.8GB backups), this failed with `DataCloneError` when the ArrayBuffer had already been transferred/detached upstream. The fix adds `data.bytes.buffer` to the transferables array, enabling zero-copy transfer regardless of the buffer's prior state. This resolves the serialization error for large file downloads while also improving memory efficiency. ## Testing Instructions (or ideally a Blueprint) 1. Create a site locally for example using Studio 2. Using the terminal, run the playground cli mounting the Studio folder, for example using this command: ``` nx dev playground-cli server --mount-before-install=<path-to-studio-site>:/wordpress ``` Replacing `<path-to-studio-site>` with the root path of your Studio site, I use the absolute path for that. 4. Open the URL that playground-cli provides and navigate to WP admin, you can take the password from the Studio settings. 5. Install All In One WP Migration plugin. 6. Upload >2GB files to the site, you can use large media files for that. 7. Export site to file using the plugin. 8. Download the file 9. Verify that the file can be downloaded successfully.
1 parent 20ac970 commit ce96566

File tree

1 file changed

+8
-1
lines changed
  • packages/php-wasm/universal/src/lib

1 file changed

+8
-1
lines changed

packages/php-wasm/universal/src/lib/api.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,14 @@ function setupTransferHandlers() {
218218
'exitCode' in obj &&
219219
'httpStatusCode' in obj,
220220
serialize(obj: PHPResponse): [PHPResponseData, Transferable[]] {
221-
return [obj.toRawData(), []];
221+
const data = obj.toRawData();
222+
// Transfer the ArrayBuffer instead of cloning it to avoid
223+
// "could not be cloned" errors when the buffer is detached
224+
const transferables: Transferable[] = [];
225+
if (data.bytes.buffer.byteLength > 0) {
226+
transferables.push(data.bytes.buffer);
227+
}
228+
return [data, transferables];
222229
},
223230
deserialize(responseData: PHPResponseData): PHPResponse {
224231
return PHPResponse.fromRawData(responseData);

0 commit comments

Comments
 (0)