docs: correct three source-contradiction findings from review

- edit-operations: E_NO_GSAP_TIMELINE is raised only by addGsapTween and addLabel
  (mutate.ts:1747), not the set/remove tween ops; drop the false 'dispatch() still
  applies structurally' claim (mutate.gsap.test.ts verifies zero patches); add the
  requirement to the Labels section where addLabel lives.
- html-schema: data-media-start is read by parser + timing compiler + runtime;
  data-playback-start is a runtime-only alias, so a lone playback-start doesn't
  shift trim/split. Document the surfaces instead of claiming one universal value.
- testing-local-changes: bun unlink cleanup used a relative cd that resolves under
  the video project; use an absolute checkout path.

Flagged by Magi (P1 #2/#3, P2 #7) and Rames.
This commit is contained in:
ukimsanov
2026-08-05 05:43:35 -07:00
parent 6ff6601dd0
commit 0f6259d461
3 changed files with 11 additions and 6 deletions
+4 -3
View File
@@ -42,11 +42,12 @@ hyperframes preview
```
Remove the link when finished. `bun unlink` takes no package name — it
unregisters whichever directory you run it from, so go back to the CLI package
first:
unregisters whichever directory you run it from, so go back to the CLI package in
your HyperFrames checkout first (an absolute path, since you are now inside the
video project):
```bash
cd packages/cli
cd /path/to/hyperframes/packages/cli
bun unlink
```
+1 -1
View File
@@ -122,7 +122,7 @@ Audio has no visual lifecycle.
| Attribute | Applies to | Meaning |
| --- | --- | --- |
| `data-playback-start`<br />(alias: `data-media-start`) | Video, audio, nested composition | Offset into the source file, used by trim and split. The two names are one value — `data-playback-start` wins if both are set. |
| `data-media-start`<br />(runtime alias: `data-playback-start`) | Video, audio, nested composition | Offset into the source file, used by trim and split. Prefer `data-media-start`: it is read everywhere — parser, timing compiler, and runtime. `data-playback-start` is a runtime-only alias that takes precedence in the player when both are set, but the compiler and parser read only `data-media-start`, so a lone `data-playback-start` will not shift trim/split timing. |
| `data-playback-rate` | Video, audio, nested composition | Playback multiplier from `0.1` to `5` |
| `data-volume` | Video and audio | Static volume from `0` to `1` |
| `data-has-audio="true"` | Video | Declares that the video contributes audio |
+6 -2
View File
@@ -76,7 +76,7 @@ Stable `code` values for `ok: false`:
| `E_NO_GSAP_SCRIPT` | Op requires a GSAP `<script>` block; none found in the document. |
<Note>
These ops need a timeline to attach to. If the composition's GSAP script has no `gsap.timeline()` declaration, `can()` returns `{ ok: false, code: 'E_NO_GSAP_TIMELINE' }` add `var tl = gsap.timeline(...)` and it succeeds. `dispatch()` still applies the op structurally even when `can()` returns false.
`E_NO_GSAP_TIMELINE` is raised by the two ops that attach to a timeline — `addGsapTween` and `addLabel`. If the composition's GSAP script has no `gsap.timeline()` declaration, `can()` returns `{ ok: false, code: 'E_NO_GSAP_TIMELINE' }`; add `var tl = gsap.timeline(...)` and it succeeds. Don't `dispatch()` after a failed `can()` — a rejected op applies nothing (no patches, script unchanged).
</Note>
See also: [`Composition`](/sdk/reference/composition) for the typed-method wrappers, [`Types`](/sdk/reference/types) for `CanResult` and `EditOp`.
@@ -318,7 +318,7 @@ comp.dispatch({ type: "removeVariable", id: "brandColor" });
These ops add, edit, and remove GSAP tween entries in the composition's GSAP script block. They operate by `animationId` — a stable string identifier minted when a tween is created. Use `comp.addGsapTween()` or `addWithKeyframes` to mint a new id; the typed wrapper returns it directly.
<Note>
These ops attach to a timeline. Without a `gsap.timeline()` declaration in the script, `can()` returns `{ ok: false, code: 'E_NO_GSAP_TIMELINE' }` declare one and retry. `dispatch()` still applies the op structurally.
Only `addGsapTween` here needs a `gsap.timeline()` to attach to — without one, `can()` returns `{ ok: false, code: 'E_NO_GSAP_TIMELINE' }`, so declare a timeline and retry. `setGsapTween`, `removeGsapTween` and `removeGsapProperty` edit or remove an existing tween and don't require it. A failed `can()` means `dispatch()` applies nothing.
</Note>
| `type` | Key fields | What it does |
@@ -485,6 +485,10 @@ GSAP timeline labels mark named positions (in seconds) in the master timeline. L
| `addLabel` | `name`, `position` | Adds a named label at a timeline position (seconds). |
| `removeLabel` | `name` | Removes a named label. |
<Note>
Like `addGsapTween`, `addLabel` attaches to a timeline: without a `gsap.timeline()` declaration in the script, `can()` returns `{ ok: false, code: 'E_NO_GSAP_TIMELINE' }`. `removeLabel` has no such requirement.
</Note>
```typescript
comp.dispatch({ type: "addLabel", name: "intro", position: 0 });
comp.dispatch({ type: "addLabel", name: "outro", position: 8 });