{"id":43286669,"url":"https://github.com/codesignal/learn_logic-sim","last_synced_at":"2026-02-01T18:02:23.916Z","repository":{"id":333840200,"uuid":"1093415774","full_name":"CodeSignal/learn_logic-sim","owner":"CodeSignal","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-21T11:13:21.000Z","size":221,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-21T21:24:48.634Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CodeSignal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-11-10T10:44:42.000Z","updated_at":"2026-01-21T11:13:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/CodeSignal/learn_logic-sim","commit_stats":null,"previous_names":["codesignal/learn_logic-sim"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/CodeSignal/learn_logic-sim","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeSignal%2Flearn_logic-sim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeSignal%2Flearn_logic-sim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeSignal%2Flearn_logic-sim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeSignal%2Flearn_logic-sim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CodeSignal","download_url":"https://codeload.github.com/CodeSignal/learn_logic-sim/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeSignal%2Flearn_logic-sim/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28984815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T17:52:09.146Z","status":"ssl_error","status_checked_at":"2026-02-01T17:49:53.529Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-01T18:02:22.954Z","updated_at":"2026-02-01T18:02:23.911Z","avatar_url":"https://github.com/CodeSignal.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Logic Circuit Lab\n\nLogic Circuit Lab is a browser-based playground for sketching, simulating, and exporting small digital circuits. The UI is built on the Bespoke generalized components so it can be embedded anywhere, while a lightweight Node.js server serves the app, handles VHDL exports, and exposes a simple messaging API.\n\n---\n\n## What’s Inside\n- `client/index.html` – the full Bespoke application (header, palette, canvas, inspector, help trigger).\n- `client/logic-sim.js` – canvas rendering, drag/drop, wiring, evaluation, auto-save, export helpers.\n- `client/logic-sim.css` – circuit-specific styling layered on top of `client/bespoke.css`.\n- `client/gate-registry.js` \u0026 `client/gates/*.svg` – built-in gate definitions, icons, and logic.\n- `client/help-modal.js` \u0026 `client/help-content-template.html` – Help modal framework and copy.\n- `client/initial_state.json` – starter circuit loaded on first launch or after reset.\n- `client/gate-config.json` – palette ordering, default zoom, and export-report options.\n- `server.js` – static file server, `/vhdl/export` handler, `/message` relay, optional WebSocket hub.\n- `circuit-report.js` – pretty printer that summarizes each export to the console.\n\n---\n\n## Features at a Glance\n- Drag gates from the palette or click to drop them at the center of the viewport.\n- Wire outputs to inputs with a click/tap workflow; wires snap to ports and redraw as you move gates.\n- Real-time simulation with deterministic propagation and cached inputs to avoid oscillations.\n- Selection panel with gate metadata, label editing, and context actions (toggle inputs, delete, etc.).\n- Infinite workspace with smooth pan (drag on empty canvas) and wheel-based zoom (Ctrl+wheel for precision).\n- Auto-save to `localStorage` with standardized Bespoke status messaging (`Ready`, `Saving...`, etc.).\n- Reset button reloads `initial_state.json` and re-primes auto-save.\n- Help modal content streamed from `help-content-template.html` and triggered by the header Help button.\n- One-click (or scripted) VHDL export that posts the circuit snapshot to the Node server.\n\n---\n\n## Getting Started\n1. **Install prerequisites** – Node.js 18+ and npm.\n2. **Install dependencies** – Run `npm install` if you need to add/refresh modules.\n3. **Start the dev server**\n   ```bash\n   npm start\n   ```\n   The server listens on `http://localhost:3000` and serves the contents of `client/`.\n4. **Open the app** – visit `http://localhost:3000` to launch Logic Circuit Lab.\n5. **Optional: broadcast a message**\n   ```bash\n   curl -X POST http://localhost:3000/message \\\n     -H \"Content-Type: application/json\" \\\n     -d '{\"message\":\"Hello lab!\"}'\n   ```\n   Requires the `ws` dependency to be installed; all connected clients will display the alert.\n\n---\n\n## Using the Interface\n- **Palette (left sidebar)** – click a gate to drop it at the center, or drag it directly into the canvas. Available gates include Input, Output, Buffer, NOT, AND, NAND, OR, NOR, and XOR; extend the list via `gate-registry.js`.\n- **Canvas** – drag on empty space to pan, use the mouse wheel (or pinch gesture) to zoom, and click a gate to select it. Press Delete/Backspace to remove the active gate. Selection outlines show connection points; ports highlight when valid wiring targets are available.\n- **Wiring workflow** – click an output port, then click a compatible input port. A ghost wire follows your cursor until you pick a destination. Clicking an occupied input rewires it to the new source.\n- **Inputs and outputs** – input gates act as toggles; click them (or use the inspector action) to switch between 0/1. Output gates display the live signal coming into their single input.\n- **Inspector (Selection card)** – shows the currently selected gate’s properties, allows renaming labels, exposes gate-specific actions, and lists every connected port.\n- **Reset** – the “Reset” button above the canvas replaces the board with `initial_state.json` and reinitializes auto-save.\n- **Help** – the `Help` button in the header opens the modal populated from `help-content-template.html`. Update that file to document your specific lab instructions, keyboard shortcuts, or grading rubric.\n\n---\n\n## Custom Gates\n- Custom gates are described through `.json` snapshots that match the `state.json` schema (the object returned by `window.logicSim.snapshot()`).\n- Build a circuit with the standard palette, export it via `window.logicSim.snapshot()` (or copy `state.json`), and drop that JSON file into `client/custom-gates/` to turn it into a reusable gate without duplicating its contents.\n- Input and output pins for the custom gate are inferred from the `input` and `output` gates inside the JSON snapshot (their labels become the exposed port names). Simulation treats the custom gate as a black box by running the nested snapshot with the same propagation engine.\n- Snapshots embedded in saved circuits (or discovered under `client/custom-gates/`) automatically appear in the main palette alongside the built-in gates.\n- VHDL exports automatically flatten any custom gates, so you can keep them in your design and still obtain a complete netlist while `state.json` preserves the original snapshot (including custom gate definitions).\n\n---\n\n## Saving, Loading, and Status Messages\n- On first load, `logic-sim.js` fetches `initial_state.json`, applies it to the canvas, and caches it locally.\n- Once the app confirms that `localStorage` works, every mutation is debounced (500 ms) and saved under the key `logic-circuit-lab-state-v1`.\n- Status changes are limited to the mandated Bespoke messages; `setStatus()` is exposed globally for future integrations.\n- If persistence fails (quota exceeded, private mode, etc.), the app logs the error, shows `Failed to load data`, and keeps the in-memory circuit running.\n- Resetting the canvas writes the starter snapshot back to storage, ensuring the pool stays in sync across reloads.\n\n---\n\n## Exporting to VHDL\n1. Trigger an export by running one of the following in DevTools or from a parent frame:\n   ```javascript\n   window.logicSim.exportToVhdl();\n   // or\n   window.dispatchEvent(new Event('logic-sim:export-vhdl'));\n   // or\n   window.postMessage({ type: 'logic-sim:export-vhdl' }, '*');\n   ```\n2. The client serializes the current snapshot to VHDL, then POSTs:\n   ```json\n   {\n     \"vhdl\": \"\u003cgenerated code\u003e\",\n     \"state\": { ...current circuit snapshot... },\n     \"exportState\": { ...flattened export snapshot... }\n   }\n   ```\n   to `POST /vhdl/export`.\n3. The server writes `user.vhdl` and `state.json` at the repo root, then runs `circuit-report.printCircuitReport()` to log counts, positions, connection issues, and (optionally) a truth table. Report sections are toggled via `gate-config.json \u003e exportReport`.\n4. If the request fails, the client shows `Save failed (will retry)` and automatically retries after 3 s.\n\n---\n\n## Configuration \u0026 Data Files\n- **`client/gate-config.json`**\n  - `defaultZoom` – initial canvas scale (clamped between 0.5 and 2.75).\n  - `paletteOrder` – ordered list of gate type keys from `gate-registry.js`.\n  - `exportReport` – toggles for each console report section plus truth-table limits.\n- **`client/initial_state.json`**\n  - Defines the starter circuit (`gates`, `connections`, `nextId`). Edit coordinates, labels, or states to showcase a different demo when the app loads.\n- **`client/gate-registry.js`**\n  - Extend `registerGate()` calls to add new gate types. Provide an SVG icon, `inputs`, `outputs`, port layout, and a pure logic function that returns output bits.\n- **`client/logic-sim.css`**\n  - Customize colors, gate chrome, canvas grid, inspector layout, etc. Keep theme tokens (`--bespoke-*`) to remain compatible with host pages.\n- **`client/help-content-template.html`**\n  - Replace placeholders with real instructions. The file is fetched as text, so inline images should use relative paths inside `client/`.\n\n---\n\n## Server API \u0026 Messaging\n- `GET /` (and static assets) – serves files from `client/`.\n- `POST /vhdl/export` – accepts `{ vhdl: string, state: object, exportState?: object }`, writes artifacts, prints reports, responds with `{ success: true }` on success.\n- `POST /message` – accepts `{ message: string }`, broadcasts it to every connected WebSocket client (`ws` package required). Clients show an alert with the message body.\n- WebSockets – automatically enabled when the `ws` dependency is installed. Connections are logged, and messages flow only from `/message` to the clients; there is no inbound command channel yet.\n\n---\n\n## Embedding \u0026 Automation Hooks\n- The canvas exposes `window.logicSim` with:\n  - `exportToVhdl()` – triggers the export flow described above.\n  - `snapshot()` – returns the current normalized circuit state.\n  - `resetToStarter()` – programmatically mirrors the Reset button.\n- Custom exporters can listen for `message` events (`event.data.type === 'logic-sim:export-vhdl'`) or dispatch the `logic-sim:export-vhdl` DOM event.\n- The app uses standard Bespoke status messaging and `.bespoke` scoping, so you can embed `client/index.html` inside `test-integration.html` or another host without style collisions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodesignal%2Flearn_logic-sim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodesignal%2Flearn_logic-sim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodesignal%2Flearn_logic-sim/lists"}