@@ -60,30 +60,15 @@ async function main() {
6060 const bytes = await loadBytes ( source ) ;
6161 const runtime = await RuntimeLoader . awaitInstance ( ) ;
6262
63- // Stub makeRenderImage so runtime.load() resolves even without WebGL.
64- // On headless Linux, origMRI() returns null (no GPU), and passing null back
65- // causes the WASM to call process.exit(0) silently. Return a Proxy stub that
66- // no-ops all method calls and immediately fires the "loaded" callback (la).
67- const origMRI = ( runtime . renderFactory as any ) . makeRenderImage ?. bind (
68- runtime . renderFactory
69- ) ;
70- if ( origMRI ) {
71- ( runtime . renderFactory as any ) . makeRenderImage = function ( ) {
72- const img = origMRI ( ) ;
73- if ( img ) {
74- queueMicrotask ( ( ) => img . la ?.( ) ) ;
75- return img ;
76- }
77- // No WebGL: proxy that no-ops all calls so the WASM doesn't crash
78- const stub : any = new Proxy ( Object . create ( null ) , {
79- get : ( _t , _p ) => ( ) => { } ,
80- } ) ;
81- queueMicrotask ( ( ) => stub . la ( ) ) ;
82- return stub ;
83- } ;
84- }
63+ // Use CustomFileAssetLoader to claim all embedded assets (images, fonts) as
64+ // handled so the runtime never calls makeRenderImage. Without this, .riv files
65+ // with embedded images cause the WASM to call process.exit(0) on headless Linux
66+ // where WebGL is unavailable. We only need the schema (artboards/VMs), not images.
67+ const assetLoader = new ( runtime as any ) . CustomFileAssetLoader ( {
68+ loadContents : ( ) => true ,
69+ } ) ;
8570
86- const riveFile = await runtime . load ( bytes , undefined , false ) ;
71+ const riveFile = await runtime . load ( bytes , assetLoader , false ) ;
8772
8873 const artboards : string [ ] = [ ] ;
8974 const stateMachines : Record < string , string [ ] > = { } ;
0 commit comments