Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloudflare + QJS + async module loader. #188

Open
qbz opened this issue Jul 11, 2024 · 3 comments
Open

Cloudflare + QJS + async module loader. #188

qbz opened this issue Jul 11, 2024 · 3 comments

Comments

@qbz
Copy link

qbz commented Jul 11, 2024

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!

@justjake
Copy link
Owner

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".

@qbz
Copy link
Author

qbz commented Jul 21, 2024

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"):

Screenshot 2024-07-21 at 7 00 56

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!

@justjake
Copy link
Owner

justjake commented Aug 14, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants