working wasm
This commit is contained in:
1 parent
2689d1512e
commit
d37745c1b9
8 files changed
+122
-42
No files matched your search
+4
-2
@@ -1,4 +1,6 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {}
|
const nextConfig = {
|
||||||
|
reactStrictMode: true,
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = nextConfig
|
module.exports = nextConfig;
|
||||||
Generated
+12
-1
@@ -16,7 +16,8 @@
|
|||||||
"next": "13.4.5",
|
"next": "13.4.5",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"typescript": "5.1.3"
|
"typescript": "5.1.3",
|
||||||
|
"utfdump_wasm": "file:pkg"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
@@ -3541,6 +3542,10 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/utfdump_wasm": {
|
||||||
|
"resolved": "pkg",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/watchpack": {
|
"node_modules/watchpack": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
||||||
@@ -3651,6 +3656,9 @@
|
|||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"pkg": {
|
||||||
|
"version": "0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -6031,6 +6039,9 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"utfdump_wasm": {
|
||||||
|
"version": "file:pkg"
|
||||||
|
},
|
||||||
"watchpack": {
|
"watchpack": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
||||||
|
|||||||
+2
-1
@@ -17,6 +17,7 @@
|
|||||||
"next": "13.4.5",
|
"next": "13.4.5",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "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
-1
@@ -1,6 +1,6 @@
|
|||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import styles from './page.module.css'
|
import styles from './page.module.css'
|
||||||
import { Inspector } from './inspector';
|
import { Inspector } from '@/components/inspector';
|
||||||
|
|
||||||
const sourceUrl = 'https://example.com';
|
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';
|
'use client';
|
||||||
|
|
||||||
import styles from './page.module.css'
|
import styles from '@/app/page.module.css'
|
||||||
|
|
||||||
type TextFieldProps = {
|
type TextFieldProps = {
|
||||||
onChange: (value: string) => void,
|
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
|
||||||
|
}
|
||||||
Reference in new issue
Block a user