Spaces:
Sleeping
Sleeping
| /** | |
| * App-wide structural types. Kept narrow on purpose: the SDK is the | |
| * source of truth for robot state, and views only need a small slice | |
| * (poses, motion frames, the saved-move record). | |
| */ | |
| /** Row-major flat-16 head matrix. The SDK's wire shape. */ | |
| export type FlatHead = number[]; | |
| /** Nested 4x4 head matrix. The app's internal shape (see motor.ts). */ | |
| export type NestedHead = number[][]; | |
| /** [left, right] antenna angles in radians. */ | |
| export type Antennas = [number, number]; | |
| /** | |
| * A single recorded actuator frame. Stored in nested + camelCase shape; | |
| * the SDK boundary (motor.ts) converts to/from the flat wire form. | |
| */ | |
| export interface MotionFrame { | |
| head: NestedHead | null; | |
| antennas: Antennas | null; | |
| body_yaw: number; | |
| check_collision: boolean; | |
| } | |
| /** | |
| * A full recorded motion. The Python Marionette + downstream tooling | |
| * expects this exact shape on disk (snake_case `set_target_data`), so | |
| * we keep it 1:1 with the v1 schema even though we're now in TS. | |
| */ | |
| export interface Motion { | |
| time: number[]; | |
| set_target_data: MotionFrame[]; | |
| duration?: number; | |
| frameCount?: number; | |
| capturedHz?: number; | |
| } | |
| /** | |
| * Audio source attached to a move. `silent` means the move records | |
| * pure motion with no audio reference. | |
| */ | |
| export type AudioMode = "silent" | "upload" | "record_now" | "record_live"; | |
| /** Where audio playback should land. Mirrors v1's settings.audioOutput. */ | |
| export type AudioOutput = "robot" | "device"; | |
| /** Where the recording mic should pull from. Mirrors v1's state.audioMic. */ | |
| export type AudioMic = "device" | "robot"; | |
| /** | |
| * Persisted move row in IndexedDB. Kept flat on purpose (no folders | |
| * in the MVP) - community provenance is carried inline so we can | |
| * show a "from @author" chip on the row. | |
| */ | |
| export interface MoveRecord { | |
| id: string; | |
| label: string; | |
| emoji: string; | |
| motion: Motion; | |
| audioBlob: Blob | null; | |
| audioMode: AudioMode; | |
| duration: number; | |
| createdAt: number; | |
| // βββ Community provenance βββββββββββββββββββββββββββββββββββββ | |
| /** Set on community-imported moves, never on user-recorded ones. */ | |
| communityAuthor?: string; | |
| /** Original HF dataset id (`org/name`). */ | |
| communityRepoId?: string; | |
| /** File path inside the repo, e.g. `data/wave.json`. Used as the | |
| * idempotency key when an import targets a move already present. */ | |
| communityMovePath?: string; | |
| /** Free-form description from the dataset's JSON, if any. */ | |
| description?: string; | |
| // βββ Share-to-HF state ββββββββββββββββββββββββββββββββββββββββ | |
| /** True once the user has pushed this move to their own dataset. */ | |
| shared?: boolean; | |
| /** HF repo the move was last shared to (`<owner>/<repo>`). */ | |
| sharedRepoId?: string; | |
| } | |
| /** | |
| * One Marionette community dataset as listed by HF | |
| * (`?filter=reachy_mini_community_moves`). | |
| */ | |
| export interface CommunityDatasetSummary { | |
| /** `org/name` - the canonical HF repo id. */ | |
| repoId: string; | |
| /** Display name (last path segment of `repoId`). */ | |
| name: string; | |
| /** First path segment of `repoId`. */ | |
| author: string; | |
| emoji: string; | |
| downloads: number; | |
| /** ISO timestamp from HF (`lastModified` / `last_modified`). */ | |
| updated: string | null; | |
| /** Lazy field: filled in by `HF.countMoves` after the list arrives. */ | |
| movesCount: number | null; | |
| } | |
| /** | |
| * A single `.json` inside a dataset, paired with a side-by-side | |
| * `.wav` when one exists. | |
| */ | |
| export interface CommunityMoveSummary { | |
| /** Stable id derived from `repoId` + path (used for idempotency). */ | |
| id: string; | |
| /** `data/wave.json` - the path inside the repo. */ | |
| path: string; | |
| /** Display name (filename without extension). */ | |
| label: string; | |
| hasAudio: boolean; | |
| } | |
| /** Persisted user preferences. */ | |
| export interface AppSettings { | |
| audioOutput: AudioOutput; | |
| robotVolume: number; | |
| debug: boolean; | |
| } | |