import { Default, handler, NAME, pattern, type PerSpace, type PerUser, Stream, UI, type VNode, Writable, } from "commonfabric"; /** * Convergence-storm fixture — the structural skeleton of * `profile-group-chat/main.tsx` with the profile wish removed, for the * multi-runtime convergence tests (convergence-storm.test.ts). * * Keeps exactly the pieces the multiplayer pathology needs: * - a `PerSpace` message array every session appends to (the contended doc); * - message objects that carry a live `Cell` link (`authorProfile`), so each * pushed element is hoisted into its own entity — the durable docs another * session discovers via link and must materialize (the wedge reads these * at seq 0); * - a shared computed over the whole list (`authors`), materialized as a * space-scoped result doc whose commit carries reads of the message docs * (the poison-carrier class); * - a `PerUser` profile cell standing in for the wish result. */ export interface StormProfile { name?: string; } export interface StormMessage { author: string; body: string; n: number; } const DEFAULT_MESSAGES: StormMessage[] = []; const DEFAULT_PROFILE: StormProfile = { name: "" }; export interface PostEvent { author?: string; body?: string; n?: number; } const post = handler; }>((event, { messages }) => { messages.push({ author: event?.author ?? "", body: event?.body ?? "", n: event?.n ?? 0, }); }); export interface ConvergenceChatInput { messages?: PerSpace>; profile?: PerUser>; } export interface ConvergenceChatOutput { [NAME]: string; [UI]: VNode; messages: PerSpace>; profile: PerUser>; post: Stream; } export default pattern( ({ messages, profile }) => { return { [NAME]: "Convergence storm fixture", [UI]: (
convergence fixture (no derived readers)
), messages, profile, post: post({ messages }), }; }, );