auto wasm compilation

This commit is contained in:
pantonshire committed 2023-06-13 11:45:16 +01:00
1 parent 78796489ca
commit 586e1d9e2c
6 files changed
+240 -52

No files matched your search

+6 -7
View File
@@ -3,7 +3,7 @@
import { useContext, useState } from 'react';
import styles from '@/app/page.module.css'
import { TextField } from './textfield';
import { WASMContext, WASMContextProvider } from '@/context/utfdump';
import { UtfdumpContext, UtfdumpContextProvider } from '@/context/utfdump';
type InspectorProps = {
sourceUrl: string,
@@ -13,7 +13,7 @@ export function Inspector(props: InspectorProps) {
const [currentString, setCurrentString] = useState('');
return (
<WASMContextProvider>
<UtfdumpContextProvider>
<section className={styles.inspector_section}>
<section className={styles.input_section}>
<TextField
@@ -31,14 +31,14 @@ export function Inspector(props: InspectorProps) {
<Out currentString={currentString} />
</section>
</WASMContextProvider>
</UtfdumpContextProvider>
);
}
function Out(props: { currentString: string }) {
const ctx = useContext(WASMContext);
const ctx = useContext(UtfdumpContext);
if (!ctx.wasm) {
if (!ctx.utfdump) {
return (
<p>Loading WASM...</p>
);
@@ -46,8 +46,7 @@ function Out(props: { currentString: string }) {
return (
<section className={styles.output_section}>
{/* <p id='out_test'>{spongebob_case(currentString)}</p> */}
<p id='out_test'>{ctx.wasm.spongebob_case(props.currentString)}</p>
<p id='out_test'>{ctx.utfdump.spongebob_case(props.currentString)}</p>
</section>
);
}
+30 -41
View File
@@ -1,49 +1,38 @@
// using solution from https://github.com/satelllte/nextjs-wasm for now
import { useState, createContext, useEffect, useRef } from 'react';
import type { ReactNode } from 'react';
import { useState, createContext, useEffect, useRef } from 'react'
import type { ReactNode } from 'react'
type UtfdumpContextTy = {
utfdump?: typeof import('utfdump_wasm'),
};
const initial: IWASMContext = {}
type UtfdumpContextProviderProps = {
children: ReactNode,
};
const useMountEffectOnce = (fn: () => void) => {
const wasExecutedRef = useRef(false)
export const UtfdumpContext = createContext<UtfdumpContextTy>({});
export function UtfdumpContextProvider(props: UtfdumpContextProviderProps) {
const hasLoaded = useRef(false);
const [contextValue, setContextValue] = useState<UtfdumpContextTy>({});
useEffect(() => {
if (!wasExecutedRef.current) {
fn()
// Ensure the WASM module is only run once, as this effect callback is called twice when React
// is in strict mode.
// FIXME: is atomic compare-and-swap necessary? Does React run this in a multithreaded context?
if (!hasLoaded.current) {
hasLoaded.current = true;
(async() => {
const utfdumpWasmModule = await import('utfdump_wasm');
await utfdumpWasmModule.default();
setContextValue({ utfdump: utfdumpWasmModule });
})();
}
wasExecutedRef.current = true
}, [fn])
}
export const WASMContext = createContext(initial)
export const WASMContextProvider: React.FC<WASMContextProviderProps> = ({
children
}) => {
const [state, setState] = useState<IWASMContext>(initial)
// This has to run only once: https://github.com/rustwasm/wasm-bindgen/issues/3153
// Though, in development React renders twice when Strict Mode is enabled: https://reactjs.org/docs/strict-mode.html
// That's why it must be limited to a single mount run
useMountEffectOnce(() => {
(async() => {
const wasm = await import("utfdump_wasm");
await wasm.default();
setState({ wasm });
})()
})
}, []);
return (
<WASMContext.Provider value={state}>
{children}
</WASMContext.Provider>
)
}
interface IWASMContext {
wasm?: typeof import('utfdump_wasm')
}
interface WASMContextProviderProps {
children: ReactNode
<UtfdumpContext.Provider value={contextValue}>
{props.children}
</UtfdumpContext.Provider>
);
}