import * as powCaptcha from "@pow-captcha/pow-captcha"; import { useCallback, useState } from "react"; import type { Route } from "./+types/App"; export async function loader({ params }: Route.LoaderArgs) { const challenge = await powCaptcha.server.createChallengesRaw({ difficultyBits: 19, challengeCount: 64, }); return { challenge }; } export default function App({ loaderData: { challenge }, }: Route.ComponentProps) { const [durationJs, setDurationJs] = useState(null); const [durationWasm, setDurationWasm] = useState(null); const run = useCallback( async ( engine: "wasm" | "js", setter: React.Dispatch>, ) => { try { setter(`Running`); const challenges = challenge.challenges.map( (challenge) => [ powCaptcha.wire.deserializeArray(challenge[0]), powCaptcha.wire.deserializeArray(challenge[1]), ] as const, ); const start = performance.now(); await powCaptcha.solver.solveChallenges({ difficultyBits: challenge.difficultyBits, challenges, engine, }); const duration = performance.now() - start; setter(`${duration.toFixed(1)}ms`); } catch (err) { setter(`Error: ${err}`); } }, [challenge], ); const runJs = useCallback(async () => { await run("js", setDurationJs); }, [run]); const runWasm = useCallback(async () => { await run("wasm", setDurationWasm); }, [run]); return (

pow-captcha Benchmark

Results:
type duration
wasm {durationWasm}
js {durationJs}
); }