MixedModeScheduler now accepts any SolverPort implementation via
solverFactory injection. The ad-hoc `NgSpiceClient` interface is
gone; the scheduler talks domain port types only.
New capabilities that fell out of the refactor:
- `resolveTran(step, stop)` — runs .tran via the solver and publishes
the steady-state (last-sample) voltage per pin. Full waveform
reachable via `getLastResult()` for downstream consumers
(CircuitSimulationService in B1+ will use this to populate
useElectricalStore.timeWaveforms).
- `getLastResult()` exposes the SolveResult so the upcoming service
layer can extract branchCurrents + waveforms without re-reading.
- `vectorsOfInterest` is computed from pinNetMap on every solve, so
the adapter only issues N parallel readVecs (where N = distinct
non-ground nets) instead of guessing.
`__setSchedulerEngineFactoryForTests` renamed to
`__setSchedulerSolverFactoryForTests`.
Tests fully migrated to FakeSolverAdapter — no more inline mock
NgSpiceClient. Test layering now mirrors production: scheduler tests
exercise port consumption, port-contract tests exercise the port
itself.
60 tests pass across mixed-mode-scheduler, solver-port-contract,
mixed-mode-bjt-switch-integration (real ngspice), pin-resolver,
pin-resolver-phase1b, connect-mixed-mode-scheduler-to-store,
connect-legacy-solver-to-mixed-mode. tsc clean.
Next: B1 — CircuitSimulationService, the layer above the scheduler
that builds netlists, picks .op vs .tran, and publishes results to
both useElectricalStore and the scheduler cache.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>