import { useCallback, useRef, useState } from 'react'; import type { Match3DClickItemRequest, Match3DRunSnapshot, } from '../packages/shared/src/contracts/match3dRuntime'; import { Match3DRuntimeShell } from './components/match3d-runtime'; import { createLocalMatch3DRuntimeAdapter, type Match3DRuntimeAdapter, startLocalMatch3DRun, } from './services/match3d-runtime'; type LocalMatch3DRuntimeSession = { adapter: Match3DRuntimeAdapter; initialRun: Match3DRunSnapshot; }; function resolveClearCountParam() { const params = new URLSearchParams(window.location.search); const clearCountParam = params.get('clearCount') ?? params.get('count'); const clearCount = clearCountParam === null ? 12 : Number.parseInt(clearCountParam, 10); return Number.isFinite(clearCount) && clearCount > 0 ? clearCount : 12; } function buildInitialRuntimeSession(): LocalMatch3DRuntimeSession { const initialRun = startLocalMatch3DRun(resolveClearCountParam()); return { adapter: createLocalMatch3DRuntimeAdapter({ initialRun }), initialRun, }; } export default function Match3DPlaygroundApp() { const runtimeSessionRef = useRef(buildInitialRuntimeSession()); const [run, setRun] = useState( runtimeSessionRef.current.initialRun, ); const syncRun = useCallback((nextRun: Match3DRunSnapshot) => { setRun(nextRun); }, []); const handleClickItem = useCallback(async (payload: Match3DClickItemRequest) => { const runId = payload.runId ?? runtimeSessionRef.current.initialRun.runId; const result = await runtimeSessionRef.current.adapter.clickItem(runId, payload); setRun(result.run); return result; }, []); const handleRestart = useCallback(() => { void runtimeSessionRef.current.adapter.restartRun(run.runId).then(({ run }) => { setRun(run); }); }, [run.runId]); const handleExit = useCallback(() => { window.location.assign('/'); }, []); const handleTimeExpired = useCallback(() => { void runtimeSessionRef.current.adapter.finishTimeUp(run.runId).then(({ run }) => { setRun(run); }); }, [run.runId]); return ( ); }