|
1 | | -<!DOCTYPE html> |
| 1 | +<!doctype html> |
2 | 2 | <html lang="en"> |
3 | | -<head> |
4 | | - <meta charset="UTF-8"> |
5 | | - <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
6 | | - <title>@sebastianwessel/quickjs in browser example</title> |
7 | | - <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.css"> |
8 | | - <link href=" https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel=" stylesheet" > |
9 | | - <style> |
10 | | - .CodeMirror { |
11 | | - height: 100%; |
12 | | - } |
13 | | - </style> |
14 | | -</head> |
15 | | -<body class="flex h-screen font-sans"> |
16 | | - <div class="flex flex-col w-2/3 border-r border-gray-300"> |
17 | | - <div class="bg-gray-100 text-center text-xl font-bold p-4"> |
18 | | - Enter your code |
19 | | - </div> |
20 | | - <div class="flex-1"> |
21 | | - <textarea id="code" class="h-full w-full">import { readFileSync, writeFileSync } from 'node:fs' |
| 3 | + <head> |
| 4 | + <meta charset="UTF-8" /> |
| 5 | + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| 6 | + <title>@sebastianwessel/quickjs in browser example</title> |
| 7 | + <link |
| 8 | + rel="stylesheet" |
| 9 | + href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.css" |
| 10 | + /> |
| 11 | + <link |
| 12 | + href=" https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" |
| 13 | + rel="stylesheet" |
| 14 | + /> |
| 15 | + <style> |
| 16 | + .CodeMirror { |
| 17 | + height: 100%; |
| 18 | + } |
| 19 | + </style> |
| 20 | + </head> |
| 21 | + <body class="flex h-screen font-sans"> |
| 22 | + <div class="flex flex-col w-2/3 border-r border-gray-300"> |
| 23 | + <div class="bg-gray-100 text-center text-xl font-bold p-4"> |
| 24 | + Enter your code |
| 25 | + </div> |
| 26 | + <div class="flex-1"> |
| 27 | + <textarea id="code" class="h-full w-full"> |
| 28 | +import { readFileSync, writeFileSync } from 'node:fs' |
22 | 29 | console.info('Starting...') |
23 | 30 | const fn = async (value)=> { |
24 | 31 | console.debug(value) |
|
32 | 39 | const response = await fetch('https://sebastianwessel.github.io/quickjs/example-request.html') |
33 | 40 | if(!response.ok) { |
34 | 41 | console.error('Request failed: ' + response.status + ' ' + response.statusText) |
35 | | - return |
| 42 | + return |
36 | 43 | } |
37 | 44 | const body = await response.text() |
38 | 45 | console.log('Response body: '+ body) |
|
43 | 50 |
|
44 | 51 | console.warn('top-level await is nice') |
45 | 52 |
|
46 | | -export default await fn('Hello World')</textarea> |
47 | | - </div> |
48 | | - <button id="runButton" class="bg-blue-500 text-white font-semibold text-lg p-4 hover:bg-blue-700"> |
49 | | - Run Code |
50 | | - </button> |
51 | | - </div> |
52 | | - <div class="flex flex-col w-1/3"> |
53 | | - <div class="bg-gray-100 p-4"> |
54 | | - <div class="text-center text-xl font-bold ">Result</div> |
55 | | - <pre id="output" class="font-semibold"></pre> |
| 53 | +export default await fn('Hello World')</textarea |
| 54 | + > |
| 55 | + </div> |
| 56 | + <button |
| 57 | + id="runButton" |
| 58 | + class="bg-blue-500 text-white font-semibold text-lg p-4 hover:bg-blue-700" |
| 59 | + > |
| 60 | + Run Code |
| 61 | + </button> |
56 | 62 | </div> |
57 | | - <div id="consoleOutput" class="flex-1 p-4 bg-black text-white overflow-y-auto"> |
58 | | - <pre id="console"></pre> |
| 63 | + <div class="flex flex-col w-1/3"> |
| 64 | + <div class="bg-gray-100 p-4"> |
| 65 | + <div class="text-center text-xl font-bold">Result</div> |
| 66 | + <pre id="output" class="font-semibold"></pre> |
| 67 | + </div> |
| 68 | + <div |
| 69 | + id="consoleOutput" |
| 70 | + class="flex-1 p-4 bg-black text-white overflow-y-auto" |
| 71 | + > |
| 72 | + <pre id="console"></pre> |
| 73 | + </div> |
59 | 74 | </div> |
60 | | - </div> |
61 | 75 |
|
62 | | - <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.js"></script> |
63 | | - <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/mode/javascript/javascript.min.js"></script> |
64 | | - <script type="module"> |
65 | | - var editor = CodeMirror.fromTextArea(document.getElementById('code'), { |
66 | | - mode: { name: "javascript", typescript: true }, |
67 | | - lineNumbers: true |
68 | | - }); |
| 76 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.js"></script> |
| 77 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/mode/javascript/javascript.min.js"></script> |
| 78 | + <script type="module"> |
| 79 | + var editor = CodeMirror.fromTextArea( |
| 80 | + document.getElementById("code"), |
| 81 | + { |
| 82 | + mode: { name: "javascript", typescript: true }, |
| 83 | + lineNumbers: true, |
| 84 | + }, |
| 85 | + ); |
69 | 86 |
|
70 | | - function logMessage(type, message) { |
71 | | - var outputElement = document.getElementById('console'); |
72 | | - var logMessage = document.createElement('div'); |
73 | | - logMessage.className = type; |
74 | | - logMessage.textContent = message; |
75 | | - outputElement.appendChild(logMessage); |
76 | | - } |
77 | | - |
78 | | -// =========== QuickJS ===================== |
79 | | - import { loadQuickJs } from "https://esm.sh/@sebastianwessel/[email protected]" |
80 | | - import "https://esm.sh/typescript" |
| 87 | + function logMessage(type, message) { |
| 88 | + var outputElement = document.getElementById("console"); |
| 89 | + var logMessage = document.createElement("div"); |
| 90 | + logMessage.className = type; |
| 91 | + logMessage.textContent = message; |
| 92 | + outputElement.appendChild(logMessage); |
| 93 | + } |
81 | 94 |
|
82 | | - const { runSandboxed } = await loadQuickJs('https://esm.sh/@jitl/quickjs-wasmfile-release-sync') |
| 95 | + // =========== QuickJS ===================== |
| 96 | + import { loadQuickJs } from "https://esm.sh/@sebastianwessel/[email protected]"; |
| 97 | + import "https://esm.sh/typescript"; |
| 98 | + import variant from "https://esm.sh/@jitl/quickjs-wasmfile-release-sync"; |
83 | 99 |
|
84 | | - const fetchAdapter = async (url,param)=> { |
85 | | - const res = await fetch(url,{...param}) |
86 | | - console.log(res) |
87 | | - return { |
88 | | - status: res.status, |
89 | | - ok: res.ok, |
90 | | - statusText: res.statusText, |
91 | | - json: async () => await res.json(), |
92 | | - text: async () => await res.text(), |
93 | | - formData: () => res.formData(), |
94 | | - headers: res.headers, |
95 | | - type: res.type, |
96 | | - url: res.url, |
97 | | - blob: async () => await res.blob(), |
98 | | - bodyUsed: res.bodyUsed, |
99 | | - redirected: res.redirected, |
100 | | - body: res.body, |
101 | | - arrayBuffer: async () => await res.arrayBuffer(), |
102 | | - clone: () => res.clone(), |
103 | | - } |
104 | | - } |
| 100 | + const { runSandboxed } = await loadQuickJs(variant); |
105 | 101 |
|
106 | | - document.getElementById('runButton').addEventListener('click', async function() { |
107 | | - var code = editor.getValue(); |
108 | | - var outputElement = document.getElementById('output'); |
109 | | - var consoleElement = document.getElementById('console'); |
110 | | - outputElement.innerHTML='' |
111 | | - consoleElement.innerHTML='' |
| 102 | + const fetchAdapter = async (url, param) => { |
| 103 | + const res = await fetch(url, { ...param }); |
| 104 | + console.log(res); |
| 105 | + return { |
| 106 | + status: res.status, |
| 107 | + ok: res.ok, |
| 108 | + statusText: res.statusText, |
| 109 | + json: async () => await res.json(), |
| 110 | + text: async () => await res.text(), |
| 111 | + formData: () => res.formData(), |
| 112 | + headers: res.headers, |
| 113 | + type: res.type, |
| 114 | + url: res.url, |
| 115 | + blob: async () => await res.blob(), |
| 116 | + bodyUsed: res.bodyUsed, |
| 117 | + redirected: res.redirected, |
| 118 | + body: res.body, |
| 119 | + arrayBuffer: async () => await res.arrayBuffer(), |
| 120 | + clone: () => res.clone(), |
| 121 | + }; |
| 122 | + }; |
112 | 123 |
|
113 | | - const options = { |
114 | | - allowFetch: true, // inject fetch and allow the code to fetch data |
115 | | - allowFs: true, // mount a virtual file system and provide node:fs module |
116 | | - fetchAdapter, // browser-fetch |
117 | | - env: { |
118 | | - MY_ENV_VAR: 'env var value', |
119 | | - }, |
120 | | - console: { |
121 | | - log: (message)=>logMessage('log text-gray-400', message), |
122 | | - info: (message)=>logMessage('info text-blue-500', message), |
123 | | - warn: (message)=>logMessage('warn text-yellow-500', message), |
124 | | - error: (message)=>logMessage('error text-red-500', message), |
125 | | - } |
126 | | - } |
127 | | - |
128 | | - try { |
129 | | - const res = await runSandboxed(async ({ evalCode }) => { |
130 | | - return evalCode(code) |
131 | | - },options) |
| 124 | + document |
| 125 | + .getElementById("runButton") |
| 126 | + .addEventListener("click", async function () { |
| 127 | + var code = editor.getValue(); |
| 128 | + var outputElement = document.getElementById("output"); |
| 129 | + var consoleElement = document.getElementById("console"); |
| 130 | + outputElement.innerHTML = ""; |
| 131 | + consoleElement.innerHTML = ""; |
132 | 132 |
|
133 | | - outputElement.innerHTML = JSON.stringify(res,null,2).replaceAll('\\n','<br>') |
134 | | - } catch (e) { |
135 | | - console.error(e); |
136 | | - logMessage('error text-red-500', JSON.stringify(e).replaceAll('\\n','<br>')) |
137 | | - } |
138 | | - }); |
139 | | - </script> |
140 | | -</body> |
| 133 | + const options = { |
| 134 | + allowFetch: true, // inject fetch and allow the code to fetch data |
| 135 | + allowFs: true, // mount a virtual file system and provide node:fs module |
| 136 | + fetchAdapter, // browser-fetch |
| 137 | + env: { |
| 138 | + MY_ENV_VAR: "env var value", |
| 139 | + }, |
| 140 | + console: { |
| 141 | + log: (message) => |
| 142 | + logMessage("log text-gray-400", message), |
| 143 | + info: (message) => |
| 144 | + logMessage("info text-blue-500", message), |
| 145 | + warn: (message) => |
| 146 | + logMessage("warn text-yellow-500", message), |
| 147 | + error: (message) => |
| 148 | + logMessage("error text-red-500", message), |
| 149 | + }, |
| 150 | + }; |
| 151 | + |
| 152 | + try { |
| 153 | + const res = await runSandboxed(async ({ evalCode }) => { |
| 154 | + return evalCode(code); |
| 155 | + }, options); |
| 156 | + |
| 157 | + outputElement.innerHTML = JSON.stringify( |
| 158 | + res, |
| 159 | + null, |
| 160 | + 2, |
| 161 | + ).replaceAll("\\n", "<br>"); |
| 162 | + } catch (e) { |
| 163 | + console.error(e); |
| 164 | + logMessage( |
| 165 | + "error text-red-500", |
| 166 | + JSON.stringify(e).replaceAll("\\n", "<br>"), |
| 167 | + ); |
| 168 | + } |
| 169 | + }); |
| 170 | + </script> |
| 171 | + </body> |
141 | 172 | </html> |
0 commit comments