Files
suaveplan/packages/media/audio/audio-timeline/src/operations/timeline-operations/timeline-operations.md
2026-05-27 23:47:53 +01:00

2.3 KiB

Timeline Operations

(no submodules)

Purpose

The timeline-operations.ts module handles view-state mutations that do not affect the audio arrangement and therefore do not push undo commands. These helpers operate on TimelineState snapshots and return partial updates that the engine merges into its internal state. Keeping view logic separate from arrangement logic makes the engine easier to reason about and test.

Features

  • setSelection normalises reversed ranges and clamps to document duration
  • setLoopRegion updates loop boundaries without clamping
  • zoomIn / zoomOut step through a discrete zoom table
  • setZoomLevel snaps arbitrary samplesPerPixel values to the table

Usage

Basic

import { setSelection, setLoopRegion } from "@suaveplan/audio-timeline/operations";

const sel = setSelection(state, 100, 50); // normalises to 50..100
const loop = setLoopRegion(state, 0, 5000);

Advanced

import { zoomIn, zoomOut, setZoomLevel } from "@suaveplan/audio-timeline/operations";

const z1 = zoomIn(zoomTable, 3); // { zoomIndex: 4, samplesPerPixel: 16 }
const z2 = setZoomLevel(zoomTable, 150); // snaps to 128

API Reference

Export Signature Description
setSelection (state, start, end) => { selectionStart, selectionEnd } Normalise and clamp
setLoopRegion (state, start, end) => { loopStart, loopEnd } Set loop bounds
zoomIn (table, index) => { zoomIndex, samplesPerPixel } Step in
zoomOut (table, index) => { zoomIndex, samplesPerPixel } Step out
setZoomLevel (table, spp) => { zoomIndex, samplesPerPixel } Snap to table

Implementation Notes

Zoom and selection are purely view state; they are not part of the undo history because users expect zoom gestures to be ephemeral. Keeping these helpers pure makes them trivial to unit-test without instantiating a full TimelineEngine. The clamping logic in setSelection guarantees that consumers always read selectionStart <= selectionEnd, even when the user drags the selection backwards. Loop boundaries are not clamped because the engine may allow loops that extend beyond the current document length for live expansion workflows.