@vosjs/editor
v1.3.1
Published
Headless video-editor infrastructure for the vos programmatic video engine — patch-based document store (undo/redo/coalescing), live-edit classifier, editor-mode bridge client (element picking & drag preview), commit helpers, and timeline view-model math.
Maintainers
Readme
@vosjs/editor
Headless editing infrastructure for vos compositions: a patch-based document store with undo, the live-edit classifier, the editor-mode bridge client, element-edit recipes and timeline view-model math.
Part of vos, the open programmatic video engine behind vos.so. These are the mechanisms every vos editor needs, with no UI opinion: apps own their document schema, their lowering and all rendering; this package owns the mechanics. Framework-free; the one dependency is Immer. @vosjs/core is a peer for the bridge types.
Install
pnpm add @vosjs/editorWhat it gives you
createProjectStore(initialDoc, options?). A patch-based document store:get,apply(recipe, { coalesceKey?, label? }),undo,redo,canUndo,canRedo,subscribe((doc, patches) => …). Consecutive edits sharing acoalesceKeywithincoalesceMs(default 400) collapse into one undo entry, which is how a drag becomes one step; a recipe that changes nothing is dropped; the forward patches reach subscribers on every change, so an autosave can ride them.classifyEdit(prev, next, canSetDuration). The live-edit classifier that keeps editing fast. It compares twoLoweredPrograms ({ program, data?, duration?, stack?, tweenEdits? }) and returns the bridge commands to send: a changed program string means a warmLOAD; a data changeSET_DATA; a stack entry's data changeSET_DATA { target }for that entry alone; a tween-overlay changeSET_TWEEN_EDITS; a duration changeSET_DURATIONwhen the player can, elseLOAD. Program-string equality is the structural hash, so a lowering that keeps its program constant gets zero reloads.createEditorBridgeClient(post, { timeoutMs? }). The host side of the engine's editor-mode bridge:hitTest(x, y),getElementRects(),setElementProps(id, props)for ephemeral drag previews,onRects,handleEvent,reset.- Element-edit recipes. Turn an on-canvas gesture into a durable, undoable config patch:
nudgeElementRecipe,scaleElementRecipe,rotateElementRecipe,setTextContentRecipe,setTextStyleRecipe, withcssDeltaToDesign,propsForRectCenter,elementBaseRotationandDESIGN_HEIGHT(1080) for the CSS-to-design-space math. - Timeline view-model math.
toPxandtoTimeover aTimelineViewport,rulerTicks,snapTimewith magnets,formatTime, and theLaneAdaptercontract (items,gesture,magnets) so an app defines its own lanes over its own document.
Example
import { createProjectStore, classifyEdit } from '@vosjs/editor'
const store = createProjectStore(initialDoc, { coalesceMs: 400 })
store.apply(
(draft) => {
draft.duration = 12
},
{ label: 'Set duration' },
)
store.subscribe((doc, patches) => autosave(patches))
// decide how the running player applies a change: no reload for a data edit
const commands = classifyEdit(prevLowered, nextLowered, ready.canSetDuration)
for (const command of commands) player.postMessage(command)License
MIT © vosso
