diff --git a/frontend/src/pages/EditorPage.tsx b/frontend/src/pages/EditorPage.tsx index c8cf8760..f8d3dba9 100644 --- a/frontend/src/pages/EditorPage.tsx +++ b/frontend/src/pages/EditorPage.tsx @@ -93,7 +93,7 @@ export const EditorPage: React.FC = () => { const setLockComponents = useSimulatorStore((s) => s.setLockComponents); useEffect(() => { - if (embedMode.lockComponents) { + if (embedMode.lockComponents && typeof setLockComponents === 'function') { setLockComponents(true); } }, [embedMode.lockComponents, setLockComponents]); @@ -102,12 +102,14 @@ export const EditorPage: React.FC = () => { if (!embedMode.enabled) return; const handler = (e: Event) => { const detail = (e as CustomEvent).detail || {}; - if (detail.lockComponents !== undefined) setLockComponents(detail.lockComponents); + if (detail.lockComponents !== undefined && typeof setLockComponents === 'function') { + setLockComponents(detail.lockComponents); + } }; window.addEventListener('velxio-embed-mode', handler); embedBridge.notifyReady(); return () => window.removeEventListener('velxio-embed-mode', handler); - }, [embedMode.enabled]); + }, [embedMode.enabled, setLockComponents]); const [editorWidthPct, setEditorWidthPct] = useState(45); // Desktop-only 3-way layout switch (code-only / circuit-only / both). diff --git a/frontend/src/services/ComponentRegistry.ts b/frontend/src/services/ComponentRegistry.ts index c8552aa4..1598d1be 100644 --- a/frontend/src/services/ComponentRegistry.ts +++ b/frontend/src/services/ComponentRegistry.ts @@ -57,7 +57,8 @@ export class ComponentRegistry { // `cache: 'no-store'` so adding a new component (or rebuilding the JSON) // shows up after a single page refresh — without this, the browser keeps // serving the stale copy until you do a hard reload. - const response = await fetch('/components-metadata.json', { cache: 'no-store' }); + const base = (typeof import.meta !== 'undefined' && import.meta.env?.BASE_URL ? import.meta.env.BASE_URL.replace(/\/+$/, '') : ''); + const response = await fetch(`${base}/components-metadata.json`, { cache: 'no-store' }); if (!response.ok) { throw new Error(`Failed to load metadata: ${response.statusText}`); } diff --git a/frontend/src/simulation/Esp32C3Simulator.ts b/frontend/src/simulation/Esp32C3Simulator.ts index 01997859..39169654 100644 --- a/frontend/src/simulation/Esp32C3Simulator.ts +++ b/frontend/src/simulation/Esp32C3Simulator.ts @@ -387,7 +387,8 @@ export class Esp32C3Simulator { // @ts-expect-error kept for future use when more peripherals are emulated private async _loadRom(): Promise { try { - const resp = await fetch('/boards/esp32c3-rom.bin'); + const base = (typeof import.meta !== 'undefined' && import.meta.env?.BASE_URL ? import.meta.env.BASE_URL.replace(/\/+$/, '') : ''); + const resp = await fetch(`${base}/boards/esp32c3-rom.bin`); if (!resp.ok) throw new Error(`HTTP ${resp.status}`); const buf = await resp.arrayBuffer(); this._romData = new Uint8Array(buf); diff --git a/frontend/src/store/useSimulatorStore.ts b/frontend/src/store/useSimulatorStore.ts index 20c01862..f7d8e60a 100644 --- a/frontend/src/store/useSimulatorStore.ts +++ b/frontend/src/store/useSimulatorStore.ts @@ -1146,6 +1146,8 @@ interface SimulatorState { dismissEsp32Crash: () => void; // ── Components ────────────────────────────────────────────────────────── + lockComponents: boolean; + setLockComponents: (lock: boolean) => void; components: Component[]; addComponent: (component: Component) => void; removeComponent: (id: string) => void; @@ -3077,6 +3079,9 @@ export const useSimulatorStore = create((set, get) => { // named V_led-builtin_sense yields the wrong key in branchCurrents // and the LED's update() loop never sees the diode current — the // node voltage is correct (the user sees ~1.84V on the wire) but the + lockComponents: false, + setLockComponents: (lock: boolean) => set({ lockComponents: lock }), + // visual brightness stays at zero. Underscore is safe. components: [ { diff --git a/frontend/src/velxio-elements/breadboard-element.ts b/frontend/src/velxio-elements/breadboard-element.ts index d7ba52a5..5cc3a4bf 100644 --- a/frontend/src/velxio-elements/breadboard-element.ts +++ b/frontend/src/velxio-elements/breadboard-element.ts @@ -96,7 +96,8 @@ export const BREADBOARD_PINS: readonly BreadboardPin[] = PINS; let artPromise: Promise | null = null; function fetchArt(): Promise { if (!artPromise) { - artPromise = fetch('/component-svgs/fritzing/breadboard-full.svg') + const base = (typeof import.meta !== 'undefined' && import.meta.env?.BASE_URL ? import.meta.env.BASE_URL.replace(/\/+$/, '') : ''); + artPromise = fetch(`${base}/component-svgs/fritzing/breadboard-full.svg`) .then((r) => (r.ok ? r.text() : null)) .catch(() => null); } diff --git a/frontend/src/velxio-elements/breadboard-mini-element.ts b/frontend/src/velxio-elements/breadboard-mini-element.ts index 06129d73..b1db62dc 100644 --- a/frontend/src/velxio-elements/breadboard-mini-element.ts +++ b/frontend/src/velxio-elements/breadboard-mini-element.ts @@ -64,7 +64,8 @@ export const BREADBOARD_MINI_PINS: readonly BreadboardMiniPin[] = PINS; let artPromise: Promise | null = null; function fetchArt(): Promise { if (!artPromise) { - artPromise = fetch('/component-svgs/fritzing/breadboard-mini.svg') + const base = (typeof import.meta !== 'undefined' && import.meta.env?.BASE_URL ? import.meta.env.BASE_URL.replace(/\/+$/, '') : ''); + artPromise = fetch(`${base}/component-svgs/fritzing/breadboard-mini.svg`) .then((r) => (r.ok ? r.text() : null)) .catch(() => null); }