-
Notifications
You must be signed in to change notification settings - Fork 24
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
Adds browser (WASM) support #34
Conversation
Ideally they shouldn't, but you need to emit Although it depends on the bundler and whether they support Either way, if possible, I'd really recommend to avoid |
This is great to know @RReverser - I'll look into updating this. |
This has now been updated as an ES Module via |
@RReverser by chance, have you ever gotten Emscripten outputs to work seamlessly with Next.js? So far it has been a bit challenging:
As of now my best solution for Next.js is the one above requiring developers to install |
Hm no I didn't do anything Next.js-specific, I'm afraid you'll need to play with it yourself.
If it's about the file extension, you can just change it to I forgot to mention one other thing, but it might help here too - instead of custom Makefile, you can integrate Wasm building into binding.gyp. See here how I did that in Sharp / feel free to borrow the common.gypi until we find a way to upstream it to emnapi (the blocker was that it won't work on Windows yet): https://github.com/lovell/sharp/pull/3522/files#diff-61fe5790e62b9d1af82b5332536fb4bdc899528b095c22f43f9f10068e91eeb7 |
@gregnr I saw that How much more work is needed on this PR? (and approximately how hard is each thing?) We at @upleveled would love to test SafeQL by @Newbie012 with our next cohort of bootcamp students (some of whom use Windows) in mid-February 2024, and I think that this PR would offer us a chance to do so! If there's an early version that @Eprince-hub or other people on our team can try out, we'd love to give it a shot, even before this PR is merged :) |
Elsewhere in the ecosystem, another WebAssembly implementation of |
@pyramation @karlhorky We've been using the WASM library at Supabase in a forked package for a while and would like to merge this PR. Are there any outstanding issues (beside the merge conflicts) that needs to be resolved? |
@karlhorky This PR is good to go now. The challenges above with Next.js are solvable using I've updated the base branch to I couldn't find any build/deploy CI automation in this repo so didn't set anything up there on the WASM side (manual wasm build + NPM deploy for now). Let me know if there's a better way to do this. |
Thank you for this amazing work :) oops, I deleted |
OK, I've published an rc version Once we verify on a few machines this is good, sounds like we can merge the wasm-feature branch into 15-latest and publish 15.0.4 or later
|
I tried to install this on a Windows machine today using
|
With the npm latest version
|
The package is not published onto Supabase S3 bucket for some reason. You need to run |
ok, so sounds like this works for linux, but not windows yet, and we need to get the binary publish |
Adds WASM support using the incredible emnapi project that implements Node's N-API for Emscripten. This means no new bindings needed to be built - we can reuse the existing Node-API bindings and simply target WASM.
Some implementation notes:
Build method
yarn build:wasm
which uses aMakefile
under the hood.emnapi
experimentally supports node-gyp, but node-gyp doesn't yet support static library linking when cross-compiling. TheMakefile
also gives us a cleaner way to load and build thelibpg_query
source.yarn build:wasm
runs via Docker to make the build process easier for devs who don't have emsdk installed.I needed to patch one line of code inThis is now merged.libpg_query
'sMakefile
to getlibpg_query.a
to build properly for Emscripten, hence the reference to my fork at https://github.com/gregnr/libpg_query.git. Once that PR is merged I will link back to the original repo.Output format
I opted for Emscripten'sSINGLE_FILE=1
flag for now which bundles the.wasm
output into the accompanying.js
file as base64. The.js
file ends up just under 2MB, but this makes NPM distribution and bundling much simpler (otherwise devs will need to add special rules to their web bundler configs to import the.wasm
file properly). I tested serving the.js
file over a web server that uses standard gzip compression, and the compressed file size went down to ~450Kb, which is more approachable.SINGLE_FILE=1
, we now useEXPORT_ES6=1
which outputs the.js
and.wasm
separately, where the.js
file is built as an ES Module that includes aimport.meta.url
reference to the WASM file, as noted below by @RReverser. Bundlers like webpack have first class support forimport.meta.url
, meaning no extra configuration is required to load the.wasm
file.Async only + single threaded for now
init()
command before they can use them.pthread
and usesemnapi
'semnapi-basic
lib. This means that asynchronous logic (ie.AsyncWorker
, etc) isn't truly multithreaded - it's just mocked in the main thread. It is possible to enablepthread
which is implemented as WebWorkers under the hood, but this method requiresSharedArrayBuffer
which has much stricter security requirements and makes deploying much more difficult/nuanced. If we are still interested in executing WASM in a different thread, I suggest we manually wrap the current output in WebWorkers and manage the back-and-forth communication ourselves without usingSharedArrayBuffer
.Consumption
exports
topackage.json
which should tell each runtime/bundler which entry point to use - meaning Node.js will continue to use the native NAPI bindings and web bundlers will use the WASM build.I haven't yet tested publishing this to NPM and using it, but plan to shortly.This has now been tested when imported as a published NPM module:@gregnr/[email protected]
. Works in both Node (uses native NAPI) and browser (uses WASM).Webpack POC
./test
as a means to test the lib in the browser.