reachy-blocks / src /embed.ts
Claude
feat: RealRobotAdapter, multiplex fan-out, full embed wiring
aa2dcd1 unverified
Raw
History Blame Contribute Delete
1.99 kB
// 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<void> {
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,
);
});