import * as Chat from "../chat/service"; import * as Comments from "../comments/service"; import * as Service from "../plan/service"; import * as Questions from "../questions/service"; import { tell } from "../wire"; import type { Plan as Wire, Request } from "@chopin/protocol"; import type { Socket } from "../wire"; import type { Room } from "../rooms"; type OpeningRoom
= { plan?: P; opening?: Promise
}; /** Complete all setup before exposing a plan to concurrent socket frames. */ export async function publishOpenedPlan
( room: OpeningRoom
,
opened: P,
prepare: () => Promise {
await prepare();
room.plan = opened;
return opened;
}
/** Preparation owns an unpublished document until close intent has been checked. */
export async function prepareOpenedPlan(
room: Room,
opened: Service.Plan,
prepare: () => Promise (room: OpeningRoom ): Promise {
if (room.opening) await room.opening;
return room.plan;
}
/** An archive that failed early still has to observe a concurrent first open. */
export async function recoverOpenedPlan (
room: OpeningRoom | undefined,
): Promise {
if (!room) return undefined;
if (!room.plan) {
try {
await room.opening;
} catch {
// A failed open left no plan or job coordinator to reattach.
}
}
return room.plan;
}
/** Read the transcript and prototype together after all earlier commits settle. */
export function greetJoinedPlan(
opened: Service.Plan,
ws: Socket,
frame: Request (
room: OpeningRoom | undefined,
): Promise {
if (room?.opening) {
try {
await room.opening;
} catch {
// A failed first open must not replace the archive outcome.
}
}
return recoverOpenedPlan(room);
}