/** A project's released copy as the release dialog shows it (#266). */ export interface ReleaseSummary { /** What the link carries: 32 hex digits, the same for as long as the project stays released. */ token: string; /** The project revision the copy was taken from. */ revision: number; /** ISO time, UTC. */ publishedAt: string; } /** What the play page loads: the copy alone, under the token rather than the project's own id. */ export interface ReleasedGame { name: string; publishedAt: string; project: unknown; } /** * The released copy of a project. Publishing copies the project as the server stored it, so what a * tab has not saved yet is not part of it; publishing again replaces the copy and keeps the link. */ export interface ReleaseStore { /** null while the project is not released. */ of(projectId: string): Promise; publish(projectId: string): Promise; takeDown(projectId: string): Promise; } /** The page a released game is played on, next to the editor's own. */ export const PLAY_PAGE = '/game-maker/play.html'; export function releaseUrl(origin: string, token: string): string { return `${origin}${PLAY_PAGE}?game=${token}`; } /** The token a play page was opened with, or null when the address carries none that could be one. */ export function releaseToken(search: string): string | null { const token = new URLSearchParams(search).get('game') ?? ''; return /^[a-f0-9]{32}$/.test(token) ? token : null; }