168 lines
4.9 KiB
TypeScript
168 lines
4.9 KiB
TypeScript
import type {
|
|
CreatePuzzleAgentSessionRequest,
|
|
PuzzleAgentSessionSnapshot,
|
|
} from '../../../packages/shared/src/contracts/puzzleAgentSession';
|
|
import {
|
|
createMiniGameDraftGenerationState,
|
|
type MiniGameDraftGenerationKind,
|
|
type MiniGameDraftGenerationPhase,
|
|
type MiniGameDraftGenerationState,
|
|
resolveMiniGameDraftGenerationStartedAtMs,
|
|
} from '../../services/miniGameDraftGenerationProgress';
|
|
|
|
export function createMiniGameDraftGenerationStateForRestoredDraft(
|
|
kind: MiniGameDraftGenerationKind,
|
|
metadata?: MiniGameDraftGenerationState['metadata'],
|
|
startedAtMs = Date.now(),
|
|
): MiniGameDraftGenerationState {
|
|
return {
|
|
...createMiniGameDraftGenerationState(kind, startedAtMs),
|
|
...(metadata ? { metadata } : {}),
|
|
};
|
|
}
|
|
|
|
export function createFailedMiniGameDraftGenerationStateForRestoredDraft(
|
|
kind: MiniGameDraftGenerationKind,
|
|
updatedAt: string | null | undefined,
|
|
error: string,
|
|
metadata?: MiniGameDraftGenerationState['metadata'],
|
|
): MiniGameDraftGenerationState {
|
|
return resolveFinishedMiniGameDraftGenerationState(
|
|
createMiniGameDraftGenerationStateForRestoredDraft(
|
|
kind,
|
|
metadata,
|
|
resolveMiniGameDraftGenerationStartedAtMs(updatedAt),
|
|
),
|
|
'failed',
|
|
{ error },
|
|
);
|
|
}
|
|
|
|
/** 清理生成态完成时间,避免返回生成页后继续沿用结束态计时。 */
|
|
export function rebaseMiniGameDraftGenerationStateForDisplay(
|
|
state: MiniGameDraftGenerationState,
|
|
): MiniGameDraftGenerationState {
|
|
return {
|
|
...state,
|
|
finishedAtMs: undefined,
|
|
};
|
|
}
|
|
|
|
export function rebaseMiniGameDraftBackgroundCompileTaskForDisplay<
|
|
T extends { generationState: MiniGameDraftGenerationState },
|
|
>(task: T): T {
|
|
return {
|
|
...task,
|
|
generationState: rebaseMiniGameDraftGenerationStateForDisplay(
|
|
task.generationState,
|
|
),
|
|
};
|
|
}
|
|
|
|
export function createPuzzleDraftGenerationStateFromPayload(
|
|
payload: CreatePuzzleAgentSessionRequest | null | undefined,
|
|
session: PuzzleAgentSessionSnapshot | null | undefined = null,
|
|
): MiniGameDraftGenerationState {
|
|
const puzzleProgressPercent =
|
|
session?.draft && !session.draft.formDraft
|
|
? session.progressPercent
|
|
: undefined;
|
|
|
|
return {
|
|
...createMiniGameDraftGenerationState(
|
|
'puzzle',
|
|
resolveMiniGameDraftGenerationStartedAtMs(session?.updatedAt),
|
|
),
|
|
metadata: {
|
|
puzzleAiRedraw: payload?.aiRedraw ?? true,
|
|
puzzleActivePhaseId:
|
|
typeof puzzleProgressPercent === 'number' ? 'compile' : undefined,
|
|
puzzleActiveStepStartedAtMs:
|
|
typeof puzzleProgressPercent === 'number' ? Date.now() : undefined,
|
|
puzzleProgressPercent,
|
|
},
|
|
};
|
|
}
|
|
|
|
export function resolvePuzzlePhaseFromSessionProgress(
|
|
state: MiniGameDraftGenerationState,
|
|
session: PuzzleAgentSessionSnapshot,
|
|
): MiniGameDraftGenerationPhase {
|
|
if (session.progressPercent >= 96) {
|
|
return 'puzzle-select-image';
|
|
}
|
|
if (session.progressPercent >= 94) {
|
|
return 'puzzle-ui-assets';
|
|
}
|
|
if (session.progressPercent >= 88) {
|
|
return state.metadata?.puzzleAiRedraw === false
|
|
? 'puzzle-level-scene'
|
|
: 'puzzle-cover-image';
|
|
}
|
|
|
|
return 'compile';
|
|
}
|
|
|
|
export function mergePuzzleSessionProgressIntoGenerationState(
|
|
state: MiniGameDraftGenerationState,
|
|
session: PuzzleAgentSessionSnapshot,
|
|
): MiniGameDraftGenerationState {
|
|
const isCompiledGenerationSession = Boolean(
|
|
session.draft && !session.draft.formDraft,
|
|
);
|
|
|
|
const nextPhaseId = isCompiledGenerationSession
|
|
? resolvePuzzlePhaseFromSessionProgress(state, session)
|
|
: state.metadata?.puzzleActivePhaseId;
|
|
const shouldResetActiveStepStart =
|
|
isCompiledGenerationSession &&
|
|
nextPhaseId != null &&
|
|
nextPhaseId !== state.metadata?.puzzleActivePhaseId;
|
|
|
|
return {
|
|
...state,
|
|
metadata: {
|
|
...state.metadata,
|
|
puzzleActivePhaseId: nextPhaseId,
|
|
puzzleActiveStepStartedAtMs: shouldResetActiveStepStart
|
|
? resolveMiniGameDraftGenerationStartedAtMs(session.updatedAt)
|
|
: state.metadata?.puzzleActiveStepStartedAtMs,
|
|
puzzleProgressPercent: isCompiledGenerationSession
|
|
? session.progressPercent
|
|
: state.metadata?.puzzleProgressPercent,
|
|
},
|
|
};
|
|
}
|
|
|
|
export function resolveFinishedMiniGameDraftGenerationState(
|
|
state: MiniGameDraftGenerationState,
|
|
phase: 'ready' | 'failed',
|
|
options: {
|
|
error?: string | null;
|
|
completedAssetCount?: number;
|
|
totalAssetCount?: number;
|
|
} = {},
|
|
): MiniGameDraftGenerationState {
|
|
return {
|
|
...state,
|
|
phase,
|
|
finishedAtMs: Date.now(),
|
|
error: options.error ?? state.error,
|
|
completedAssetCount:
|
|
options.completedAssetCount ?? state.completedAssetCount,
|
|
totalAssetCount: options.totalAssetCount ?? state.totalAssetCount,
|
|
};
|
|
}
|
|
|
|
export function isMiniGameDraftReady(
|
|
state: MiniGameDraftGenerationState | null,
|
|
) {
|
|
return state?.phase === 'ready';
|
|
}
|
|
|
|
export function isMiniGameDraftGenerating(
|
|
state: MiniGameDraftGenerationState | null,
|
|
) {
|
|
return Boolean(state && state.phase !== 'ready' && state.phase !== 'failed');
|
|
}
|