feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
/**
|
|
|
|
|
* proBoardRegistry — runtime registration seam for boards a private overlay
|
|
|
|
|
* (velxio.com) ships outside the OSS tree.
|
|
|
|
|
*
|
|
|
|
|
* The OSS BoardKind union and its compiler-enforced Record maps stay exactly
|
|
|
|
|
* as they are for the open boards. An overlay calls registerProBoards() at
|
|
|
|
|
* mount with data-only definitions; registration patches the exported maps in
|
|
|
|
|
* types/board.ts (labels / FQBN / MicroPython set) so every existing read site
|
|
|
|
|
* keeps working untouched, and the handful of sites a map can't cover (canvas
|
|
|
|
|
* render, pin-name mapping, simulator construction, firmware load) consult
|
|
|
|
|
* getProBoard() as a fallback.
|
|
|
|
|
*
|
|
|
|
|
* The OSS build never registers anything here — like the proRoutes /
|
|
|
|
|
* __velxio_pro_gate__ / registerComponentDoc seams, this module is dead code
|
|
|
|
|
* until an overlay imports it. Board ad cards (ONLINE_ONLY_BOARD_ADS) hide
|
|
|
|
|
* automatically for registered kinds: the picker filter checks
|
|
|
|
|
* `ad.id in BOARD_KIND_LABELS`, and registration inserts the label.
|
|
|
|
|
*/
|
|
|
|
|
import type React from 'react';
|
2026-08-21 00:48:24 +07:00
|
|
|
import type { ESP32BoardOptions } from '../types/boardOptions';
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
import {
|
|
|
|
|
BOARD_KIND_LABELS,
|
|
|
|
|
BOARD_KIND_FQBN,
|
|
|
|
|
BOARD_SUPPORTS_MICROPYTHON,
|
2026-07-28 13:45:56 +07:00
|
|
|
registerPiFamilyKind,
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
type BoardKind,
|
|
|
|
|
} from '../types/board';
|
|
|
|
|
|
|
|
|
|
/** Structural contract for an overlay-provided in-browser board simulator.
|
|
|
|
|
* Mirrors the surface the store already uses on RP2040Simulator — the store
|
|
|
|
|
* only ever duck-types these members for pro simulators. */
|
|
|
|
|
export interface ProBoardSimulator {
|
|
|
|
|
/** Brand flag so the store can recognize overlay simulators without a class. */
|
|
|
|
|
readonly isProBoardSimulator: true;
|
|
|
|
|
onSerialData: ((ch: string) => void) | null;
|
|
|
|
|
onPinChangeWithTime: ((pin: number, state: boolean, time: number) => void) | null;
|
|
|
|
|
stop(): void;
|
|
|
|
|
detachPioPeripheral?(): void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ProBoardDef {
|
|
|
|
|
/** The board id — behaves like a BoardKind everywhere at runtime. */
|
|
|
|
|
kind: string;
|
|
|
|
|
label: string;
|
|
|
|
|
/** arduino-cli FQBN, or null when the board has no backend compile. */
|
|
|
|
|
fqbn: string | null;
|
|
|
|
|
/** One-line picker description. */
|
|
|
|
|
description: string;
|
|
|
|
|
/** The board's custom-element tag. The overlay's import must have run
|
|
|
|
|
* customElements.define for it before the board is placed. */
|
|
|
|
|
tag: string;
|
|
|
|
|
/** True pixel size of the element (selection ring + pin overlays). */
|
|
|
|
|
size: { w: number; h: number };
|
|
|
|
|
supportsMicroPython?: boolean;
|
|
|
|
|
/** ESP32 run-path routing: the base chip the board carries. Routes the run
|
|
|
|
|
* through the ESP32 bridge path and picks the machine/engine type. Omit for
|
|
|
|
|
* boards that provide createSimulator (RP2350 class) or AVR/RP2040. */
|
2026-08-19 09:42:24 +07:00
|
|
|
esp32Family?: 'esp32' | 'esp32-s3' | 'esp32-c3' | 'esp32-c6' | 'esp32-p4' | 'esp32-c5';
|
2026-07-28 13:45:56 +07:00
|
|
|
/** QEMU-Linux run-path routing: route this kind through the Raspberry Pi
|
|
|
|
|
* bridge (backend qemu WebSocket, VFS panel, boot terminal). The overlay
|
|
|
|
|
* must also register a matching backend profile for the kind. */
|
|
|
|
|
piFamily?: boolean;
|
2026-07-28 19:36:13 +07:00
|
|
|
/** One shell line sent to the guest right after it reaches the boot
|
|
|
|
|
* prompt (piFamily boards only). Lets a board de-brand the generic
|
|
|
|
|
* image, e.g. set its own hostname/PS1 and clear the stock motd. */
|
|
|
|
|
guestSetup?: string;
|
2026-07-28 21:28:02 +07:00
|
|
|
/** Home directory of the guest user for the VFS panel and uploads
|
|
|
|
|
* (piFamily boards only; default '/home/pi'). Boards whose guest logs
|
|
|
|
|
* in as root pass '/root'; these also drop the hello.sh sample. */
|
|
|
|
|
guestHome?: string;
|
|
|
|
|
/** Shell command run automatically after boot: the VFS is uploaded and
|
|
|
|
|
* this line executed, so a single click on Run boots, uploads and
|
|
|
|
|
* starts the user's script (piFamily boards only). */
|
|
|
|
|
autoRun?: string;
|
2026-07-29 02:07:21 +07:00
|
|
|
/** Suppress the guest's boot chatter in the terminal (piFamily boards
|
|
|
|
|
* only): the shared rootfs prints another product's banner/motd during
|
|
|
|
|
* boot, before guestSetup can re-brand it. With quietBoot the terminal
|
|
|
|
|
* shows a neutral Velxio boot-progress line instead and reveals the
|
|
|
|
|
* shell right before the auto-run command executes. */
|
|
|
|
|
quietBoot?: boolean;
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
/** Canvas renderer. Receives the placed board's props; return a React node.
|
|
|
|
|
* When omitted, the canvas renders `<tag id=... style=absolute@x,y>`. */
|
|
|
|
|
render?: (props: { id: string; x: number; y: number; running: boolean }) => React.ReactNode;
|
|
|
|
|
/** pinInfo name -> GPIO number (power/ground pins -> -1). Falls back to the
|
|
|
|
|
* generic numeric parse when omitted. Return null for "not mine". */
|
|
|
|
|
pinToNumber?: (pinName: string) => number | null;
|
2026-08-22 10:12:58 +07:00
|
|
|
/**
|
|
|
|
|
* Which pads reach the ADC, and on which channel — the overlay's own version
|
|
|
|
|
* of the OSS ADC_PIN_MAP.
|
|
|
|
|
*
|
|
|
|
|
* That map is keyed by the BoardKind union, which no overlay kind can join,
|
|
|
|
|
* so the SPICE analog path skipped every pro board outright: a divider or an
|
|
|
|
|
* LDR wired to one of these boards solved correctly and then had nowhere to
|
|
|
|
|
* go. Parts that inject directly (a potentiometer through partUtils) were
|
|
|
|
|
* unaffected, which is why this looked like it worked.
|
|
|
|
|
*
|
|
|
|
|
* Names are pad names as they appear in pinInfo. A pad that is analog under a
|
|
|
|
|
* different silk (the Pimoroni Pico Plus 2 W ties GP26/27/28 to the ADC-
|
|
|
|
|
* capable GP40/41/42 through 1k) is declared under the name a wire uses.
|
|
|
|
|
*/
|
|
|
|
|
adcPins?: Array<{ pinName: string; channel: number }>;
|
2026-08-23 08:07:43 +07:00
|
|
|
/**
|
|
|
|
|
* Supply pads and logic voltage, for the SPICE netlist — the overlay's
|
|
|
|
|
* version of BOARD_PIN_GROUPS, which is keyed by the BoardKind union and so
|
|
|
|
|
* can never name a pro board.
|
|
|
|
|
*
|
|
|
|
|
* Without it a board falls back to that table's `default`: 5 V, ground pads
|
|
|
|
|
* called GND/GND.1/GND.2, supply pads called 5V/VCC. For a 3.3 V board with a
|
|
|
|
|
* "3V3" pad that is wrong twice over, and silently — the rail is simply
|
|
|
|
|
* solved at 5 V, so every divider, pull-up and LED current on the board is
|
|
|
|
|
* off by 1.5x.
|
|
|
|
|
*
|
|
|
|
|
* Shape matches BoardPinGroup: { vcc, gnd[], vcc_pins[], aux? }.
|
|
|
|
|
*/
|
|
|
|
|
power?: {
|
|
|
|
|
vcc: number;
|
|
|
|
|
gnd: string[];
|
|
|
|
|
vcc_pins: string[];
|
|
|
|
|
aux?: { volts: number; pins: string[] };
|
|
|
|
|
};
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
/** In-browser simulator factory (e.g. the RP2350/Hazard3 emulator). The pm
|
|
|
|
|
* argument is the store's PinManager instance. */
|
|
|
|
|
createSimulator?: (pm: unknown) => ProBoardSimulator;
|
|
|
|
|
/** Load compiled firmware into a createSimulator() instance at run time —
|
|
|
|
|
* the overlay owns the whole sequence (PIO attach, binary load, demo I2C
|
2026-07-23 02:22:40 +07:00
|
|
|
* devices, ...). `program` is the compiled artifact exactly as the store
|
|
|
|
|
* holds it (base64/hex string, same value RP2040Simulator.loadBinary gets). */
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
loadFirmware?: (
|
|
|
|
|
sim: ProBoardSimulator,
|
2026-07-23 02:22:40 +07:00
|
|
|
program: string,
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
ctx: { boardKind: string; boardId: string },
|
|
|
|
|
) => void;
|
|
|
|
|
/** Built-in bridge sensors registered without wiring (e.g. an on-board I2C
|
|
|
|
|
* keyboard): pushed into the ESP32 bridge's sensor config on every run. */
|
|
|
|
|
builtInSensors?: Array<{ sensor_type: string; pin: number; addr?: number }>;
|
|
|
|
|
/** Built-in microSD on a shared SPI bus: the CS pin the bridge must gate.
|
|
|
|
|
* (A standalone SD card component still overrides this to un-gated.) */
|
|
|
|
|
builtInSdCsPin?: number;
|
2026-08-04 20:57:17 +07:00
|
|
|
/** Board carries an on-board microphone whose bridge implements
|
|
|
|
|
* setMicrophoneSource (I2S RX sample injection): shows the canvas-header
|
|
|
|
|
* Mic toggle that streams the computer's microphone into it. */
|
|
|
|
|
builtInMicrophone?: boolean;
|
2026-08-19 07:50:49 +07:00
|
|
|
/** The board carries a camera fed from the host webcam (CameraToggle in the
|
|
|
|
|
* canvas header; the bridge implements pushCameraFrame). An object form
|
|
|
|
|
* caps the injected JPEG size for drivers with tight frame buffers. */
|
|
|
|
|
builtInCamera?: boolean | { maxFrameBytes?: number };
|
2026-08-12 21:39:37 +07:00
|
|
|
/** Display-controller identity for panel autodetect probes. Vendor
|
|
|
|
|
* libraries (M5GFX and friends) identify a board by reading the panel's
|
|
|
|
|
* RDDID over SPI with the display's own chip-select — and reject the
|
|
|
|
|
* board, or misdetect it as something else entirely, when the answer is
|
|
|
|
|
* the bus's idle 0xFF. A bridge that supports this answers `idByte` on
|
|
|
|
|
* MISO while `csPin` is low. Board DATA, not bridge code: the M5Stack
|
|
|
|
|
* Core is `{ csPin: 14, idByte: 0xE3 }` (ILI9342C), the Cardputer ADV
|
|
|
|
|
* `{ csPin: 37, idByte: 0x85 }` (ST7789V2). */
|
|
|
|
|
spiPanelId?: { csPin: number; idByte: number };
|
2026-08-10 04:48:56 +07:00
|
|
|
/** Board carries an IMU whose bridge implements setImuAcceleration /
|
|
|
|
|
* setImuGyro: shows the canvas-header tilt pad. Without it the emulated
|
|
|
|
|
* part faithfully reports the board lying flat for the whole run. */
|
|
|
|
|
builtInImu?: boolean;
|
|
|
|
|
/** Board reads a battery through its bridge (setBatteryVoltage): shows the
|
|
|
|
|
* canvas-header charge slider, so low-battery code paths can be reached. */
|
|
|
|
|
builtInBattery?: boolean;
|
2026-08-13 02:01:54 +07:00
|
|
|
/** Power-management IC on the internal I2C bus, when the board carries one
|
|
|
|
|
* the vendor library probes. Board DATA like spiPanelId: the bridge that
|
|
|
|
|
* supports the type instantiates the model at the given address, and
|
|
|
|
|
* setBatteryVoltage drives it. The M5Stack Core is
|
|
|
|
|
* { type: 'ip5306', addr: 0x75 }. */
|
|
|
|
|
i2cPmic?: { type: 'ip5306'; addr?: number };
|
2026-07-23 03:33:46 +07:00
|
|
|
/** Built-in peripheral attachment for a RUNNING board (LCD decoder onto the
|
|
|
|
|
* element's own canvas, speaker, on-board button/keyboard event forwarding).
|
|
|
|
|
* Called shortly after run start with the board's DOM element plus its
|
|
|
|
|
* simulator shim and ESP32 bridge (either may be null depending on the run
|
|
|
|
|
* path); must return a cleanup that detaches everything. */
|
|
|
|
|
attachBuiltins?: (ctx: {
|
|
|
|
|
el: HTMLElement;
|
|
|
|
|
sim: unknown;
|
|
|
|
|
bridge: unknown;
|
|
|
|
|
}) => () => void;
|
|
|
|
|
|
2026-08-18 20:01:52 +07:00
|
|
|
/**
|
|
|
|
|
* Seed code a freshly placed board starts with, per language mode.
|
|
|
|
|
*
|
|
|
|
|
* Without this the editor falls back to the family default — the Arduino
|
|
|
|
|
* `LED_BUILTIN` blink, the Pico `Pin(25)` blink, or the Raspberry Pi
|
|
|
|
|
* `RPi.GPIO` script — and NONE of those run on a board that has no such
|
|
|
|
|
* LED, no RPi.GPIO and its own vendor library (an M5Stack needs
|
|
|
|
|
* `M5.begin()`, the UNIHIKER needs pinpong/unihiker). The user's very
|
|
|
|
|
* first Run then fails on a board they have not touched yet. Keep each
|
|
|
|
|
* entry as close to the vendor's own first example as the emulator
|
|
|
|
|
* allows, and self-contained: a freshly placed board has nothing wired
|
|
|
|
|
* to it, so the code must do something visible on the board itself.
|
|
|
|
|
*
|
|
|
|
|
* Keys are the board's language modes plus 'python' for QEMU-Linux
|
|
|
|
|
* (piFamily) boards, whose seed is the guest script.
|
|
|
|
|
*/
|
|
|
|
|
defaultFiles?: Partial<
|
|
|
|
|
Record<'arduino' | 'micropython' | 'espidf' | 'python', Array<{ name: string; content: string }>>
|
|
|
|
|
>;
|
|
|
|
|
/** Library manifest seeded together with `defaultFiles.arduino` — the seed
|
|
|
|
|
* sketch includes the vendor library, so the board must declare it or the
|
|
|
|
|
* first compile resolves against nothing. */
|
|
|
|
|
defaultLibraries?: string[];
|
|
|
|
|
|
2026-08-21 00:48:24 +07:00
|
|
|
/**
|
|
|
|
|
* Build options this board is physically born with, merged over the family
|
|
|
|
|
* defaults whenever the project has not saved its own.
|
|
|
|
|
*
|
|
|
|
|
* A module carries the RAM and flash it carries: the ESP32-S3-EYE always has
|
|
|
|
|
* 8 MB of octal PSRAM, and its camera driver allocates the frame buffer with
|
|
|
|
|
* MALLOC_CAP_SPIRAM. Compiled with the conservative family default
|
|
|
|
|
* (CONFIG_SPIRAM=n) the sketch builds fine and then dies at run time with
|
|
|
|
|
* `cam_dma_config(509): frame buffer malloc failed` — a hardware fact
|
|
|
|
|
* reported as a mysterious driver error. Boards that ship the RAM say so
|
|
|
|
|
* here; everything else keeps sending no options at all.
|
|
|
|
|
*/
|
|
|
|
|
defaultBoardOptions?: Partial<ESP32BoardOptions>;
|
|
|
|
|
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
/** Sidebar / toolbar accents (fall back to a neutral chip icon). */
|
|
|
|
|
icon?: string;
|
|
|
|
|
color?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const registry = new Map<string, ProBoardDef>();
|
|
|
|
|
|
2026-07-23 11:59:46 +07:00
|
|
|
// Registration happens when the overlay's dynamic import lands - potentially
|
|
|
|
|
// AFTER a consumer rendered and memoized its board list. Subscribers re-render
|
|
|
|
|
// on every registration (same contract as proRoutes / registerProExamples).
|
|
|
|
|
let version = 0;
|
|
|
|
|
const listeners = new Set<() => void>();
|
|
|
|
|
|
|
|
|
|
export function subscribeProBoards(cb: () => void): () => void {
|
|
|
|
|
listeners.add(cb);
|
|
|
|
|
return () => listeners.delete(cb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getProBoardsVersion(): number {
|
|
|
|
|
return version;
|
|
|
|
|
}
|
|
|
|
|
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
export function registerProBoards(defs: ProBoardDef[]): void {
|
|
|
|
|
for (const def of defs) {
|
|
|
|
|
registry.set(def.kind, def);
|
|
|
|
|
const kind = def.kind as BoardKind;
|
|
|
|
|
// Patch the exported maps so every existing read site sees the board —
|
|
|
|
|
// labels also make the picker's ONLINE ad for this kind disappear.
|
|
|
|
|
(BOARD_KIND_LABELS as Record<string, string>)[kind] = def.label;
|
|
|
|
|
(BOARD_KIND_FQBN as Record<string, string | null>)[kind] = def.fqbn;
|
|
|
|
|
if (def.supportsMicroPython) BOARD_SUPPORTS_MICROPYTHON.add(kind);
|
2026-07-28 13:45:56 +07:00
|
|
|
if (def.piFamily) registerPiFamilyKind(def.kind);
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
}
|
2026-07-23 11:59:46 +07:00
|
|
|
version++;
|
|
|
|
|
for (const l of listeners) l();
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getProBoard(kind: string): ProBoardDef | undefined {
|
|
|
|
|
return registry.get(kind);
|
|
|
|
|
}
|
|
|
|
|
|
fix(boards): el overlay ya no secuestra el dibujo de las Raspberry Pi
Dos fallos que salieron probando pi-to-arduino-led-control y
pi5-pir-motion-alarm.
1) BoardOnCanvas mira getProBoard() ANTES del switch OSS para decidir si
dibuja un elemento del overlay. El overlay registraba un def minimo
para las seis Pi solo para llevar una linea de setup del guest, y eso
basto para cambiarles el render: en vez de la ilustracion
Raspberry_Pi_3_illustration.svg salia la caja esquematica, con otras
coordenadas de pines, y los cables quedaban colgando en la esquina.
Ahora hay un registro aparte, registerGuestSetup(kind, linea), que
lleva la cadena y nada mas; getGuestSetup() la resuelve dando
prioridad al def del overlay si existe.
2) Las partes de entrada (PIR, botones, sensores) avisan con
simulator.setPinState(pin, nivel). En una placa QEMU-Linux no hay
simulador de MCU -- el CPU es el guest -- asi que la llamada acababa
en la instancia AVR heredada y se perdia: pulsar el sensor no hacia
nada. traceDetailed devuelve ahora tambien la placa a la que llega el
pin, y si es de la familia Pi la parte recibe un simulador que empuja
el nivel al bridge (gpio_in para el guest, el valor pin<N> que leen
los shims del motor de navegador) y al PinManager de esa placa.
2026-07-29 12:34:01 +07:00
|
|
|
// ── Guest setup lines for boards the OSS tree already owns ───────────────
|
|
|
|
|
//
|
|
|
|
|
// A QEMU-Linux board that is NOT overlay-registered (the Raspberry Pi
|
|
|
|
|
// family) may still need a line run at the boot prompt — an overlay can
|
|
|
|
|
// mount something on the guest for it. Registering a whole ProBoardDef
|
|
|
|
|
// just to carry that string is the wrong tool: `getProBoard` is what
|
|
|
|
|
// BoardOnCanvas checks to decide whether to render the overlay's custom
|
|
|
|
|
// element instead of the OSS board art, so a stub def silently replaced
|
|
|
|
|
// the Pi's illustration with a bare schematic box and left the wires
|
|
|
|
|
// hanging at the corner. This registry carries the line and nothing else.
|
|
|
|
|
const guestSetups = new Map<string, string>();
|
|
|
|
|
|
|
|
|
|
export function registerGuestSetup(kind: string, line: string): void {
|
|
|
|
|
guestSetups.set(kind, line);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** The line to run at the guest's boot prompt: an overlay board's own
|
|
|
|
|
* `guestSetup` first, then anything registered for an OSS board kind. */
|
|
|
|
|
export function getGuestSetup(kind: string): string | undefined {
|
|
|
|
|
return registry.get(kind)?.guestSetup ?? guestSetups.get(kind);
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-30 06:09:04 +07:00
|
|
|
// ── Built-in peripheral attachment for boards the OSS tree already owns ──
|
|
|
|
|
//
|
|
|
|
|
// Same reasoning as the guest setups above: an overlay may need to wire
|
|
|
|
|
// something to a run of an OSS-rendered board — the Pi family has no
|
|
|
|
|
// built-in screen, but an overlay can route the guest's display frames to
|
|
|
|
|
// a panel wired on the canvas. Carrying that through a stub ProBoardDef
|
|
|
|
|
// would take over the board's artwork, so it gets its own registry.
|
|
|
|
|
type BuiltinsAttach = (ctx: {
|
|
|
|
|
el: HTMLElement;
|
|
|
|
|
sim: unknown;
|
|
|
|
|
bridge: unknown;
|
|
|
|
|
}) => () => void;
|
|
|
|
|
|
|
|
|
|
const boardBuiltins = new Map<string, BuiltinsAttach>();
|
|
|
|
|
|
|
|
|
|
export function registerBoardBuiltins(kind: string, attach: BuiltinsAttach): void {
|
|
|
|
|
boardBuiltins.set(kind, attach);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** How to attach built-in peripherals for a board kind: an overlay board's
|
|
|
|
|
* own `attachBuiltins` first, then anything registered for an OSS kind. */
|
|
|
|
|
export function getBoardBuiltins(kind: string): BuiltinsAttach | undefined {
|
|
|
|
|
return registry.get(kind)?.attachBuiltins ?? boardBuiltins.get(kind);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-18 20:01:52 +07:00
|
|
|
/**
|
|
|
|
|
* Seed files for a board kind in a given language mode, or undefined when the
|
|
|
|
|
* board carries no seed of its own (the editor's family default applies).
|
|
|
|
|
* `mode` is 'python' for QEMU-Linux boards — see ProBoardDef.defaultFiles.
|
|
|
|
|
*/
|
|
|
|
|
export function getBoardSeedFiles(
|
|
|
|
|
kind: string,
|
|
|
|
|
mode: 'arduino' | 'micropython' | 'espidf' | 'python',
|
|
|
|
|
): Array<{ name: string; content: string }> | undefined {
|
|
|
|
|
const files = registry.get(kind)?.defaultFiles?.[mode];
|
|
|
|
|
return files && files.length ? files : undefined;
|
|
|
|
|
}
|
|
|
|
|
|
feat(boards): runtime board-registration seam for private overlays
registerProBoards() lets a hosted overlay ship boards outside the OSS tree as
data-only definitions: registration patches the exported BoardKind maps
(labels / FQBN / MicroPython) so every existing read site keeps working, and
the sites a map can't cover consult the registry — canvas render (custom
element or overlay render fn), BOARD_SIZE, pin-name mapping, picker list +
descriptions + tag, ESP32 family routing, in-browser simulator construction
and firmware load (structural ProBoardSimulator contract, duck-typed PIO
attach/detach), built-in bridge sensors, and a CS-gated built-in microSD
(sdCsPin -> sd_card.cs_pin worker config). Esp32Bridge additionally gains the
esp32-c6 machine type + TX pin (public chip knowledge — the C6 compile path
already ships) and a generic sendKey() for built-in matrix keyboards.
registerProExamples() appends gallery examples at runtime; the board ONLINE
ads recompute at render so registration hides them. OSS behavior without an
overlay is unchanged — the registry is dead code, same as the other seams.
2026-07-23 02:21:21 +07:00
|
|
|
export function listProBoards(): ProBoardDef[] {
|
|
|
|
|
return Array.from(registry.values());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isProBoardSimulator(sim: unknown): sim is ProBoardSimulator {
|
|
|
|
|
return !!sim && (sim as { isProBoardSimulator?: boolean }).isProBoardSimulator === true;
|
|
|
|
|
}
|