From edd2ac32d5a7dcff3c25a57500589af9ecea5fba Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Mon, 4 May 2026 14:03:20 -0300 Subject: [PATCH] feat: add optional extension hooks for private overlays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three small, backwards-compatible hooks let anyone with private features (velxio.dev's analytics, custom integrations, paid tiers, …) layer them on top of the open-source build without forking files. Backend (app/main.py): - After standard router registration, try-import an optional `app.pro` module exposing `register_pro(app)`. ImportError is silently swallowed (the OSS image doesn't ship `app.pro`, so this is a no-op there). Frontend: - EditorToolbar: new optional `rightSlot` prop renders extra elements after the built-in right-group buttons (mirrors the existing `centerSlot` pattern). - main.tsx: dynamic `import('@pro/index')` gated by VITE_PRO_BUILD env. When unset (OSS build), the branch is dead-code-eliminated and no pro chunk is emitted. - vite.config.ts: `@pro` alias resolves to `src/__pro_stub__/` by default. Private builds set `VITE_PRO_BUILD=true` and `PRO_OVERLAY_PATH=` to point at their real overlay tree. - src/__pro_stub__/index.ts: 1-line no-op `mountPro` so TypeScript and Vite resolvers stay happy in OSS builds. Verified: `npm run build:docker` succeeds; `npm test` passes 1161/1162; the OSS bundle (43 MB) contains zero references to `__pro_stub__`, `@pro`, or `pro/index` (verified via `grep dist/`). Co-Authored-By: Claude Opus 4.7 (1M context) --- backend/app/main.py | 11 + frontend/public/sitemap.xml | 326 +++++++++--------- frontend/src/__pro_stub__/index.ts | 7 + .../src/components/editor/EditorToolbar.tsx | 8 + frontend/src/main.tsx | 10 + frontend/vite.config.ts | 16 + 6 files changed, 215 insertions(+), 163 deletions(-) create mode 100644 frontend/src/__pro_stub__/index.ts diff --git a/backend/app/main.py b/backend/app/main.py index 1a92688b..e871d0bc 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -126,6 +126,17 @@ app.include_router(simulation.router, prefix="/api/simulation", tags=["simulatio from app.api.routes import iot_gateway app.include_router(iot_gateway.router, prefix="/api/gateway", tags=["iot-gateway"]) +# Optional pro extension. The `app.pro` package only exists in private builds +# (overlaid at Docker build time by an external repo) — its absence in the +# open-source image is expected and silently ignored. Anyone with private +# extensions can drop a package at `backend/app/pro/` exposing +# `register_pro(app)` and have it auto-loaded here without further edits. +try: + from app.pro import register_pro # type: ignore[import-not-found] + register_pro(app) +except ImportError: + pass + @app.get("/") def root(): return { diff --git a/frontend/public/sitemap.xml b/frontend/public/sitemap.xml index 6509fe40..1d7e5b52 100644 --- a/frontend/public/sitemap.xml +++ b/frontend/public/sitemap.xml @@ -4,980 +4,980 @@ https://velxio.dev/ - 2026-05-03 + 2026-05-04 weekly 1 https://velxio.dev/editor - 2026-05-03 + 2026-05-04 weekly 0.9 https://velxio.dev/examples - 2026-05-03 + 2026-05-04 weekly 0.8 https://velxio.dev/docs - 2026-05-03 + 2026-05-04 monthly 0.8 https://velxio.dev/docs/intro - 2026-05-03 + 2026-05-04 monthly 0.8 https://velxio.dev/docs/getting-started - 2026-05-03 + 2026-05-04 monthly 0.8 https://velxio.dev/docs/emulator - 2026-05-03 + 2026-05-04 monthly 0.7 https://velxio.dev/docs/esp32-emulation - 2026-05-03 + 2026-05-04 monthly 0.7 https://velxio.dev/docs/riscv-emulation - 2026-05-03 + 2026-05-04 monthly 0.7 https://velxio.dev/docs/rp2040-emulation - 2026-05-03 + 2026-05-04 monthly 0.7 https://velxio.dev/docs/raspberry-pi3-emulation - 2026-05-03 + 2026-05-04 monthly 0.7 https://velxio.dev/docs/components - 2026-05-03 + 2026-05-04 monthly 0.7 https://velxio.dev/docs/architecture - 2026-05-03 + 2026-05-04 monthly 0.7 https://velxio.dev/docs/third-party - 2026-05-03 + 2026-05-04 monthly 0.7 https://velxio.dev/docs/mcp - 2026-05-03 + 2026-05-04 monthly 0.7 https://velxio.dev/docs/setup - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/docs/roadmap - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/circuit-simulator - 2026-05-03 + 2026-05-04 weekly 0.95 https://velxio.dev/spice-simulator - 2026-05-03 + 2026-05-04 weekly 0.9 https://velxio.dev/electronics-simulator - 2026-05-03 + 2026-05-04 monthly 0.85 https://velxio.dev/custom-chip-simulator - 2026-05-03 + 2026-05-04 monthly 0.85 https://velxio.dev/attiny85-simulator - 2026-05-03 + 2026-05-04 monthly 0.85 https://velxio.dev/arduino-simulator - 2026-05-03 + 2026-05-04 monthly 0.9 https://velxio.dev/arduino-emulator - 2026-05-03 + 2026-05-04 monthly 0.9 https://velxio.dev/atmega328p-simulator - 2026-05-03 + 2026-05-04 monthly 0.85 https://velxio.dev/arduino-mega-simulator - 2026-05-03 + 2026-05-04 monthly 0.85 https://velxio.dev/esp32-simulator - 2026-05-03 + 2026-05-04 monthly 0.9 https://velxio.dev/esp32-s3-simulator - 2026-05-03 + 2026-05-04 monthly 0.85 https://velxio.dev/esp32-c3-simulator - 2026-05-03 + 2026-05-04 monthly 0.85 https://velxio.dev/raspberry-pi-pico-simulator - 2026-05-03 + 2026-05-04 monthly 0.9 https://velxio.dev/raspberry-pi-simulator - 2026-05-03 + 2026-05-04 monthly 0.85 https://velxio.dev/v2 - 2026-05-03 + 2026-05-04 monthly 0.9 https://velxio.dev/v2-5 - 2026-05-03 + 2026-05-04 weekly 0.95 https://velxio.dev/about - 2026-05-03 + 2026-05-04 monthly 0.7 https://velxio.dev/examples/blink-led - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/traffic-light - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/button-led - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/fade-led - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/serial-hello - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/rgb-led - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/simon-says - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/tft-display - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/lcd-hello - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/serial-echo - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/serial-led-control - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/i2c-scanner - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/i2c-rtc-read - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/i2c-eeprom-rw - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/spi-loopback - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/multi-protocol - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-blink - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-serial-echo - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-serial-led-control - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-i2c-scanner - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-i2c-rtc-read - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-i2c-eeprom-rw - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-spi-loopback - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-adc-read - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-multi-protocol - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-blink-led - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-serial-echo - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pi-to-arduino-led-control - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/dual-pico-serial1-passthrough - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/dual-pico-bidirectional-handshake - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/dual-pico-digital-mirror - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/nano-blink - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/nano-serial - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/nano-button-led - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/nano-fade - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/mega-blink - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/mega-serial - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/mega-led-chase - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/mega-serial-control - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/c3-blink - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/c3-serial - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/c3-rgb - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/c3-button - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/c3-serial-echo - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/uno-7segment - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-7segment - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-7segment - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/uno-potentiometer - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/uno-rgb-cycle - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-button-led - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-rgb - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/uno-dht22 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/uno-hcsr04 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/uno-pir - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/uno-servo - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/uno-photoresistor - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/uno-ntc - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-dht22 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-hcsr04 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-pir - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-servo - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-ntc - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pico-joystick - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-dht22 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-hcsr04 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-mpu6050 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-pir - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-servo - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-joystick - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/c3-dht22 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/c3-hcsr04 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/c3-pir - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/c3-servo - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32c3-wifi-scan - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32c3-wifi-connect - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32c3-http-server - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32c3-ble-advertise - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-wifi-scan - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-wifi-connect - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-http-server - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-ble-advertise - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-bmp280 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-oled - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/attiny85-blink - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/attiny85-button-led - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/attiny85-pwm-fade - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/attiny85-ntc-sensor - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32cam-webcam-demo - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32cam-lcd-preview - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/voltage-divider - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/rc-low-pass-filter - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/wheatstone-bridge - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/ntc-temperature - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/led-current-limiting - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/parallel-resistors - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pot-adc-reader - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/photoresistor-light - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/multi-led-bar - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/capacitor-charge-curve - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/npn-led-switch - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/pnp-high-side-switch - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/mosfet-pwm-led - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/diode-rectifier - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/zener-regulator - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/schottky-reverse-protection - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/bjt-common-emitter - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/darlington-high-current - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/opamp-inverting - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/opamp-voltage-follower - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/opamp-comparator - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/opamp-difference - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/opamp-schmitt-trigger - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/and-gate-alarm - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/xor-toggle-detector - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/nand-sr-latch - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/full-adder - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/binary-counter-leds - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/logic-probe - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/relay-led-switch - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/optocoupler-signal - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/l293d-motor-control - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/l293d-speed-pwm - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/power-supply-7805 - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/lm317-adjustable-psu - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/battery-voltage-monitor - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-dual-adc - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/mega-multi-led - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/nano-sensor-station - 2026-05-03 + 2026-05-04 monthly 0.6 https://velxio.dev/examples/esp32-pwm-led-rgb - 2026-05-03 + 2026-05-04 monthly 0.6 diff --git a/frontend/src/__pro_stub__/index.ts b/frontend/src/__pro_stub__/index.ts new file mode 100644 index 00000000..dd0ab3ae --- /dev/null +++ b/frontend/src/__pro_stub__/index.ts @@ -0,0 +1,7 @@ +// Open-source no-op stub for the @pro alias (see vite.config.ts). +// Private overlays (e.g. velxio-prod) replace this at build time by setting +// VITE_PRO_BUILD=true and PRO_OVERLAY_PATH to their real pro/frontend/src/pro +// directory. The dynamic `import('@pro/index')` in main.tsx is gated by +// VITE_PRO_BUILD, so this stub is unreachable in OSS builds — it exists only +// to keep the TypeScript and Vite resolvers happy. +export const mountPro = () => {}; diff --git a/frontend/src/components/editor/EditorToolbar.tsx b/frontend/src/components/editor/EditorToolbar.tsx index 8ea6b54b..517d728a 100644 --- a/frontend/src/components/editor/EditorToolbar.tsx +++ b/frontend/src/components/editor/EditorToolbar.tsx @@ -33,6 +33,12 @@ interface EditorToolbarProps { * regardless of how narrow the editor pane gets. */ centerSlot?: React.ReactNode; + /** + * Optional extra elements rendered after the built-in right-group buttons + * (Libraries / Import-Export / Output Console). Used by private overlays + * to add deployment-specific actions without forking the toolbar. + */ + rightSlot?: React.ReactNode; } const BOARD_PILL_ICON: Record = { @@ -63,6 +69,7 @@ export const EditorToolbar = ({ compileLogs: _compileLogs, setCompileLogs, centerSlot, + rightSlot, }: EditorToolbarProps) => { const { files, codeChangedSinceLastCompile, markCompiled } = useEditorStore(); const { @@ -973,6 +980,7 @@ export const EditorToolbar = ({ + {rightSlot} diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index ff3cb342..2ed9f611 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -15,3 +15,13 @@ import './components/velxio-components/EPaperElement'; import App from './App.tsx'; createRoot(document.getElementById('root')!).render(); + +// Optional pro overlay. The `@pro` import resolves to a no-op stub in the +// open-source build (see vite.config.ts) and to the real overlay only when +// VITE_PRO_BUILD=true at build time. The dynamic import keeps the pro chunk +// out of the OSS bundle entirely (Vite tree-shakes the never-taken branch). +if (import.meta.env.VITE_PRO_BUILD) { + import('@pro/index') + .then((m) => m.mountPro?.()) + .catch((err) => console.warn('[pro] failed to load overlay:', err)); +} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 1abee7c7..160bee35 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -1,11 +1,27 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' +import path from 'path' // https://vite.dev/config/ // avr8js / rp2040js / @wokwi/elements are resolved from npm via package.json. // (The third-party/ clones are reference-only — keep them updated for credits.) +// +// The `@pro` alias resolves to a no-op stub by default. Private overlays +// (e.g. velxio-prod) set VITE_PRO_BUILD=true and PRO_OVERLAY_PATH at build +// time to point at their actual pro source tree. See README's "Pro overlay" +// section. +const proOverlayPath = + process.env.VITE_PRO_BUILD && process.env.PRO_OVERLAY_PATH + ? path.resolve(process.env.PRO_OVERLAY_PATH) + : path.resolve(__dirname, 'src/__pro_stub__') + export default defineConfig({ plugins: [react()], + resolve: { + alias: { + '@pro': proOverlayPath, + }, + }, server: { proxy: { '/api': {