From d426848cab5c2a772168ce9141ef801e9bf94132 Mon Sep 17 00:00:00 2001
From: printfn
Date: Thu, 2 May 2024 12:25:00 +0000
Subject: [PATCH] Fix wasm initialisation
---
web/src/App.tsx | 120 ++++++++++++++++----------------------------
web/src/lib/wasm.ts | 32 ++++++++++++
2 files changed, 76 insertions(+), 76 deletions(-)
create mode 100644 web/src/lib/wasm.ts
diff --git a/web/src/App.tsx b/web/src/App.tsx
index e689d018..33f43075 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -1,20 +1,5 @@
-import {
- evaluateFendWithTimeout,
- evaluateFendWithVariablesJson,
- default as initWasm,
- initialiseWithHandlers,
-} from 'fend-wasm';
-import {
- type FormEvent,
- type KeyboardEvent,
- type ReactNode,
- useCallback,
- useEffect,
- useMemo,
- useRef,
- useState,
-} from 'react';
-import { getExchangeRates } from './lib/exchange-rates';
+import { type FormEvent, type KeyboardEvent, type ReactNode, useCallback, useEffect, useRef, useState } from 'react';
+import { fend } from './lib/wasm';
const examples = `
> 5'10" to cm
@@ -46,36 +31,22 @@ const exampleContent = (
);
-async function load() {
- try {
- await initWasm();
- initialiseWithHandlers(await getExchangeRates());
-
- const result = evaluateFendWithTimeout('1 + 2', 500);
- if (result !== '3') {
- alert('Failed to initialise WebAssembly');
- return;
- }
- } catch (e) {
- console.error(e);
- alert('Failed to initialise WebAssembly');
- return;
- }
-}
-await load();
-
export default function App({ widget = false }: { widget?: boolean }) {
const [currentInput, setCurrentInput] = useState('');
const [output, setOutput] = useState(widget ? <>> : exampleContent);
const [history, setHistory] = useState([]);
const [variables, setVariables] = useState('');
const [navigation, setNavigation] = useState(0);
- const hint = useMemo(() => {
- const result = JSON.parse(evaluateFendWithVariablesJson(currentInput, 100, variables));
- if (!result.ok) {
- return '';
- }
- return result.result;
+ const [hint, setHint] = useState('');
+ useEffect(() => {
+ (async () => {
+ const result = await fend(currentInput, 100, variables);
+ if (!result.ok) {
+ setHint('');
+ } else {
+ setHint(result.result);
+ }
+ })();
}, [currentInput, variables]);
const inputText = useRef(null);
const inputHint = useRef(null);
@@ -93,37 +64,39 @@ export default function App({ widget = false }: { widget?: boolean }) {
}, []);
const evaluate = useCallback(
(event: KeyboardEvent) => {
- // allow multiple lines to be entered if shift, ctrl
- // or meta is held, otherwise evaluate the expression
- if (!(event.key === 'Enter' && !event.shiftKey && !event.ctrlKey && !event.metaKey)) {
- return;
- }
- event.preventDefault();
- if (currentInput.trim() === 'clear') {
+ (async () => {
+ // allow multiple lines to be entered if shift, ctrl
+ // or meta is held, otherwise evaluate the expression
+ if (!(event.key === 'Enter' && !event.shiftKey && !event.ctrlKey && !event.metaKey)) {
+ return;
+ }
+ event.preventDefault();
+ if (currentInput.trim() === 'clear') {
+ setCurrentInput('');
+ setOutput(null);
+ return;
+ }
+ const request = {`> ${currentInput}`}
;
+ if (currentInput.trim().length > 0) {
+ setHistory(h => [...h, currentInput]);
+ }
+ setNavigation(0);
+ const fendResult = await fend(currentInput, 500, variables);
setCurrentInput('');
- setOutput(null);
- return;
- }
- const request = {`> ${currentInput}`}
;
- if (currentInput.trim().length > 0) {
- setHistory(h => [...h, currentInput]);
- }
- setNavigation(0);
- const fendResult = JSON.parse(evaluateFendWithVariablesJson(currentInput, 500, variables));
- setCurrentInput('');
- console.log(fendResult);
- const result = {fendResult.ok ? fendResult.result : fendResult.message}
;
- if (fendResult.ok && fendResult.variables.length > 0) {
- setVariables(fendResult.variables);
- }
- setOutput(o => (
- <>
- {o}
- {request}
- {result}
- >
- ));
- inputHint.current?.scrollIntoView();
+ console.log(fendResult);
+ const result = {fendResult.ok ? fendResult.result : fendResult.message}
;
+ if (fendResult.ok && fendResult.variables.length > 0) {
+ setVariables(fendResult.variables);
+ }
+ setOutput(o => (
+ <>
+ {o}
+ {request}
+ {result}
+ >
+ ));
+ inputHint.current?.scrollIntoView();
+ })();
},
[currentInput, variables],
);
@@ -147,11 +120,6 @@ export default function App({ widget = false }: { widget?: boolean }) {
},
[currentInput, navigation, history],
);
- useEffect(() => {
- (async () => {
- await load();
- })();
- }, []);
useEffect(() => {
document.addEventListener('click', focus);
return () => {
diff --git a/web/src/lib/wasm.ts b/web/src/lib/wasm.ts
new file mode 100644
index 00000000..ab260f49
--- /dev/null
+++ b/web/src/lib/wasm.ts
@@ -0,0 +1,32 @@
+import {
+ evaluateFendWithTimeout,
+ evaluateFendWithVariablesJson,
+ default as initWasm,
+ initialiseWithHandlers,
+} from 'fend-wasm';
+import { getExchangeRates } from './exchange-rates';
+
+async function load() {
+ try {
+ const [, exchangeRates] = await Promise.all([initWasm(), getExchangeRates()]);
+ initialiseWithHandlers(exchangeRates);
+
+ const result = evaluateFendWithTimeout('1 + 2', 500);
+ if (result !== '3') {
+ alert('Failed to initialise WebAssembly');
+ return;
+ }
+ } catch (e) {
+ console.error(e);
+ alert('Failed to initialise WebAssembly');
+ return;
+ }
+}
+await load();
+
+type FendResult = { ok: true; result: string; variables: string } | { ok: false; message: string };
+
+export async function fend(input: string, timeout: number, variables: string) {
+ const res: FendResult = JSON.parse(evaluateFendWithVariablesJson(input, timeout, variables));
+ return res;
+}