Switches animation on for one param: its stored keyframes come back, or a first one is made at clipLocalSec from the current value (invalid-argument outside the clip).
Adds a clip of a stored asset to an existing video or audio track; type-mismatch for a track of another kind. Not undoable.
Adds an image track holding a canvas-sized flat colour (any CSS colour) starting at atTimeSec. Not undoable.
Adds an effect from the catalog (transform-not-found otherwise). Recipes (zoom presets) open their window at atClipLocalSec (default 0); other effects ignore it.
Optionaloptions: AddEffectOptionsAdds a text track with one "Text" clip of five seconds at the playhead; change it with updateClip and trimClip. Not undoable.
Adds a text track with one clip per caption, all in style. Not undoable.
A new video or audio track playing an asset that is already in the
project (the source monitor's "Add to Timeline"). Lands after everything
else unless startSec says where.
Optionaloptions: PlaceOptionsOld projects kept opacity on the clip row. Moves it into an Opacity row of the Transform group so the rows are the single owner; the picture does not change. Returns false when there was nothing to move. Not undoable.
Asks the running export to stop, so exportProject rejects with export-cancelled. Nothing happens when none runs.
Whether redo() has a step to replay.
Whether undo() has a step to take back.
Copies the clip with its effects and keyframes to the backend's clipboard. Not undoable.
Switches animation off for one param; its keyframes stay stored so activateKeyframing can bring them back.
The same as deleteClips([clipId]).
Deletes every named clip and the linked partner of each, in one undo step. An unknown id is clip-not-found and nothing is deleted. An empty list changes nothing.
Deletes the keyframe; keyframe-not-found when there is none.
Drop a finished export's MP4 and the project's export folder from browser storage. Call it once the user is done with the result, otherwise every export the user downloads sits in storage for ever. Never rejects, and never before the browser has finished streaming a download from the file.
Cancels queued work, drops every listener and destroys the player. Safe to call twice.
Pastes a copy of the clip right after it on its own track; clip-overlap when the next clip is in the way.
Eases every keyframe lane of every effect on the clip. Returns how many changed.
Eases one lane: the keyframes of one param on one effect. Returns how many changed.
Encodes the timeline, or range, to an MP4 in file storage, reporting export-progress; nothing-to-export when empty, missing-media when a placed file never arrived, export-cancelled after cancelExport(), engine-required headless.
Optionalrange: { endSec: number; startSec: number }The clip on the track playing at timeSec (start inclusive, end exclusive), or undefined.
The text clips showing at the playhead.
The size the preview draws at, or null before the renderer has one.
The clip row, or undefined when there is no such clip.
The rectangle the clip's picture fills on the canvas before its effects, or null when its frame is not loaded.
Every effect on the clip with its definition and keyframes; throws when a definition is missing.
Whether any of types animates on the clip, and whether a keyframe sits at clipLocalSec.
The playhead in seconds; 0 before open().
The timeline length in seconds; 0 before open().
Every effect definition a clip can take, seeded by open().
The outcome of the licence check open() runs once; resolves when it has run.
"invalid" and "localhost" draw a watermark on the preview, renderFrameAt and exports.
Audio tracks being added whose sound is still decoding (a long file takes a while).
audio-loading reports changes.
Every media file stored in the project, placed on the timeline or not.
The state the player last reported; "idle" before open().
The project row. Throws a plain Error when the store has no project with this id.
Videos whose proxy is being made, by asset id, each 0 to 1. Proxies are made
in the background after an import and on open; proxy-progress reports changes.
The clip's effects resolved at the playhead, for the canvas overlay.
The timeline as the panel draws it: tracks, layers, audio, transitions and the duration.
Every transition between two clips of this project.
Whether copyClip has put a clip on the clipboard.
Stores a media file in the project without placing it on the timeline
(the source monitor's Import). probe is what the caller already learned
about the file; it fills the asset row. Not undoable. Works headless.
Stores the file and adds an audio track playing it; audio-loading reports the decode. import-failed when it does not decode. Not undoable.
Optionaloptions: PlaceOptionsFetches a web address into file storage as a stream (never whole into memory),
probes it and adds it like importAsset. type: "audio" keeps only a video's sound.
Cross-origin addresses must allow this page (Access-Control-Allow-Origin).
A failed download is import-failed. Not undoable. Works headless.
Optionaloptions: { type?: "video" | "audio" }Stores the picture and adds an image track showing it; import-failed when it does not decode. Not undoable.
Optionaloptions: PlaceOptionsStores the file and adds a video track playing it, after everything else unless startSec says where; import-failed when it does not decode. Not undoable.
Optionaloptions: PlaceOptionsTrue when constructed without a preview canvas. Engine methods throw in this mode.
Marks a video clip and the audio clip that is its sound as linked. From then on the two move, delete and split together. Refuses clips that are not one video and one audio (type-mismatch) and a clip that is linked already (invalid-argument).
Replaces this project's content with document. resolve gives each asset's file or
a web address; either is written to file storage as a stream. An asset it fails on
loads with missing: true: its clips show a flat placeholder and export refuses
(missing-media). Any other failure leaves the project as it was. Clears undo and redo.
The same as placeClips with one clip kept on its own track.
Moves the keyframe, taking the place of one already at the new time; invalid-argument for a time outside the clip.
Steps the playhead one frame forward at the project frame rate.
Runs the licence check, seeds effect definitions, renumbers an old project's track orders once (see stacking-migration.ts) and loads the project into the player (if a preview is attached). Missing proxies are made in the background afterwards.
Pastes the clipboard clip at atTimeSec; null when the clipboard is empty, type-mismatch for a track of another kind, clip-overlap when it would overlap.
Pauses the preview.
Puts every clip at its placement in one undo step, or refuses and changes nothing: a track of another kind (type-mismatch), a start before zero (invalid-argument), a clip overlapping another on its new track (clip-overlap). Judged on the final layout, so clips moving together may swap places. A transition whose two clips no longer touch on one track is removed in the same step. A linked clip brings its partner: a partner that is not named is placed on its own track shifted by the same seconds, and a pair named with two different shifts is refused (invalid-argument).
Starts the preview and emits preview-played.
Engine-only, not persisted: shows a drag in progress. Cleared by the next persisted change.
Steps the playhead one frame back at the project frame rate.
The media file behind an asset (for waveforms and transcription). Works headless.
The asset's proxy when it has one, else the original: lighter to preview. Works headless.
The finished MP4 an export left behind (ExportResult.opfsPath), for the download button.
Replays the latest undone step; does nothing when there is none.
Removes the effect and its keyframes; effect-not-found when there is none.
Removes the track and its clips. The partner of a linked clip on it is unlinked, since its clip is gone.
Removes the transition; transition-not-found when there is none.
Sets the project name as given; nothing is checked.
null or an empty string clears the name back to the default. Trimmed, at most 60 characters.
Composes one frame at the preview size: a slow cold path for tests and thumbnails, not scrubbing. invalid-argument before 0; engine-required headless.
orderedClipTransformIds must name every effect on the clip exactly once.
frontToBack must name every visual track of the project exactly once,
front first, which is the order the timeline shows. Writes new orders so the
picture matches. Refuses audio tracks (type-mismatch) and incomplete or
repeated lists (invalid-argument). No undo step and no event when nothing changes.
Writes only the touched style properties onto each text clip, leaving the rest of every clip's style alone. One undo step. Returns how many clips changed.
The project as plain JSON, plus one manifest entry per stored media file. An entry's
read() hands back a handle to the stored file, never its bytes.
Moves the playhead to timeSec.
Fixes the output size in pixels; null lets the canvas follow the first video again.
Persists the Transform group rows for changed. A type that is animated
gets a keyframe at atClipLocalSec; one that is not gets a static value
(mode "auto"). "keyframe" always keyframes, "static" always freezes.
Optionaloptions: SetClipGeometryOptionsMerges params over the effect's stored params (a key set to undefined
is removed). With record: false the write is a live preview: no undo
step; the next recorded write on the same effect undoes back to the params
from before the first preview.
Optionaloptions: SetEffectParamsOptionsSets the clip-local span the effect applies over; invalid-argument when it starts before 0 or ends before it starts.
Sets the frame rate used for frame stepping and export; nothing is checked.
Adds a keyframe, or changes the one already at that time, and returns its id; invalid-argument for a non-finite value, an unknown easing or a time outside the clip.
Optionaleasing: stringSets the keyframe's easing; invalid-argument for an unknown easing name.
Switches looping over the work area on or off.
Sets the preview speed, 1 being normal.
Which text clip the preview outlines as selected; null for none.
Visual tracks only (type-mismatch for audio, which keeps its mute). A hidden track is not drawn.
Shifts the whole track so it starts at startSec; a text track moves its first clip. Not undoable.
Sets the track's volume; type-mismatch for anything but an audio track. Not undoable.
Sets or replaces the transition between two clips that meet on one track, trimming a clip to make footage when needed; invalid-argument when they do not meet, have no media or the duration does not fit.
Sets the range to play and export. A first range switches looping on; null clears the range and the loop.
The project with ids replaced by stable labels and numbers rounded, for comparing in tests.
Cuts the clip in two at timelineSec and returns the new second half. A linked clip
whose partner is also cut by that time is split with it, and the two new halves are
linked to each other. One undo step. invalid-split when the cut is too near an edge.
Hears every event the backend emits; returns the function that unsubscribes.
Transcribes the clip's sound on the device and adds a text track of captions, returning how many (none: no track). invalid-argument for a clip without media; engine-required headless.
Trims this one clip only; a linked partner is left alone so sound and picture can be cut apart.
Takes back the latest undo step and refreshes everything; does nothing when there is none.
Breaks the link the clip is in. Refuses a clip that is not linked (invalid-argument).
Writes the given clip fields as one undo step named label; nothing but the clip's existence is checked.
Optionallabel: string
The one door between the editor UI (or a test, or a coding agent) and the project. Times are seconds. Every method that changes the project is async, runs on the backend's serial queue, is undoable unless stated, and ends by emitting an event. Reads that hit the store are async; reads of engine state are sync.
The design lives in design-docs/video-editor/agent-interface/backend.md.