From 00a15c6f7662a7a6211eb7d4fbeae7f8bdce4899 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Thu, 16 Apr 2026 08:39:47 -0300 Subject: [PATCH] feat: add 'circuits' category to ExampleProject interface fix: increase timeout for compilation requests to 180 seconds refactor: call recalculateAllWirePositions after loading examples chore: update subproject commit for rp2040js to dirty state chore: update subproject commit for wokwi-elements to dirty state --- frontend/public/components-metadata.json | 209 ++++++++++- .../src/__tests__/examples-circuits.test.ts | 10 +- .../src/components/editor/EditorToolbar.tsx | 16 +- .../components/examples/ExamplesGallery.tsx | 7 +- frontend/src/data/examples-circuits.ts | 326 +++++++++--------- frontend/src/data/examples.ts | 2 +- frontend/src/services/compilation.ts | 2 +- frontend/src/utils/loadExample.ts | 3 + 8 files changed, 393 insertions(+), 182 deletions(-) diff --git a/frontend/public/components-metadata.json b/frontend/public/components-metadata.json index 2ae8a80f..9f79f76a 100644 --- a/frontend/public/components-metadata.json +++ b/frontend/public/components-metadata.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "generatedAt": "2026-04-16T03:35:24.515Z", + "generatedAt": "2026-04-16T04:07:07.823Z", "components": [ { "thumbnail": "\n \n \n DIODE-1N4007\n \n ", @@ -815,6 +815,162 @@ "ili9341" ] }, + { + "id": "lcd1602", + "tagName": "wokwi-lcd1602", + "name": "LCD1602", + "category": "displays", + "thumbnail": "\n \n \n LCD1602\n \n ", + "properties": [ + { + "name": "color", + "type": "string", + "defaultValue": "black", + "control": "text" + }, + { + "name": "background", + "type": "string", + "defaultValue": "green", + "control": "text" + }, + { + "name": "characters", + "type": "number", + "defaultValue": { + "0": 0, + "1": 0, + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0, + "9": 0, + "10": 0, + "11": 0, + "12": 0, + "13": 0, + "14": 0, + "15": 0, + "16": 0, + "17": 0, + "18": 0, + "19": 0, + "20": 0, + "21": 0, + "22": 0, + "23": 0, + "24": 0, + "25": 0, + "26": 0, + "27": 0, + "28": 0, + "29": 0, + "30": 0, + "31": 0 + }, + "control": "range" + }, + { + "name": "font", + "type": "string", + "control": "text" + }, + { + "name": "cursor", + "type": "string", + "defaultValue": false, + "control": "text" + }, + { + "name": "blink", + "type": "string", + "defaultValue": false, + "control": "text" + }, + { + "name": "cursorX", + "type": "string", + "defaultValue": 0, + "control": "text" + }, + { + "name": "cursorY", + "type": "string", + "defaultValue": 0, + "control": "text" + }, + { + "name": "backlight", + "type": "string", + "defaultValue": true, + "control": "text" + }, + { + "name": "pins", + "type": "string", + "defaultValue": "full", + "control": "text" + }, + { + "name": "screenOnly", + "type": "string", + "defaultValue": false, + "control": "text" + } + ], + "defaultValues": { + "color": "black", + "background": "green", + "characters": { + "0": 0, + "1": 0, + "2": 0, + "3": 0, + "4": 0, + "5": 0, + "6": 0, + "7": 0, + "8": 0, + "9": 0, + "10": 0, + "11": 0, + "12": 0, + "13": 0, + "14": 0, + "15": 0, + "16": 0, + "17": 0, + "18": 0, + "19": 0, + "20": 0, + "21": 0, + "22": 0, + "23": 0, + "24": 0, + "25": 0, + "26": 0, + "27": 0, + "28": 0, + "29": 0, + "30": 0, + "31": 0 + }, + "cursor": false, + "blink": false, + "cursorX": 0, + "cursorY": 0, + "backlight": true, + "pins": "full", + "screenOnly": false + }, + "pinCount": 21, + "tags": [ + "lcd1602" + ] + }, { "id": "lcd2004", "tagName": "wokwi-lcd2004", @@ -1748,6 +1904,57 @@ "servo" ] }, + { + "id": "stepper-motor", + "tagName": "wokwi-stepper-motor", + "name": "Stepper Motor", + "category": "motors", + "thumbnail": "\n \n \n STEPPER-MOTOR\n \n ", + "properties": [ + { + "name": "angle", + "type": "string", + "defaultValue": 0, + "control": "text" + }, + { + "name": "arrow", + "type": "string", + "defaultValue": "", + "control": "text" + }, + { + "name": "value", + "type": "string", + "defaultValue": "", + "control": "text" + }, + { + "name": "units", + "type": "string", + "defaultValue": "", + "control": "text" + }, + { + "name": "size", + "type": "string", + "control": "text" + } + ], + "defaultValues": { + "angle": 0, + "arrow": "", + "value": "", + "units": "" + }, + "pinCount": 4, + "tags": [ + "stepper-motor", + "stepper motor", + "stepper", + "motor" + ] + }, { "id": "7segment", "tagName": "wokwi-7segment", diff --git a/frontend/src/__tests__/examples-circuits.test.ts b/frontend/src/__tests__/examples-circuits.test.ts index 89f6ae2b..c34ff74b 100644 --- a/frontend/src/__tests__/examples-circuits.test.ts +++ b/frontend/src/__tests__/examples-circuits.test.ts @@ -23,11 +23,9 @@ describe('circuitExamples integration', () => { expect(dupes).toEqual([]); }); - it('circuit examples cover all expected categories', () => { - const cats = new Set(circuitExamples.map((e) => e.category)); - expect(cats.has('basics')).toBe(true); - expect(cats.has('sensors')).toBe(true); - expect(cats.has('robotics')).toBe(true); + it('all circuit examples use the circuits category', () => { + const nonCircuits = circuitExamples.filter((e) => e.category !== 'circuits'); + expect(nonCircuits.map((e) => e.id)).toEqual([]); }); it('every example has valid required fields', () => { @@ -35,7 +33,7 @@ describe('circuitExamples integration', () => { expect(e.id, `missing id: ${JSON.stringify(e)}`).toBeTypeOf('string'); expect(e.title).toBeTypeOf('string'); expect(e.description).toBeTypeOf('string'); - expect(e.category).toMatch(/^(basics|sensors|displays|communication|games|robotics)$/); + expect(e.category).toMatch(/^(basics|sensors|displays|communication|games|robotics|circuits)$/); expect(e.difficulty).toMatch(/^(beginner|intermediate|advanced)$/); expect(e.code).toBeTypeOf('string'); expect(Array.isArray(e.components)).toBe(true); diff --git a/frontend/src/components/editor/EditorToolbar.tsx b/frontend/src/components/editor/EditorToolbar.tsx index 5a4e8178..d0b68160 100644 --- a/frontend/src/components/editor/EditorToolbar.tsx +++ b/frontend/src/components/editor/EditorToolbar.tsx @@ -150,7 +150,10 @@ export const EditorToolbar = ({ consoleOpen, setConsoleOpen, compileLogs: _compi addLog({ timestamp: new Date(), type: 'info', message: `Starting compilation for ${boardLabel} (${fqbn})...` }); try { - const sketchFiles = files.map((f) => ({ name: f.name, content: f.content })); + const groupFiles = activeBoard?.activeFileGroupId + ? useEditorStore.getState().getGroupFiles(activeBoard.activeFileGroupId) + : files; + const sketchFiles = (groupFiles.length > 0 ? groupFiles : files).map((f) => ({ name: f.name, content: f.content })); const result = await compileCode(sketchFiles, fqbn); const resultLogs = parseCompileResult(result, boardLabel); @@ -524,14 +527,9 @@ export const EditorToolbar = ({ consoleOpen, setConsoleOpen, compileLogs: _compi {/* Run */}