import type { DropSquareHoleShapeRequest, SquareHoleDropResponse, SquareHoleRunResponse, StopSquareHoleRunRequest, } from '../../../packages/shared/src/contracts/squareHoleRuntime'; import { type ApiRetryOptions, } from '../apiClient'; import { type RuntimeGuestRequestOptions } from '../runtimeGuestAuth'; import { buildRuntimeApiPath, requestRuntimeJson } from '../runtimeRequest'; const SQUARE_HOLE_RUNTIME_API_BASE = '/api/runtime/square-hole'; const SQUARE_HOLE_RUNTIME_READ_RETRY: ApiRetryOptions = { maxRetries: 1, baseDelayMs: 120, maxDelayMs: 360, }; const SQUARE_HOLE_RUNTIME_WRITE_RETRY: ApiRetryOptions = { maxRetries: 1, baseDelayMs: 120, maxDelayMs: 360, retryUnsafeMethods: true, }; type SquareHoleRuntimeRequestOptions = RuntimeGuestRequestOptions; /** * 基于作品启动一局方洞挑战正式 run。 */ export function startSquareHoleRun( profileId: string, options: SquareHoleRuntimeRequestOptions = {}, ) { return requestRuntimeJson({ url: buildRuntimeApiPath( SQUARE_HOLE_RUNTIME_API_BASE, 'works', profileId, 'runs', ), method: 'POST', jsonBody: { profileId }, fallbackMessage: '启动方洞挑战失败', retry: SQUARE_HOLE_RUNTIME_WRITE_RETRY, requestOptions: options, }); } /** * 读取方洞挑战运行态快照。 */ export function getSquareHoleRun( runId: string, options: SquareHoleRuntimeRequestOptions = {}, ) { return requestRuntimeJson({ url: buildRuntimeApiPath(SQUARE_HOLE_RUNTIME_API_BASE, 'runs', runId), fallbackMessage: '读取方洞挑战运行快照失败', retry: SQUARE_HOLE_RUNTIME_READ_RETRY, requestOptions: options, }); } /** * 提交一次洞口选择,由后端做权威确认。 */ export function dropSquareHoleShape( runId: string, payload: DropSquareHoleShapeRequest, options: SquareHoleRuntimeRequestOptions = {}, ) { return requestRuntimeJson({ url: buildRuntimeApiPath( SQUARE_HOLE_RUNTIME_API_BASE, 'runs', runId, 'drop', ), method: 'POST', jsonBody: { ...payload, runId: payload.runId ?? runId, }, fallbackMessage: '确认方洞挑战投入失败', retry: SQUARE_HOLE_RUNTIME_WRITE_RETRY, requestOptions: options, }); } /** * 停止当前方洞挑战运行态。 */ export function stopSquareHoleRun( runId: string, payload: StopSquareHoleRunRequest = { clientActionId: `square-hole-stop-${Date.now()}`, }, options: SquareHoleRuntimeRequestOptions = {}, ) { return requestRuntimeJson({ url: buildRuntimeApiPath(SQUARE_HOLE_RUNTIME_API_BASE, 'runs', runId, 'stop'), method: 'POST', jsonBody: payload, fallbackMessage: '停止方洞挑战失败', retry: SQUARE_HOLE_RUNTIME_WRITE_RETRY, requestOptions: options, }); } /** * 基于当前 run 重开一局。 */ export function restartSquareHoleRun( runId: string, options: SquareHoleRuntimeRequestOptions = {}, ) { return requestRuntimeJson({ url: buildRuntimeApiPath( SQUARE_HOLE_RUNTIME_API_BASE, 'runs', runId, 'restart', ), method: 'POST', fallbackMessage: '重新开始方洞挑战失败', retry: SQUARE_HOLE_RUNTIME_WRITE_RETRY, requestOptions: options, }); } /** * 前端倒计时归零后通知后端确认失败状态。 */ export function finishSquareHoleTimeUp( runId: string, options: SquareHoleRuntimeRequestOptions = {}, ) { return requestRuntimeJson({ url: buildRuntimeApiPath( SQUARE_HOLE_RUNTIME_API_BASE, 'runs', runId, 'time-up', ), method: 'POST', fallbackMessage: '同步方洞挑战倒计时失败', retry: SQUARE_HOLE_RUNTIME_WRITE_RETRY, requestOptions: options, }); } export const squareHoleRuntimeClient = { dropShape: dropSquareHoleShape, finishTimeUp: finishSquareHoleTimeUp, getRun: getSquareHoleRun, restartRun: restartSquareHoleRun, startRun: startSquareHoleRun, stopRun: stopSquareHoleRun, };