Implement editor poc
This commit is contained in:
parent
cd16208634
commit
60b2b56d8f
54
webserial/package-lock.json
generated
54
webserial/package-lock.json
generated
@ -11,6 +11,8 @@
|
||||
"@sveltejs/vite-plugin-svelte": "^2.0.0",
|
||||
"@tsconfig/svelte": "^3.0.0",
|
||||
"@types/w3c-web-serial": "^1.0.3",
|
||||
"monaco-editor": "^0.34.1",
|
||||
"sass": "^1.57.1",
|
||||
"svelte": "^3.54.0",
|
||||
"svelte-check": "^2.10.0",
|
||||
"tslib": "^2.4.1",
|
||||
@ -776,6 +778,12 @@
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.1.tgz",
|
||||
"integrity": "sha512-7WYV7Q5BTs0nlQm7tl92rDYYoyELLKHoDMBKhrxEoiV4mrfVdRz8hzPiYOzH7yWjzoVEamxRuAqhxL2PLRwZYQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
@ -947,6 +955,12 @@
|
||||
"mkdirp": "bin/cmd.js"
|
||||
}
|
||||
},
|
||||
"node_modules/monaco-editor": {
|
||||
"version": "0.34.1",
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.1.tgz",
|
||||
"integrity": "sha512-FKc80TyiMaruhJKKPz5SpJPIjL+dflGvz4CpuThaPMc94AyN7SeC9HQ8hrvaxX7EyHdJcUY5i4D0gNyJj1vSZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/mri": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
|
||||
@ -1204,6 +1218,23 @@
|
||||
"rimraf": "^2.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.57.1",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz",
|
||||
"integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"sass": "sass.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sorcery": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz",
|
||||
@ -1948,6 +1979,12 @@
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"immutable": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.1.tgz",
|
||||
"integrity": "sha512-7WYV7Q5BTs0nlQm7tl92rDYYoyELLKHoDMBKhrxEoiV4mrfVdRz8hzPiYOzH7yWjzoVEamxRuAqhxL2PLRwZYQ==",
|
||||
"dev": true
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
@ -2074,6 +2111,12 @@
|
||||
"minimist": "^1.2.6"
|
||||
}
|
||||
},
|
||||
"monaco-editor": {
|
||||
"version": "0.34.1",
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.1.tgz",
|
||||
"integrity": "sha512-FKc80TyiMaruhJKKPz5SpJPIjL+dflGvz4CpuThaPMc94AyN7SeC9HQ8hrvaxX7EyHdJcUY5i4D0gNyJj1vSZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"mri": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
|
||||
@ -2237,6 +2280,17 @@
|
||||
"rimraf": "^2.5.2"
|
||||
}
|
||||
},
|
||||
"sass": {
|
||||
"version": "1.57.1",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.57.1.tgz",
|
||||
"integrity": "sha512-O2+LwLS79op7GI0xZ8fqzF7X2m/m8WFfI02dHOdsK5R2ECeS5F62zrwg/relM1rjSLy7Vd/DiMNIvPrQGsA0jw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
}
|
||||
},
|
||||
"sorcery": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz",
|
||||
|
@ -13,6 +13,8 @@
|
||||
"@sveltejs/vite-plugin-svelte": "^2.0.0",
|
||||
"@tsconfig/svelte": "^3.0.0",
|
||||
"@types/w3c-web-serial": "^1.0.3",
|
||||
"monaco-editor": "^0.34.1",
|
||||
"sass": "^1.57.1",
|
||||
"svelte": "^3.54.0",
|
||||
"svelte-check": "^2.10.0",
|
||||
"tslib": "^2.4.1",
|
||||
|
@ -1,10 +1,28 @@
|
||||
<script lang="ts">
|
||||
import Par from "./dmx/fixtures/par.svelte";
|
||||
import Monaco from "./editor/Monaco.svelte";
|
||||
import EvalLoop from "./eval/EvalLoop.svelte";
|
||||
import SerialManager from "./serial/SerialManager.svelte";
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div>cOnTeNt</div>
|
||||
<Par address={1} />
|
||||
<Monaco />
|
||||
<SerialManager />
|
||||
<EvalLoop />
|
||||
</main>
|
||||
|
||||
<style lang="scss">
|
||||
:global(body) {
|
||||
margin: 0;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
:global(#app) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
main {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
|
7
webserial/src/dmx/Debug.svelte
Normal file
7
webserial/src/dmx/Debug.svelte
Normal file
@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { dmxData } from "./store";
|
||||
|
||||
$: dbg = new Array(10).fill(0).map((_, i) => `${i}: ${$dmxData[i].toString().padStart(3, " ")}`).join(" ");
|
||||
</script>
|
||||
|
||||
<pre>dbg: "{dbg}"</pre>
|
50
webserial/src/editor/Monaco.svelte
Normal file
50
webserial/src/editor/Monaco.svelte
Normal file
@ -0,0 +1,50 @@
|
||||
<script lang="ts">
|
||||
import * as monaco from "monaco-editor";
|
||||
import { onMount } from "svelte";
|
||||
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
|
||||
import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
|
||||
import TS from "typescript";
|
||||
import defaultCode from "./defaultCode.ts?raw";
|
||||
import defaultEnv from "./defaultEnv.d.ts?raw";
|
||||
import { code } from "./code";
|
||||
|
||||
let divEl: HTMLDivElement = null;
|
||||
let editor: monaco.editor.IStandaloneCodeEditor;
|
||||
|
||||
let value = defaultCode;
|
||||
$: $code = TS.transpile(value, { strict: true });
|
||||
|
||||
onMount(async () => {
|
||||
// @ts-ignore
|
||||
self.MonacoEnvironment = {
|
||||
getWorker: function (_moduleId: any, label: string) {
|
||||
if (label === "typescript" || label === "javascript") {
|
||||
return new tsWorker();
|
||||
}
|
||||
return new editorWorker();
|
||||
},
|
||||
};
|
||||
|
||||
editor = monaco.editor.create(divEl, {
|
||||
value: value,
|
||||
language: "typescript",
|
||||
});
|
||||
|
||||
let lib = monaco.languages.typescript.typescriptDefaults.addExtraLib(defaultEnv);
|
||||
|
||||
editor.onKeyUp((_e) => (value = editor.getValue()));
|
||||
|
||||
return () => {
|
||||
lib.dispose();
|
||||
editor.dispose();
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<div bind:this={divEl} />
|
||||
|
||||
<style lang="scss">
|
||||
div {
|
||||
flex-grow: 1;
|
||||
}
|
||||
</style>
|
6
webserial/src/editor/code.ts
Normal file
6
webserial/src/editor/code.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { writable } from "svelte/store";
|
||||
import defaultCode from "./defaultCode.ts?raw";
|
||||
import TS from "typescript";
|
||||
|
||||
/** the transpiled JavaScript code */
|
||||
export const code = writable(TS.transpile(defaultCode, {strict: true}));
|
4
webserial/src/editor/defaultCode.ts
Normal file
4
webserial/src/editor/defaultCode.ts
Normal file
@ -0,0 +1,4 @@
|
||||
// ayaya ayaya
|
||||
|
||||
ctx.set(1, 255);
|
||||
ctx.set(2, 255);
|
9
webserial/src/editor/defaultEnv.d.ts
vendored
Normal file
9
webserial/src/editor/defaultEnv.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
type Context = {
|
||||
set(address: number, value: number): void,
|
||||
};
|
||||
|
||||
/** the global Context object */
|
||||
declare const ctx: Context;
|
||||
|
||||
/** the current time (in seconds, e.g. 1.25 after 1250 milliseconds) */
|
||||
declare const t: number;
|
43
webserial/src/eval/EvalLoop.svelte
Normal file
43
webserial/src/eval/EvalLoop.svelte
Normal file
@ -0,0 +1,43 @@
|
||||
<script lang="ts">
|
||||
/// <reference path="../editor/defaultEnv.d.ts" />
|
||||
import { onMount } from "svelte";
|
||||
import { code } from "../editor/code";
|
||||
import { dmxData } from "../dmx/store";
|
||||
|
||||
let startTime: number;
|
||||
let payload = new Uint8Array(512);
|
||||
let ctx: Context = {
|
||||
set(address: number, value: number) {
|
||||
payload[address - 1] = value;
|
||||
}
|
||||
}
|
||||
|
||||
let result: string;
|
||||
|
||||
function dmxFrame() {
|
||||
payload = new Uint8Array(512);
|
||||
const t = (performance.now() - startTime) / 1000;
|
||||
try {
|
||||
let ret = Function("ctx", "t", $code).call({}, ctx, t);
|
||||
result = JSON.stringify(ret);
|
||||
} catch (err) {
|
||||
result = JSON.stringify(err);
|
||||
}
|
||||
$dmxData = payload;
|
||||
}
|
||||
|
||||
const FPS = 50;
|
||||
const FRAME_TIME = 1000 / FPS; // milliseconds
|
||||
|
||||
onMount(() => {
|
||||
startTime = performance.now();
|
||||
|
||||
let int = setInterval(dmxFrame, FRAME_TIME);
|
||||
|
||||
return () => {
|
||||
clearInterval(int);
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!-- <pre>{result}</pre> -->
|
@ -13,6 +13,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#if navigator.serial}
|
||||
<p>Serial available 🚀</p>
|
||||
{#if port !== null}
|
||||
@ -24,4 +25,11 @@
|
||||
{:else}
|
||||
<p>Looks like your browser does not support WebSerial 😢</p>
|
||||
<p>Check <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API#browser_compatibility">here</a> for a list of compatible browsers</p>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div {
|
||||
height: 15vh;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user