working wasm

main
pantonshire 3 years ago
parent 2689d1512e
commit d37745c1b9

@ -1,4 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {}
const nextConfig = {
reactStrictMode: true,
};
module.exports = nextConfig
module.exports = nextConfig;

13
package-lock.json generated

@ -16,7 +16,8 @@
"next": "13.4.5",
"react": "18.2.0",
"react-dom": "18.2.0",
"typescript": "5.1.3"
"typescript": "5.1.3",
"utfdump_wasm": "file:pkg"
}
},
"node_modules/@babel/runtime": {
@ -3541,6 +3542,10 @@
"punycode": "^2.1.0"
}
},
"node_modules/utfdump_wasm": {
"resolved": "pkg",
"link": true
},
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
@ -3651,6 +3656,9 @@
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"pkg": {
"version": "0.1.0"
}
},
"dependencies": {
@ -6031,6 +6039,9 @@
"punycode": "^2.1.0"
}
},
"utfdump_wasm": {
"version": "file:pkg"
},
"watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",

@ -17,6 +17,7 @@
"next": "13.4.5",
"react": "18.2.0",
"react-dom": "18.2.0",
"typescript": "5.1.3"
"typescript": "5.1.3",
"utfdump_wasm": "file:pkg"
}
}

@ -1,36 +0,0 @@
'use client';
import { useState } from 'react';
import styles from './page.module.css'
import { TextField } from './textfield';
type InspectorProps = {
sourceUrl: string,
};
export function Inspector(props: InspectorProps) {
const [currentString, setCurrentString] = useState('');
return (
<section className={styles.inspector_section}>
<section className={styles.input_section}>
<TextField
onChange={setCurrentString}
placeholder='Enter Unicode text here'
/>
<div className={styles.info_box}>
<p>
Source code is available
<a href={props.sourceUrl}>here</a>.
Text entered above is not sent over the network.
</p>
</div>
</section>
<section className={styles.output_section}>
<p id='out_test'>{currentString}</p>
</section>
</section>
)
}

@ -1,6 +1,6 @@
import Image from 'next/image'
import styles from './page.module.css'
import { Inspector } from './inspector';
import { Inspector } from '@/components/inspector';
const sourceUrl = 'https://example.com';

@ -0,0 +1,53 @@
'use client';
import { useContext, useState } from 'react';
import styles from '@/app/page.module.css'
import { TextField } from './textfield';
import { WASMContext, WASMContextProvider } from '@/context/utfdump';
type InspectorProps = {
sourceUrl: string,
};
export function Inspector(props: InspectorProps) {
const [currentString, setCurrentString] = useState('');
return (
<WASMContextProvider>
<section className={styles.inspector_section}>
<section className={styles.input_section}>
<TextField
onChange={setCurrentString}
placeholder='Enter Unicode text here'
/>
<div className={styles.info_box}>
<p>
Source code is available <a href={props.sourceUrl}>here</a>.
Text entered above is not sent over the network.
</p>
</div>
</section>
<Out currentString={currentString} />
</section>
</WASMContextProvider>
);
}
function Out(props: { currentString: string }) {
const ctx = useContext(WASMContext);
if (!ctx.wasm) {
return (
<p>Loading WASM...</p>
);
}
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>
</section>
);
}

@ -1,6 +1,6 @@
'use client';
import styles from './page.module.css'
import styles from '@/app/page.module.css'
type TextFieldProps = {
onChange: (value: string) => void,

@ -0,0 +1,49 @@
// using solution from https://github.com/satelllte/nextjs-wasm for now
import { useState, createContext, useEffect, useRef } from 'react'
import type { ReactNode } from 'react'
const initial: IWASMContext = {}
const useMountEffectOnce = (fn: () => void) => {
const wasExecutedRef = useRef(false)
useEffect(() => {
if (!wasExecutedRef.current) {
fn()
}
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
}
Loading…
Cancel
Save