From aff1476aba8cd171d481de0ffcdbb1562bbfe271 Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Sat, 19 Sep 2026 06:06:41 -0400 Subject: [PATCH] feat(core): video, audio and image length come from one shared resolver A new resolver in @hyperframes/parsers decides how long a video, audio or image occupies the timeline. The core runtime start resolver, clip manifest and clip tree now read length through it. An image with data-start and no data-duration gets the dropped-image default of 3 seconds; a bare image stays a static layer. Video and audio take their length from the file until an authored duration trims it. The playback rate bound (0.1 to 10) now lives in parsers, and core re-exports it. A rate lane keeps its own arithmetic in core. The lint rule that asked images for data-duration is removed, and the docs no longer say an image requires it. --- docs/reference/html-schema.mdx | 2 +- packages/core/docs/core.md | 2 +- packages/core/src/playbackRateBounds.ts | 4 +- packages/core/src/runtime/clipTree.test.ts | 11 ++ packages/core/src/runtime/clipTree.ts | 14 +- .../core/src/runtime/playbackRate.test.ts | 72 ++++++++++ packages/core/src/runtime/playbackRate.ts | 93 +++++++------ .../core/src/runtime/startResolver.test.ts | 21 +++ packages/core/src/runtime/startResolver.ts | 16 +-- packages/core/src/runtime/timeline.test.ts | 36 +++++ packages/core/src/runtime/timeline.ts | 2 + .../lint/src/rules/structure.catalog.test.ts | 1 - packages/lint/src/rules/structure.test.ts | 21 +-- packages/lint/src/rules/structure.ts | 33 ++--- packages/parsers/package-subpaths.json | 12 ++ packages/parsers/package.json | 20 +++ packages/parsers/src/index.ts | 1 + packages/parsers/src/mediaDuration.test.ts | 123 +++++++++++++++++ packages/parsers/src/mediaDuration.ts | 129 ++++++++++++++++++ packages/parsers/src/mediaDurationFixtures.ts | 91 ++++++++++++ packages/parsers/tsup.config.ts | 2 + skills-manifest.json | 2 +- .../references/data-attributes.md | 18 +-- 23 files changed, 619 insertions(+), 107 deletions(-) create mode 100644 packages/parsers/src/mediaDuration.test.ts create mode 100644 packages/parsers/src/mediaDuration.ts create mode 100644 packages/parsers/src/mediaDurationFixtures.ts diff --git a/docs/reference/html-schema.mdx b/docs/reference/html-schema.mdx index 883888ad3d..e11aa8d93f 100644 --- a/docs/reference/html-schema.mdx +++ b/docs/reference/html-schema.mdx @@ -96,7 +96,7 @@ unbounded animation, and timeline-free compositions need an explicit duration. | --- | --- | --- | | `id` | Yes | Stable identifier for timing, editing, and animation | | `data-start` | Yes | Start in seconds or a relative timing expression | -| `data-duration` | Yes for DOM, image, and nested-composition clips | Visible slot length in seconds | +| `data-duration` | Yes for DOM and nested-composition clips; optional for image (3 s default), video and audio (source length) | Visible slot length in seconds | | `data-track-index` | No | Studio timeline lane, display only. The render never reads it and it does not prevent overlap | | `class="clip"` | Recommended for authored timed DOM and image elements | Layout and tooling convention. Visibility is keyed off `data-start`, but the shared `.clip` rule supplies the full-frame box | diff --git a/packages/core/docs/core.md b/packages/core/docs/core.md index 262094d20d..2ec22dfdc1 100644 --- a/packages/core/docs/core.md +++ b/packages/core/docs/core.md @@ -183,7 +183,7 @@ A clip is any discrete block on the timeline. We represent clips as HTML element - `id` — Unique identifier (e.g., "el-1") - `data-start` — Start time in seconds, or a clip `id` reference. See [Relative Timing](#relative-timing). -- `data-duration` — Duration in seconds. Required for `` clips. Optional for `