Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
58821c5
74421 configure build pipeline (#74426)
adamsilverstein Jan 8, 2026
d13031b
74422 implement blob loader (#74468)
adamsilverstein Jan 9, 2026
fedaa28
74423 custom vips init (#74476)
adamsilverstein Jan 9, 2026
1cb4814
Try: revert scripts package changes
adamsilverstein Jan 13, 2026
8301259
Try: remove babel config change
adamsilverstein Jan 13, 2026
c565608
Add @wordpress/worker-threads package
adamsilverstein Jan 14, 2026
8513192
Add worker bundling support to @wordpress/build
adamsilverstein Jan 14, 2026
2c78a69
Migrate @wordpress/vips to use @wordpress/worker-threads
adamsilverstein Jan 14, 2026
abdca2e
Add unit tests for @wordpress/worker-threads
adamsilverstein Jan 14, 2026
0308d35
Remove obsolete vips-worker test file
adamsilverstein Jan 14, 2026
117b4c2
Fine tuning
adamsilverstein Jan 14, 2026
edd8e47
prettier
adamsilverstein Jan 14, 2026
4651fc1
remove pr description
adamsilverstein Jan 15, 2026
35334ec
Update packages/vips/src/vips-worker.ts
adamsilverstein Jan 15, 2026
3c7291e
Remove unnecessary async keywords from WASM inlining test callbacks (…
Copilot Jan 15, 2026
f322c1a
Optimize transferables duplicate detection with Set for O(1) lookups …
Copilot Jan 15, 2026
658a5ea
prettier
adamsilverstein Jan 15, 2026
a204117
remove shopify traces
adamsilverstein Jan 15, 2026
a9ca712
build vips-worker
adamsilverstein Jan 15, 2026
60b08d6
Fix build for tests
adamsilverstein Jan 15, 2026
2170cee
prettier
adamsilverstein Jan 15, 2026
741c291
Fix TypeScript build by generating worker-code.ts placeholder before …
adamsilverstein Jan 15, 2026
9ff1398
lint fix
adamsilverstein Jan 15, 2026
2fca3d8
Update packages/wp-build/lib/build.mjs
adamsilverstein Jan 15, 2026
8a7281e
remove heif support
adamsilverstein Jan 16, 2026
1c6e593
Simplify isRPCMessage to minimal type check
adamsilverstein Jan 16, 2026
f76d50f
Simplify findTransferables to only check direct args/result
adamsilverstein Jan 16, 2026
bdbef08
Remove vips-heif.wasm inlining test
adamsilverstein Jan 16, 2026
8d2dc4f
Simplify worker-threads library with worker-rpc
adamsilverstein Jan 16, 2026
53a2f08
Replace worker-rpc with comctx in worker-threads package
adamsilverstein Jan 16, 2026
a73e21a
Fix TypeScript error in worker-thread postMessage call
adamsilverstein Jan 16, 2026
879b1b5
update package lock
adamsilverstein Jan 20, 2026
c759d26
add re-transpilation step
adamsilverstein Jan 27, 2026
17ff565
Break out placeholder generation
adamsilverstein Jan 28, 2026
d985c3b
remove stray diff
adamsilverstein Jan 28, 2026
f31636f
Extract worker build code from build.mjs into separate worker-build.m…
adamsilverstein Jan 28, 2026
c5d847a
Remove inadvertantly committed build files and add to gitignore
adamsilverstein Jan 29, 2026
e58dca6
linter fixes
adamsilverstein Jan 29, 2026
d1b015b
Fix prettier formatting in build.mjs
adamsilverstein Jan 29, 2026
f40162d
Update changelogs for vips, wp-build packages and add changelog for n…
adamsilverstein Jan 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ build-style
build-types
build-wp
node_modules
.wasm-vips-build
gutenberg.zip
.content-entry.js
coverage
Expand Down
7 changes: 7 additions & 0 deletions bin/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ async function build() {
{ silent: true }
);

// Step 2.5: Generate worker placeholders
// This must happen before TypeScript compilation because some packages
// (like vips) have source files that import from generated worker-code.ts
await exec( 'node', [
'./bin/packages/generate-worker-placeholders.mjs',
] );
Comment on lines +100 to +105

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could be wrong, but I think this may need to happen in dev.mjs too. I’m here because after a fresh pull from trunk, the dev script failed due to the missing file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, let me review - I assume you mean running npm run dev?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to reproduce in trunk, maybe something in my local. Going to try a fresh repo checkout.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m here because after a fresh pull from trunk, the dev script failed due to the missing file.

@stokesman thanks for reporting this... does this go away if you run npm run build first?

I was able to reproduce on a fresh checkout, opening a PR to fix!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stokesman I created a follow up PR to fix this - #75104


if ( ! skipTypes ) {
// Step 3: Validate TypeScript version
console.log( '\n🔍 Validating TypeScript version...' );
Expand Down
96 changes: 96 additions & 0 deletions bin/packages/generate-worker-placeholders.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env node

/**
* External dependencies
*/
import { readFile, writeFile, access, mkdir } from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
import glob from 'fast-glob';

const __dirname = path.dirname( fileURLToPath( import.meta.url ) );
const ROOT_DIR = path.resolve( __dirname, '../..' );
const PACKAGES_DIR = path.join( ROOT_DIR, 'packages' );

/**
* Generate placeholder files for worker code in packages that define wpWorkers.
* This must run before TypeScript compilation because some packages
* (like vips) have source files that import from generated worker-code.ts.
*/
async function generateWorkerPlaceholders() {
console.log( '🔧 Generating worker placeholders...\n' );

const startTime = Date.now();

const packageJsonPaths = await glob(
path.join( PACKAGES_DIR, '*', 'package.json' ).replace( /\\/g, '/' )
);

let placeholdersCreated = 0;

for ( const packageJsonPath of packageJsonPaths ) {
try {
const packageJsonContent = await readFile(
packageJsonPath,
'utf8'
);
const packageJson = JSON.parse( packageJsonContent );

if ( packageJson.wpWorkers ) {
const packageDir = path.dirname( packageJsonPath );
const workerCodeFile = path.join(
packageDir,
'src',
'worker-code.ts'
);

try {
await access( workerCodeFile );
// File exists, no need to create placeholder.
} catch {
// File doesn't exist, create placeholder.
const placeholderContent = `/**
* Worker code for inline Blob URL creation.
*
* This file is a placeholder that gets overwritten by the build process.
* If you see this placeholder content at runtime, run \`npm run build\` first.
*
* @package gutenberg
*/

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const workerCode = '/* Placeholder - run npm run build to generate actual worker code */';
`;
await mkdir( path.dirname( workerCodeFile ), {
recursive: true,
} );
await writeFile( workerCodeFile, placeholderContent );
placeholdersCreated++;
console.log(
` ✔ Created placeholder: ${ path.relative(
ROOT_DIR,
workerCodeFile
) }`
);
}
}
} catch {
// Skip packages with invalid package.json.
}
}

const totalTime = Date.now() - startTime;

if ( placeholdersCreated === 0 ) {
console.log( ' ✔ All worker placeholders already exist' );
}

console.log(
`\n🎉 Worker placeholder generation complete! (${ totalTime }ms)`
);
}

generateWorkerPlaceholders().catch( ( error ) => {
console.error( '❌ Worker placeholder generation failed:', error );
process.exit( 1 );
} );
23 changes: 23 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions packages/vips/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Auto-generated worker code for inline Blob URL creation.
# The build process generates a placeholder if needed, then overwrites it with real content.
src/worker-code.ts
4 changes: 3 additions & 1 deletion packages/vips/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@

### New Features

- Initial public release.
- Initial release of `@wordpress/vips` package for client-side image processing using `wasm-vips` ([#74785](https://github.com/WordPress/gutenberg/pull/74785)).
- Uses `@wordpress/worker-threads` for type-safe Web Worker communication.
- ESM-only package with inlined WASM bundling.
10 changes: 0 additions & 10 deletions packages/vips/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,4 @@ _Returns_

- `Promise< { buffer: ArrayBuffer | ArrayBufferLike; width: number; height: number; originalWidth: number; originalHeight: number; } >`: Processed file data plus the old and new dimensions.

### setLocation

Dynamically sets the location / public path to use for loading the WASM files.

This is required when loading this module in an inline worker, where globals such as **webpack_public_path** are not available.

_Parameters_

- _newLocation_ `string`: Location, typically a base URL such as "<https://example.com/path/to/js/...">.

<!-- END TOKEN(Autogenerated API docs) -->
14 changes: 10 additions & 4 deletions packages/vips/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,29 @@
},
"files": [
"src",
"build",
"build-module",
"build-types",
"*.md"
],
"main": "build/index.cjs",
"type": "module",
"module": "build-module/index.mjs",
"exports": {
".": {
"types": "./build-types/index.d.ts",
"import": "./build-module/index.mjs",
"default": "./build/index.cjs"
"import": "./build-module/index.mjs"
},
"./worker": {
"types": "./build-types/vips-worker.d.ts",
"import": "./build-module/vips-worker.mjs"
},
"./package.json": "./package.json"
},
"types": "build-types",
"wpWorkers": {
"./worker": "./src/worker.ts"
},
"dependencies": {
"@wordpress/worker-threads": "file:../worker-threads",
"wasm-vips": "^0.0.10"
},
"publishConfig": {
Expand Down
32 changes: 8 additions & 24 deletions packages/vips/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
*/
import Vips from 'wasm-vips';

// @ts-expect-error
// @ts-expect-error - WASM files are inlined as base64 data URLs at build time
import VipsModule from 'wasm-vips/vips.wasm';

// @ts-expect-error
import VipsHeifModule from 'wasm-vips/vips-heif.wasm';

// @ts-expect-error
// @ts-expect-error - WASM files are inlined as base64 data URLs at build time
import VipsJxlModule from 'wasm-vips/vips-jxl.wasm';

/**
Expand All @@ -29,20 +26,6 @@ interface EmscriptenModule {
setDelayFunction: ( fn: ( fn: () => void ) => void ) => void;
}

let location = '';

/**
* Dynamically sets the location / public path to use for loading the WASM files.
*
* This is required when loading this module in an inline worker,
* where globals such as __webpack_public_path__ are not available.
*
* @param newLocation Location, typically a base URL such as "https://example.com/path/to/js/...".
*/
export function setLocation( newLocation: string ) {
location = newLocation;
}

let cleanup: () => void;

let vipsInstance: typeof Vips;
Expand All @@ -59,15 +42,16 @@ async function getVips(): Promise< typeof Vips > {

vipsInstance = await Vips( {
locateFile: ( fileName: string ) => {
// WASM files are inlined as base64 data URLs at build time,
// eliminating the need for separate file downloads and avoiding
// issues with hosts not serving WASM files with correct MIME types.
if ( fileName.endsWith( 'vips.wasm' ) ) {
fileName = VipsModule;
} else if ( fileName.endsWith( 'vips-heif.wasm' ) ) {
fileName = VipsHeifModule;
return VipsModule;
} else if ( fileName.endsWith( 'vips-jxl.wasm' ) ) {
fileName = VipsJxlModule;
return VipsJxlModule;
}

return location + fileName;
return fileName;
},
preRun: ( module: EmscriptenModule ) => {
// https://github.com/kleisauke/wasm-vips/issues/13#issuecomment-1073246828
Expand Down
Loading
Loading