2026-07-03 — editable base calls with undo/redo + FASTQ/QUAL export (v13)
Today's push adds the first of two professional-parity editing features: in-place editable base calls with a full undo/redo stack, plus FASTQ and Phred .qual export so edited sequences can flow directly into downstream tools.
Editable base calls
Every base span in the sequence panel is now an interactive element
(tabindex="0" role="button"). Double-clicking a span — or focusing it and pressing
Enter/Space — activates edit mode for that position. Type any IUPAC character
(A, C, G, T, N, R, Y, S, W, K, M, B, V, D, H) to replace the called base.
Pressing Delete or Backspace reverts the position to the original raw-trace base.
Pressing Escape cancels without committing.
Edits are stored in a pure-TypeScript BaseEditModel keyed on forward-strand indices.
When the reverse-complement view is active, the display index is mapped back to the forward-strand
coordinate automatically and the stored base is IUPAC-complemented so it reads correctly in both
orientations. Edited bases are highlighted in amber (.edited-base) with matching
colours in both light and dark themes.
Propagation
Because edits are applied inside buildDisplayTrace() — before the revcomp and
mixed-base steps — every downstream consumer automatically sees the corrected sequence:
- Sequence panel — rendered text reflects edits immediately.
- Find/search — IUPAC motif search runs against the edited sequence.
- Reverse complement — strand flip correctly maps the edited forward sequence.
- Mixed-base calling — re-runs on the edited basecalls.
- FASTA export — exported sequence contains the edited bases.
- FASTQ export — edited positions carry Phred score 0 (encoded
!in Phred+33). - QUAL export — integer quality file also uses 0 at edited positions.
Undo/redo
The BaseEditModel maintains separate undo and redo stacks as full snapshots of the
edits map. Undo (Ctrl+Z / ⌘Z) pops the stack and restores the previous state; redo
(Ctrl+Shift+Z / ⌘Shift+Z or Ctrl+Y) reapplies it. Making a new edit clears the redo stack.
Toolbar buttons — ↩ Undo and ↪ Redo — reflect the current stack depth:
they are disabled at stack ends so the user always has visual feedback about what's available.
FASTQ and QUAL export
Two new export buttons — Export FASTQ and Export QUAL — sit alongside the
existing FASTA and PNG/SVG buttons. toFastq() produces a standard four-line FASTQ
record (one record per file, no line-wrapping of sequence or quality). toQual()
emits the NCBI/FASTA-style Phred .qual format with 60 integer scores per line.
Both functions respect the current strand, trim mode, and edits in the same way as
toFasta().
Accessibility
Every span carries an aria-label like "G at position 42 (edited)" so
screen readers announce the base, its 1-based position, and whether it has been modified.
Focus is preserved across an edit cycle: after typing a replacement, the span at the same
display index is re-focused automatically. The undo/redo buttons expose
aria-label with keyboard-shortcut hints in their titles.
Tests
tests/core/editModel.test.ts covers 27 exact-value assertions across every
state transition: basic substitution, applying the original base to clear an edit, multi-position
edits, canUndo/canRedo booleans at each step, multiple undo/redo cycles, quality sentinel
substitution, and reset behaviour.
tests/core/fastq-export.test.ts asserts exact FASTQ record bytes — the
@header, sequence, + separator, and Phred+33-encoded quality string —
for known inputs, including the sentinel ! character, the maximum ~
(score 93), the revcomp header suffix, and trimmed-mode slicing.
tests/e2e/edit-base.e2e.test.ts runs nine Playwright scenarios: editing a base
and asserting the new character and .edited-base class in the panel; asserting
the FASTQ export contains the edit at the correct sequence position with quality !;
undo/redo via toolbar buttons; Ctrl+Z / Ctrl+Shift+Z keyboard shortcuts; disabled-state checks
on undo/redo buttons; basic FASTQ file validity; and accessibility attribute assertions.