Skip to content

Instantly share code, notes, and snippets.

@WietseWind
Created May 25, 2024 00:40
Show Gist options
  • Save WietseWind/987dd7140cb1099d3abbdf1cd485cfed to your computer and use it in GitHub Desktop.
Save WietseWind/987dd7140cb1099d3abbdf1cd485cfed to your computer and use it in GitHub Desktop.
WASI versions of ESBuild & QuickJS compiler for JS Hooks - fully client side
<! -- Demo here: https://zoq4jb3.dlvr.cloud/index.html -->
<html>
<head>
<style>
pre {
border: 1px solid red;
padding: 10px;
margin: 10px;
}
</style>
</head>
<body style="font-family: system-ui;">
<pre id="ts">// Sample
const str: string = "Some content";
console.log(str)</pre>
<pre id="js"></pre>
<pre id="bc"></pre>
<script type="module">
import { WASI } from 'https://cdn.jsdelivr.net/npm/@runno/wasi@0.7.0/+esm'
import { Buffer } from 'https://cdn.jsdelivr.net/npm/buffer@6.0.3/+esm'
// Setup a proxy to fetch release from GH and add CORS & correct wasm MIME
const binaries = {
esbuild: 'https://github-release.dlvr.cloud/XRPL-Labs/jshooks-esbuild/releases/download/autorelease/esbuild.wasm',
qjsc: 'https://github-release.dlvr.cloud/XRPL-Labs/jshooks-quickjs-runtime/releases/download/autorelease/qjsc.wasm'
}
const stdout = (...args) => console.info(...args)
const stderr = (...args) => console.info(...args)
const ts2js = content => new Promise(resolve => {
const esbuild = WASI.start(fetch(binaries.esbuild), {
args: ['esbuild', 'file.ts', '--bundle', '--minify', '--platform=browser', '--format=esm', '--target=es2017', '--outfile=file.js'],
stdout, stderr,
fs: {
"/file.ts": {
mode: "string", path: "/file.ts", timestamps: { access: new Date(), change: new Date(), modification: new Date(), },
content,
},
},
})
esbuild.then(({ fs: js }) => resolve(Buffer.from(js?.['/file.js']?.content).toString()))
})
const js2bc = content => new Promise(resolve => {
const qjsc = WASI.start(fetch(binaries.qjsc), {
args: ["qjsc", "-c", "-o", "/hook.bc", '/hook.js'],
stdout, stderr,
fs: {
"/hook.js": {
mode: "string", path: "/hook.js", timestamps: { access: new Date(), change: new Date(), modification: new Date(), },
content,
},
},
})
qjsc.then(({ fs: bc }) => resolve(Buffer.from(bc?.['/hook.bc']?.content).toString()))
})
// Magic!!
ts2js(document.getElementById('ts').innerText)
.then(js => {
document.getElementById('js').innerText = js
return js2bc(js)
}).then(bc => {
document.getElementById('bc').innerText = bc
console.log(bc)
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment