Skip to content

Commit b32fca8

Browse files
committed
readme: refresh toolbox section, port-sync list, project structure, scripts
1 parent a8a035d commit b32fca8

1 file changed

Lines changed: 49 additions & 46 deletions

File tree

README.md

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ src/
105105
│ │ └── generated/ # Auto-generated defaults
106106
│ ├── stores/ # Svelte stores (state management)
107107
│ │ └── graph/ # Graph state with subsystem navigation
108+
│ ├── toolbox/ # Runtime toolbox install/registry (catalog, installer, dependencies)
109+
│ ├── tours/ # In-app onboarding tours (builder, anchors, scripts)
108110
│ ├── types/ # TypeScript type definitions
109111
│ └── utils/ # Utilities (colors, download, csvExport, codemirror)
110112
├── routes/ # SvelteKit pages
@@ -114,6 +116,7 @@ pathview/ # Python package (pip install pathview)
114116
├── app.py # Flask server (subprocess management, HTTP routes)
115117
├── worker.py # REPL worker subprocess (Python execution)
116118
├── cli.py # CLI entry point (pathview serve)
119+
├── config.py # Server configuration (host, port, packages)
117120
├── converter.py # PVM to Python converter (public API)
118121
├── data/ # Bundled data files
119122
│ └── registry.json # Block/event registry for converter
@@ -131,7 +134,10 @@ scripts/
131134
├── generated/ # Generated files (from extract.py)
132135
│ └── registry.json # Block/event registry with import paths
133136
├── extract.py # Unified extraction script
134-
└── pvm2py.py # Standalone .pvm to Python converter
137+
├── pathview_introspect.py # Shared block/event introspection helpers
138+
├── pvm2py.py # Standalone .pvm to Python converter
139+
├── build_package.py # Build pip wheel + bundled frontend
140+
└── capture-screenshots.js # Snapshot block icons for build (Playwright)
135141
```
136142

137143
---
@@ -276,16 +282,18 @@ Configure in `src/lib/nodes/uiConfig.ts`:
276282

277283
```typescript
278284
export const syncPortBlocks = new Set([
279-
'Integrator',
280-
'Differentiator',
281-
'Delay',
282-
'PID',
283-
'PID_Antiwindup',
284-
'Amplifier',
285-
'Sin', 'Cos', 'Tan', 'Tanh',
285+
// Dynamic blocks
286+
'Integrator', 'Differentiator', 'Delay',
287+
// Algebraic blocks (element-wise)
288+
'Amplifier', 'Sin', 'Cos', 'Tan', 'Tanh',
286289
'Abs', 'Sqrt', 'Exp', 'Log', 'Log10',
287-
'Mod', 'Clip', 'Pow',
288-
'SampleHold'
290+
'Mod', 'Clip', 'Pow', 'Polynomial',
291+
'Rescale', 'Alias',
292+
// Logic blocks
293+
'LogicNot',
294+
// Discrete blocks
295+
'SampleHold', 'FirstOrderHold',
296+
'DiscreteIntegrator', 'DiscreteDerivative'
289297
]);
290298
```
291299

@@ -309,56 +317,48 @@ export const portLabelParams: Record<string, PortLabelConfig | PortLabelConfig[]
309317

310318
---
311319

312-
## Adding New Toolboxes
320+
## Toolboxes
313321

314-
To add a new PathSim toolbox (like `pathsim-chem`):
322+
PathView supports two complementary ways to extend the block library: **runtime toolboxes** that the user installs from the UI at any time, and **build-time toolboxes** that are baked into the deployed bundle.
315323

316-
### 1. Add to requirements
324+
### Runtime Toolboxes (default)
317325

318-
Edit `scripts/config/requirements-pyodide.txt`:
326+
Users install toolboxes from the **Toolbox Manager** dialog without rebuilding the app. Three install sources are supported:
319327

320-
```txt
321-
--pre
322-
pathsim
323-
pathsim-chem>=0.2rc2 # optional
324-
pathsim-controls # optional - your new toolbox
325-
```
326-
327-
The `# optional` comment means Pyodide will continue loading if this package fails to install.
328-
329-
### 2. Create toolbox config
328+
- **PyPI** — install a published package via `micropip` (Pyodide) or `pip` (Flask backend)
329+
- **URL** — load a wheel or sdist hosted anywhere
330+
- **Inline** — paste / upload a `.py` module to register ad-hoc blocks for one session
330331

331-
Create `scripts/config/pathsim-controls/blocks.json`:
332+
Once installed, PathView introspects the module's `Block` (and optional `Event`) subclasses, registers them as new node types, and persists the selection to `localStorage` so it replays on reload. The user can disable individual blocks, override their category, name, shape, or `syncPorts` flag, and uninstall the toolbox at any time. Saving a `.pvm` file embeds the list of toolbox dependencies; opening one elsewhere prompts to install missing pieces.
332333

333-
```json
334-
{
335-
"$schema": "../schemas/blocks.schema.json",
336-
"toolbox": "pathsim-controls",
337-
"importPath": "pathsim_controls.blocks",
334+
Implementation lives in `src/lib/toolbox/` (catalog, installer, register, persistence). The curated catalog of one-click installable toolboxes is in `catalog.ts`:
338335

339-
"categories": {
340-
"Controls": [
341-
"PIDController",
342-
"StateEstimator"
343-
]
336+
```typescript
337+
export const TOOLBOX_CATALOG: CatalogEntry[] = [
338+
{
339+
id: 'pathsim-chem',
340+
displayName: 'pathsim-chem',
341+
source: { type: 'pypi', pkg: 'pathsim-chem' },
342+
importPath: 'pathsim_chem',
343+
defaultCategory: 'Chemical',
344+
preloaded: true // seeded into store on first launch
344345
}
345-
}
346+
];
346347
```
347348

348-
### 3. (Optional) Add events
349+
To add an entry to the catalog: append a `CatalogEntry` to `TOOLBOX_CATALOG` and ship — no extraction step, no rebuild required for the user. Toolboxes outside the catalog still work via the manager's PyPI/URL/file inputs.
349350

350-
Create `scripts/config/pathsim-controls/events.json` if the toolbox has custom events.
351+
For the toolbox-package contract (which Python conventions a toolbox must follow to be introspectable), see [**docs/toolbox-spec.md**](docs/toolbox-spec.md).
351352

352-
### 4. Run extraction and build
353+
### Build-time Toolboxes (bundled into the deploy)
353354

354-
```bash
355-
npm run extract
356-
npm run build
357-
```
355+
For toolboxes that should be available without an install step (e.g. the core `pathsim` toolbox itself), block metadata is extracted at build time:
358356

359-
No code changes needed - the extraction script automatically discovers toolbox directories.
357+
1. Add the package to `scripts/config/requirements-pyodide.txt` so Pyodide can install it.
358+
2. Create `scripts/config/<toolbox-id>/blocks.json` (and optionally `events.json`) listing the categories and block class names.
359+
3. Run `npm run extract` to regenerate the TypeScript registry under `src/lib/*/generated/`.
360360

361-
For the full toolbox integration reference (Python package contract, config schemas, extraction pipeline, generated output), see [**docs/toolbox-spec.md**](docs/toolbox-spec.md).
361+
The build-time path is appropriate when a toolbox is part of the core deployment; for everything else prefer the runtime path, which avoids a redeploy.
362362

363363
---
364364

@@ -710,6 +710,8 @@ https://view.pathsim.org/?modelgh=pathsim/pathview/static/examples/feedback-syst
710710
| `npm run build:package` | Build pip package (frontend + wheel) |
711711
| `npm run preview` | Preview production build |
712712
| `npm run check` | TypeScript/Svelte type checking |
713+
| `npm run check:watch` | Type checking in watch mode |
714+
| `npm run screenshots` | Capture block-icon screenshots (Playwright) |
713715
| `npm run lint` | Run ESLint |
714716
| `npm run format` | Format code with Prettier |
715717
| `npm run extract` | Regenerate all definitions from PathSim |
@@ -733,7 +735,8 @@ Nodes are styled based on their category, with CSS-driven shapes and colors.
733735
| Sources | Pill | 20px |
734736
| Dynamic | Rectangle | 4px |
735737
| Algebraic | Rectangle | 4px |
736-
| Mixed | Asymmetric | 12px 4px 12px 4px |
738+
| Logic | Rectangle | 4px |
739+
| Discrete | Asymmetric | 12px 4px 12px 4px |
737740
| Recording | Pill | 20px |
738741
| Subsystem | Rectangle | 4px |
739742

0 commit comments

Comments
 (0)