// Embedded mode: the host shell has authenticated the user, picked a // robot, and started a streaming session before this module runs. The // on-screen puppet mirrors the real robot (motion only — audio plays on // the robot's speaker). import "./app/styles.css"; import { connectToHost } from "@pollen-robotics/reachy-mini-sdk/host/embed"; import { safelyReturnToPose } from "@pollen-robotics/reachy-mini-sdk/animation"; import { bootApp } from "./app/boot"; import { makeEmotionSource, makeSoundSource } from "./emotions/sources"; import { MultiplexAdapter } from "./robot/multiplex"; import { RealRobotAdapter, type RealRobotSdk } from "./robot/real"; import { VirtualRobotAdapter } from "./robot/virtual"; async function main(): Promise { const handle = await connectToHost(); const reachy = handle.reachy as unknown as RealRobotSdk; const app = bootApp(document.getElementById("root")!, { theme: handle.theme, emotions: makeEmotionSource(), sounds: makeSoundSource(), attachRobot: (puppetHost, log) => new MultiplexAdapter( [new VirtualRobotAdapter(puppetHost, undefined, { muteAudio: true }), new RealRobotAdapter(reachy)], log, ), }); handle.onThemeChange((theme) => app.setTheme(theme)); handle.onLeave(() => { // Kick the runner's abort (cancels moves/audio, runs its own safe // cleanup) but don't hold the host's leave budget on its sleeps — // the canonical safe-return below dispatches synchronously and the // daemon interpolates on its own clock after the iframe is gone. void app.runner.stop(); safelyReturnToPose(handle.reachy); }); } void main().catch((err: unknown) => { console.error("[reachy-blocks] embed boot failed", err); window.parent.postMessage( { source: "reachy-mini", type: "embed:error", version: 1, message: err instanceof Error ? err.message : String(err), fatal: true, }, window.location.origin, ); });