These libraries are experimental. APIs may change without notice. Generated from source with koruc 0.1.7 on 11/4/2026.

Composition

@korulang/composition@0.0.1

Time-first composition model — objects placed in global wall-clock time, tempo as beats→seconds convenience, magnetic references as phantom obligations — plus a renderer-agnostic seconds→Rect projection surface

composition/index.kz · 19 tors

@korulang/composition — time-first object model + renderer-agnostic projection. · 24 more lines
@korulang/composition — time-first object model + renderer-agnostic projection. Ported from Intranquil's composition/layout laws: the timeline is NOT the base reality; global wall-clock time is. Timelines are objects placed in time; clips live inside timelines; tempo is a beats→seconds convenience; a magnetic reference makes a timeline's start DERIVED — the <bound> obligation means moving it by hand is unexpressible, and only a comp.follow leader can relocate it. Two surfaces in one module: MODEL comp/tempo/timeline/clip/follow/shift/resolve — pure seconds. PROJECTION view/proj — seconds → pixels. Emits Rect; knows nothing about Metal, vaxis, or any renderer. The draw surface is the consumer's seam — a metal ! frame arm, a terminal cell fill, an SVG emitter all consume the same Rect. Known toolchain gaps this package currently exposes (do NOT route around): - 330_136: per-arg phantom checking is skipped for part-declared tors. Package tors are module-declared, so <bound> enforcement at the call site is measured working for imports — keep it that way. - User type named `Item` collides with injected ast.Item when a consumer merges parts into one module — this package's type is Clip (which is also the better canvas word: .graph-clip).

Phantom lifecycles

Derived from the phantom labels in the declarations below — state! issues an obligation the compiler will chase, !state discharges it, a bare state holds it without moving it. Nothing here is hand-drawn.

Composition 2 states open!resolved!
Timeline 2 states free!bound!

comp.new

<open!> index.kz:122

comp.resolve

<!open|!resolved><resolved!> index.kz:123

tempo.new

index.kz:142

timeline.new

<open|resolved><free!> index.kz:153

clip.new

<free|bound> index.kz:180

comp.follow

<open|resolved><!free><free|bound><bound!> index.kz:206

timeline.shift

<free> index.kz:224

timeline.release

<open|resolved><!free|!bound> index.kz:232

comp.free

<!open|!resolved> index.kz:248

resolve.timeline-start

<free|bound> index.kz:255

resolve.timeline-end

<free|bound> index.kz:260

resolve.clip-start

<free|bound> index.kz:265

resolve.clip-abs-start

<free|bound> index.kz:270

view.new

index.kz:280

view.pan

index.kz:287

view.zoom

index.kz:292

proj.timeline-rect

<free|bound> index.kz:305

proj.clip-rect

<free|bound> index.kz:317