You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
40 lines
993 B
TypeScript
40 lines
993 B
TypeScript
1 year ago
|
'use client'
|
||
|
|
||
|
import { useEffect, useRef } from "react"
|
||
|
|
||
|
interface Module {
|
||
|
setup?: (wabt?: any) => Promise<undefined>
|
||
|
cleanup?: () => Promise<undefined>
|
||
|
}
|
||
|
|
||
|
export default function PageScript({ script, wasm }: { script?: string, wasm?: Uint8Array }) {
|
||
|
const moduleRef = useRef<Module | null>(null)
|
||
|
|
||
|
useEffect(() => {
|
||
|
if (!script) return undefined
|
||
|
|
||
|
import(/* webpackIgnore: true */ script)
|
||
|
.then(scriptModule => {
|
||
|
if (!wasm) return [scriptModule]
|
||
|
|
||
|
return WebAssembly.instantiate(Uint8Array.from(wasm)).then(({ instance }) => [scriptModule, instance])
|
||
|
})
|
||
|
.then(([scriptModule, wasmModule]) => {
|
||
|
moduleRef.current = scriptModule
|
||
|
|
||
|
if (scriptModule.setup && typeof scriptModule.setup === 'function')
|
||
|
scriptModule.setup(wasmModule)
|
||
|
})
|
||
|
|
||
|
return () => {
|
||
|
const mod = moduleRef.current
|
||
|
|
||
|
if (mod?.cleanup && typeof mod.cleanup === 'function') {
|
||
|
mod.cleanup()
|
||
|
}
|
||
|
}
|
||
|
}, [])
|
||
|
|
||
|
return null
|
||
|
}
|