quickjs-emscripten
quickjs-emscripten copied to clipboard
Cloudflare + QJS + async module loader.
Hello, I am struggling making async module loader when using QJS on CF. I need setModuleLoader to be async, but this requires ASYNCified WASM build as far as I understood. When trying this, I am getting TS error (also it doesn't work after ts-ignore):
import type { QuickJSAsyncWASMModule, QuickJSWASMModule } from 'quickjs-emscripten'
import { newQuickJSWASMModule, RELEASE_ASYNC as baseVariant, newVariant, newQuickJSAsyncWASMModule } from 'quickjs-emscripten'
import cloudflareWasmModule from './wasm/RELEASE_ASYNCIFY.wasm'
export function initQuickJS(): Promise<QuickJSAsyncWASMModule> {
// TS error
const cloudflareVariant = newVariant<QuickJSAsyncVariant>(baseVariant, {
wasmModule: cloudflareWasmModule,
})
return newQuickJSAsyncWASMModule(cloudflareVariant)
}
export const QuickJSWasmModule = initQuickJS()
error:
Argument of type 'import("/Users/project/node_modules/.pnpm/@[email protected]/node_modules/@jitl/quickjs-ffi-types/dist/index").QuickJSAsyncVariant' is not assignable to parameter of type 'import("/Users/project/node_modules/@jitl/quickjs-ffi-types/dist/index").QuickJSAsyncVariant'.
The types returned by 'importFFI()' are incompatible between these types.
Type 'Promise<new (module: import("/Users/project/node_modules/.pnpm/@[email protected]/node_modules/@jitl/quickjs-ffi-types/dist/index").QuickJSAsyncEmscriptenModule) => import("/Users/project/node_modules/.pnpm/@[email protected]/node_modules/@jitl/quickjs-ffi-ty...' is not assignable to type 'Promise<new (module: import("/Users/project/node_modules/@jitl/quickjs-ffi-types/dist/index").QuickJSAsyncEmscriptenModule) => import("/Users/project/node_modules/@jitl/quickjs-ffi-types/dist/index").QuickJSAsyncFFI>'.
Type 'new (module: import("/Users/project/node_modules/.pnpm/@[email protected]/node_modules/@jitl/quickjs-ffi-types/dist/index").QuickJSAsyncEmscriptenModule) => import("/Users/project/node_modules/.pnpm/@[email protected]/node_modules/@jitl/quickjs-ffi-types/dist...' is not assignable to type 'new (module: import("/Users/project/node_modules/@jitl/quickjs-ffi-types/dist/index").QuickJSAsyncEmscriptenModule) => import("/Users/project/node_modules/@jitl/quickjs-ffi-types/dist/index").QuickJSAsyncFFI'.
....
Code above was working fine when it used SYNC versions of builds:
import type { QuickJSWASMModule } from 'quickjs-emscripten'
import { newQuickJSWASMModule, RELEASE_SYNC as baseVariant, newVariant } from 'quickjs-emscripten'
import cloudflareWasmModule from './wasm/RELEASE_SYNC.wasm'
export function initQuickJS(): Promise<QuickJSWASMModule> {
const cloudflareVariant = newVariant(baseVariant, {
wasmModule: cloudflareWasmModule,
})
return newQuickJSWASMModule(cloudflareVariant)
}
export const QuickJSWasmModule = initQuickJS()
Is it possible to run such thing on CF or not?
Thanks a lot for such a great project anyway!
The type error is confusing because it seems like there are two copies of @jitl/quickjs-ffi-types at different locations inside node_modules:
'import("/Users/project/node_modules/.pnpm/@[email protected]/node_modules/@jitl/quickjs-ffi-types/dist/index").QuickJSAsyncVariant'
'import("/Users/project/node_modules/ @jitl/quickjs-ffi-types/dist/index").QuickJSAsyncVariant'
Is it possible there are two incompatible versions of the quickjs-emscripten packages installed and being mixed together? I'm not sure how pnpm works but I get the sense that it is "cutting edge" and can introduce some breakages in the packages it installs.
I am more interested in a runtime error, you say:
also it doesn't work after ts-ignore
I would like to know what you mean by "it doesn't work".
Thanks for quick response!
Hm, seems like you are right. I just tried to restart VSCode and suddenly types are okay. Not sure what was that, maybe pnpm stuff or VSCode. Anyway, when trying to run this on CloudFlare, I see this (that's what I meant by "it doesnt work"):
I tried to google this, but honestly not much was found. Maybe you have any ideas?
Update: you were right. I had different version of quickjs-emscripten and wasm builds. After fixiting this, it doesn't stuck anymore! 🎉
Nevertheless, it looks like I am facing new problem (I can create another issue if you want). I tried to use it with { type: "module" } and now it returns {}. So, in short, this snippet returns 2:
const ctx = runtime.newContext()
const result = await ctx.evalCodeAsync('1 + 1')
console.log(ctx.dump(ctx.unwrapResult(result)))
and this returns just {}
const ctx = runtime.newContext()
const result = await ctx.evalCodeAsync('1 + 1', undefined, { type: "module" })
console.log(ctx.dump(ctx.unwrapResult(result)))
I have read constructor name of what it returns from sandbox and it is Module. Can you help me with reading the value I need? Thanks!
Module evaluation always returns a module or a promise of a module. You will need to set a global variable you can read later, call an injected callback function, or export the result from the module to retrieve the value