Decodal/site/decodal-site/src/Playground.svelte

82 lines
1.7 KiB
Svelte

<script>
import { onMount } from 'svelte';
const starter = `let
Service = {
name = String;
port = Int & > 443 default 8443;
feature.enable = Bool default true;
};
in
Service & {
name = "api";
port = 9443;
}
`;
let source = starter;
let output = '';
let error = '';
let ready = false;
let loading = true;
let evaluate;
onMount(async () => {
try {
const wasm = await import('./wasm/decodal_wasm.js');
await wasm.default();
evaluate = wasm.evaluate;
ready = true;
run();
} catch (err) {
error = `Failed to load WASM playground: ${err.message ?? err}`;
} finally {
loading = false;
}
});
function run() {
if (!evaluate) return;
const result = JSON.parse(evaluate(source));
if (result.ok) {
output = result.output;
error = '';
} else {
output = '';
error = result.error;
}
}
</script>
<section class="playground-page">
<div class="playground-header">
<div>
<h1>Playground</h1>
<p>Evaluate Decodal directly in your browser through WebAssembly.</p>
</div>
<button on:click={run} disabled={!ready}>Run</button>
</div>
{#if loading}
<p class="status">Loading WASM...</p>
{/if}
<div class="playground-grid">
<label class="pane">
<span>Input</span>
<textarea bind:value={source} spellcheck="false" on:keydown={(event) => {
if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') run();
}} />
</label>
<section class="pane output-pane">
<span>Output</span>
{#if error}
<pre class="error">{error}</pre>
{:else}
<pre>{output}</pre>
{/if}
</section>
</div>
</section>