| Filename | Latest commit message | Latest commit date |
|---|---|---|
Two fixes to the same complaint — opening a board took minutes and the dialog
explaining why was misleading.
Ordering: the scope-wide lib presync ran "in PARALLEL with the wasm download",
so ~155 libraries' worth of requests competed with the 26MB+ bundle and the
project's own files — the things the user is actually blocked on. It now
starts after driveProjectIntoTool, warming IndexedDB behind an editor that is
already open. Still fire-and-forget and best-effort (the SyncStack dedups, so
a lib the wasm reaches mid-presync awaits the same in-flight fetch), now
abortable on unmount, and no longer shown on the boot overlay as a counter the
user is waiting on — the background indicator owns it.
Wording: the dialog quoted the compressed size with no hint that it was
compressed ("~35 MB" for a bundle whose progress bar then counts ~150 MB raw),
and quoted only the count of libs whose BODIES need downloading — while the
progress bar went to 155, because every warm lib still costs a sync-stack
resolve plus a manifest GET to find nothing changed. It now reads "~35 MB
compressed / ~150 MB uncompressed" and "downloads 1 library, checks all 155
for updates". Every existing degradation path is kept: unknown sizes still
say "large", sizesKnown:false degrades to "at least ~X MB", and the
no-warmth-answer case now says "fetched in the background" rather than the
newly-false "downloaded now".
Investigated and NOT changed: the symbol path is not structurally more
deferred than footprints — both enumerateLibrary() implementations are already
no-ops, so neither face does bridge crossings at boot. The perceived
schematic-vs-board difference was this presync timing plus set size.
typecheck clean; 233/233 standalone tests pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H8jo7zz1ZwzYpjJ64UZKN4
|
||
| .. | ||
| backend | ||
| pcbjam-shared@6189307bf5 | ||
| standalone | ||
| .env.example | ||
| .gitignore | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| tsconfig.base.json | ||
| turbo.json | ||
PCBJam Web — standalone editor (GPL)
A self-contained, GPL web app that opens KiCad projects in the WASM tools
(pcbnew / eeschema / pl_editor / …) — from a local folder, or from any backend
that implements the MIT @pcbjam/shared contract. It opens a
tool by URL:
/p/<project>/<tool>/<file-path> e.g. /p/demo/pcbnew/nyak.kicad_pcb
This workspace contains only the generic editor and a thin reference backend. All project-specific concerns (accounts, project management, uploads, auth) live in the separate closed application, which reuses this editor by hosting it standalone and redirecting to it (it must not link the GPL editor).
Layout
web/
├── standalone/ # @pcbjam/standalone — the GPL editor (Vite + React)
├── backend/ # @pcbjam/backend-example — thin reference @pcbjam/shared impl
└── pcbjam-shared/ # @pcbjam/shared — the FE↔BE contract (git submodule, MIT)
- Editor: Vite + React + TypeScript. Boots a tool directly in the document (no iframe), syncs the project tree into MEMFS, drives File→Open, and runs same-tab collaboration over BroadcastChannel.
- Example backend: Fastify + ts-rest serving a single project off the local
filesystem (
PROJECT_DIR). No DB, no auth, no uploads — the minimum the editor needs, and a worked example of the contract. Listens on:3060. Ondev/startit self-provisions example libraries — a curated slice of upstream KiCad symbol + footprint libs is cloned + extracted into.libs(served as read-only origins), so a bare clone has libraries to browse with no closed repo present. Seebackend/src/extract/.
Quick start
cd web
pnpm install
git submodule update --init web/pcbjam-shared # if not already populated
cp standalone/.env.example standalone/.env
cp backend/.env.example backend/.env # PROJECT_DIR=../../tests/fixtures/demo
pnpm dev # turbo: backend :3060 + editor :3048
Open http://localhost:3048 — either open a local folder (no backend needed)
or open the backend's project. The editor can point at any conforming backend
via VITE_API_BASE_URL.
WASM artifacts
The runtime artifacts (<tool>.js/.wasm, wx.js, images.tar.gz, <tool>.html)
are build outputs, not committed. They are synced into tests/apps/kicad/ by
tests/scripts/setup-kicad-wasm.sh (from repo-root output/).
They must be served same-origin as the app. Under the document's COEP /
cross-origin-isolation (set by the Vite dev server), KiCad WASM refuses to load
its glue/wasm from a different origin. pnpm dev runs scripts/link-wasm.mjs,
which symlinks standalone/public/wasm → tests/apps/kicad; Vite serves them
at /wasm. VITE_WASM_ASSET_BASE_URL defaults to /wasm.
- Point the symlink elsewhere with
WASM_SRC_DIR=/path pnpm --filter @pcbjam/standalone link-wasm. - If a tool won't load, the target dir is probably empty — run
tests/scripts/setup-kicad-wasm.shto populatetests/apps/kicad/. - prod: point
VITE_WASM_ASSET_BASE_URLat a URL whose origin also satisfies the same-origin / COEP constraints.
Scripts
| Command | What |
|---|---|
pnpm dev |
editor + example backend (turbo) |
pnpm build |
build all packages |
pnpm typecheck |
typecheck all packages |
Contract (@pcbjam/shared, MIT)
The editor reads from a backend over the shared contract:
GET /api/projects, GET /api/projects/:project,
GET /api/projects/:project/files, and the streamed
GET /api/projects/:project/files/* (raw bytes). Management/write operations and
ownership are not part of this contract — they belong to the closed app.