auto wasm compilation
This commit is contained in:
1 parent
78796489ca
commit
586e1d9e2c
6 files changed
+240
-52
No files matched your search
@@ -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
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user