Skip to content

Commit

Permalink
Merge pull request #27 from sebastianwessel/22-doc-add-documentation-…
Browse files Browse the repository at this point in the history
…about-using-this-lib-in-browser-and-on-platform-providers

doc: add documentation about platform support
  • Loading branch information
sebastianwessel authored Jul 12, 2024
2 parents 3d6c01b + 67dfebf commit d561595
Show file tree
Hide file tree
Showing 6 changed files with 320 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This TypeScript package allows you to safely execute **JavaScript and TypeScript
- [Fetch in Guest System](./fetch.md)
- [Custom Node Modules](./custom-modules.md)
- [Custom File System](./custom-file-system.md)
- [Usage in browser and on Providers](./usage-in-browser-and-providers.md)
- Compatibility:
- [Core Javascript](./core-js-compatibility.md)
- [NodeJS](./node-compatibility.md)
Expand Down
128 changes: 128 additions & 0 deletions docs/example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@sebastianwessel/quickjs in browser exmple</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
<style>
.CodeMirror {
height: 100%;
}
</style>
</head>
<body class="flex h-screen font-sans">
<div class="flex flex-col w-2/3 border-r border-gray-300">
<div class="bg-gray-100 text-center text-xl font-bold p-4">
Enter your code
</div>
<div class="flex-1">
<textarea id="code" class="h-full w-full">import { readFileSync, writeFileSync } from 'node:fs'
console.info('Starting...')
const fn = async (value: string)=> {
console.debug(value)
writeFileSync('./text.txt', value)
return readFileSync('./text.txt')
}

console.warn('Might be cool!')

const getExample = async ()=> {
try {
const response = await fetch('https://example.com')

if(!response.ok) {
console.error('Request failed ' + response.statusCode )
return
}
console.log(await response.text())
}catch(err){
console.error('Failed to fetch! Check browser console!')
console.error(JSON.stringify(err,null,2))
}
}

await getExample()

console.warn('top-level await is nice')

export default await fn('Hello World')</textarea>
</div>
<button id="runButton" class="bg-blue-500 text-white font-semibold text-lg p-4 hover:bg-blue-700">
Run Code
</button>
</div>
<div class="flex flex-col w-1/3">
<div class="bg-gray-100 p-4">
<div class="text-center text-xl font-bold ">Result</div>
<pre id="output" class="font-semibold"></pre>
</div>
<div id="consoleOutput" class="flex-1 p-4 bg-black text-white overflow-y-auto">
<pre id="console"></pre>
</div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/mode/javascript/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/mode/javascript/typescript.min.js"></script>
<script type="module">
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
mode: { name: "javascript", typescript: true },
lineNumbers: true
});

function logMessage(type, message) {
var outputElement = document.getElementById('console');
var logMessage = document.createElement('div');
logMessage.className = type;
logMessage.textContent = message;
outputElement.appendChild(logMessage);
}


// =========== QuickJS =====================
import { quickJS } from "https://esm.sh/@sebastianwessel/[email protected]"
import "https://esm.sh/typescript"

const {createRuntime} = await quickJS('https://esm.sh/@jitl/quickjs-wasmfile-release-sync')

const fetchAdapter = (...param)=>fetch(...param)

document.getElementById('runButton').addEventListener('click', async function() {
var code = editor.getValue();
var outputElement = document.getElementById('output');
var consoleElement = document.getElementById('console');
outputElement.innerHTML=''
consoleElement.innerHTML=''

const { evalCode } = await createRuntime({
allowFetch: true, // inject fetch and allow the code to fetch data
allowFs: true, // mount a virtual file system and provide node:fs module
transformTypescript: true, // typescript support
fetchAdapter, // browser-fetch
env: {
MY_ENV_VAR: 'env var value',
},
console: {
log: (message)=>logMessage('log text-gray-400', message),
info: (message)=>logMessage('info text-blue-500', message),
warn: (message)=>logMessage('warn text-yellow-500', message),
error: (message)=>logMessage('error text-red-500', message),
}
})




try {
const res = await evalCode(code);
outputElement.innerHTML = JSON.stringify(res,null,2).replaceAll('\\n','<br>')
} catch (e) {
console.error(e);
logMessage('error text-red-500', JSON.stringify(e).replaceAll('\\n','<br>'))
}
});
</script>
</body>
</html>
40 changes: 40 additions & 0 deletions docs/usage-in-browser-and-providers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: sage in browser and on Providers
description: Use the QuickJS library in browser an on platform providers
---

## Usage in Browser

Here is the most minimal example on how to use this library in the browser.
You need to ensure, that the webassembly file can be loaded correctly. Therefore, you need to add this as parameter to the `quickJS` call.

Using `fetch`is possible, but there are the same restrictions as in any other browser usage (CORS & co).

```html
<!doctype html>
<!-- Import from a ES Module CDN -->
<script type="module">
import { quickJS } from "https://esm.sh/@sebastianwessel/[email protected]"
const {createRuntime} = await quickJS('https://esm.sh/@jitl/quickjs-wasmfile-release-sync')
const { evalCode } = await createRuntime({
allowFetch: true,
fetchAdapter: (...params)=>fetch(...params)
env: {
MY_ENV_VAR: 'env var value',
},
})
console.log(await evalCode("export default 1+1"))
</script>
```

## Cloudflare Workers

Cloudflare workers have some limitations regarding bundling. The developers of the underlaying quickjs-emscripten library, already solved this.

[github.com/justjake/quickjs-emscripten/tree/main/examples/cloudflare-workers](https://github.com/justjake/quickjs-emscripten/tree/main/examples/cloudflare-workers)

This library will be aligned soon, to support cloudflare as well.
5 changes: 5 additions & 0 deletions example/browser/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Browser Example

An example on how to use this library witout any build step in the browser.

The [simple Version](./simple.html) and the [Playground version](./playground.html) are available.
128 changes: 128 additions & 0 deletions example/browser/playground.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@sebastianwessel/quickjs in browser exmple</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
<style>
.CodeMirror {
height: 100%;
}
</style>
</head>
<body class="flex h-screen font-sans">
<div class="flex flex-col w-2/3 border-r border-gray-300">
<div class="bg-gray-100 text-center text-xl font-bold p-4">
Enter your code
</div>
<div class="flex-1">
<textarea id="code" class="h-full w-full">import { readFileSync, writeFileSync } from 'node:fs'
console.info('Starting...')
const fn = async (value: string)=> {
console.debug(value)
writeFileSync('./text.txt', value)
return readFileSync('./text.txt')
}

console.warn('Might be cool!')

const getExample = async ()=> {
try {
const response = await fetch('https://example.com')

if(!response.ok) {
console.error('Request failed ' + response.statusCode )
return
}
console.log(await response.text())
}catch(err){
console.error('Failed to fetch! Check browser console!')
console.error(JSON.stringify(err,null,2))
}
}

await getExample()

console.warn('top-level await is nice')

export default await fn('Hello World')</textarea>
</div>
<button id="runButton" class="bg-blue-500 text-white font-semibold text-lg p-4 hover:bg-blue-700">
Run Code
</button>
</div>
<div class="flex flex-col w-1/3">
<div class="bg-gray-100 p-4">
<div class="text-center text-xl font-bold ">Result</div>
<pre id="output" class="font-semibold"></pre>
</div>
<div id="consoleOutput" class="flex-1 p-4 bg-black text-white overflow-y-auto">
<pre id="console"></pre>
</div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/mode/javascript/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/mode/javascript/typescript.min.js"></script>
<script type="module">
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
mode: { name: "javascript", typescript: true },
lineNumbers: true
});

function logMessage(type, message) {
var outputElement = document.getElementById('console');
var logMessage = document.createElement('div');
logMessage.className = type;
logMessage.textContent = message;
outputElement.appendChild(logMessage);
}


// =========== QuickJS =====================
import { quickJS } from "https://esm.sh/@sebastianwessel/[email protected]"
import "https://esm.sh/typescript"

const {createRuntime} = await quickJS('https://esm.sh/@jitl/quickjs-wasmfile-release-sync')

const fetchAdapter = (...param)=>fetch(...param)

document.getElementById('runButton').addEventListener('click', async function() {
var code = editor.getValue();
var outputElement = document.getElementById('output');
var consoleElement = document.getElementById('console');
outputElement.innerHTML=''
consoleElement.innerHTML=''

const { evalCode } = await createRuntime({
allowFetch: true, // inject fetch and allow the code to fetch data
allowFs: true, // mount a virtual file system and provide node:fs module
transformTypescript: true, // typescript support
fetchAdapter, // browser-fetch
env: {
MY_ENV_VAR: 'env var value',
},
console: {
log: (message)=>logMessage('log text-gray-400', message),
info: (message)=>logMessage('info text-blue-500', message),
warn: (message)=>logMessage('warn text-yellow-500', message),
error: (message)=>logMessage('error text-red-500', message),
}
})




try {
const res = await evalCode(code);
outputElement.innerHTML = JSON.stringify(res,null,2).replaceAll('\\n','<br>')
} catch (e) {
console.error(e);
logMessage('error text-red-500', JSON.stringify(e).replaceAll('\\n','<br>'))
}
});
</script>
</body>
</html>
18 changes: 18 additions & 0 deletions example/browser/simple.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<!-- Import from a ES Module CDN -->
<script type="module">

import { quickJS } from "https://esm.sh/@sebastianwessel/[email protected]"

const {createRuntime} = await quickJS('https://esm.sh/@jitl/quickjs-wasmfile-release-sync')

const { evalCode } = await createRuntime({
allowFetch: true, // inject fetch and allow the code to fetch data
allowFs: true, // mount a virtual file system and provide node:fs module
env: {
MY_ENV_VAR: 'env var value',
},
})

console.log(await evalCode("export default 1+1"))
</script>

0 comments on commit d561595

Please sign in to comment.