frameyard 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/GLOSSARY.md +46 -2
  3. package/README.md +174 -106
  4. package/dist/bindings.d.ts +42 -0
  5. package/dist/bindings.d.ts.map +1 -0
  6. package/dist/bindings.js +144 -0
  7. package/dist/bindings.js.map +1 -0
  8. package/dist/cli.js +32 -21
  9. package/dist/cli.js.map +1 -1
  10. package/dist/composition/adapter.d.ts +30 -0
  11. package/dist/composition/adapter.d.ts.map +1 -0
  12. package/dist/composition/adapter.js +2 -0
  13. package/dist/composition/adapter.js.map +1 -0
  14. package/dist/composition/animation.d.ts +19 -0
  15. package/dist/composition/animation.d.ts.map +1 -0
  16. package/dist/composition/animation.js +55 -0
  17. package/dist/composition/animation.js.map +1 -0
  18. package/dist/composition/attributes.d.ts +7 -0
  19. package/dist/composition/attributes.d.ts.map +1 -0
  20. package/dist/composition/attributes.js +24 -0
  21. package/dist/composition/attributes.js.map +1 -0
  22. package/dist/composition/descriptor.d.ts +30 -0
  23. package/dist/composition/descriptor.d.ts.map +1 -0
  24. package/dist/composition/descriptor.js +188 -0
  25. package/dist/composition/descriptor.js.map +1 -0
  26. package/dist/composition/diagnostics.d.ts +12 -0
  27. package/dist/composition/diagnostics.d.ts.map +1 -0
  28. package/dist/composition/diagnostics.js +38 -0
  29. package/dist/composition/diagnostics.js.map +1 -0
  30. package/dist/composition/index.d.ts +12 -0
  31. package/dist/composition/index.d.ts.map +1 -0
  32. package/dist/composition/index.js +7 -0
  33. package/dist/composition/index.js.map +1 -0
  34. package/dist/composition/media.d.ts +27 -0
  35. package/dist/composition/media.d.ts.map +1 -0
  36. package/dist/composition/media.js +162 -0
  37. package/dist/composition/media.js.map +1 -0
  38. package/dist/composition/paths.d.ts +5 -0
  39. package/dist/composition/paths.d.ts.map +1 -0
  40. package/dist/composition/paths.js +16 -0
  41. package/dist/composition/paths.js.map +1 -0
  42. package/dist/composition/transcripts.d.ts +19 -0
  43. package/dist/composition/transcripts.d.ts.map +1 -0
  44. package/dist/composition/transcripts.js +57 -0
  45. package/dist/composition/transcripts.js.map +1 -0
  46. package/dist/composition/walk.d.ts +10 -0
  47. package/dist/composition/walk.d.ts.map +1 -0
  48. package/dist/composition/walk.js +32 -0
  49. package/dist/composition/walk.js.map +1 -0
  50. package/dist/contracts.d.ts +75 -47
  51. package/dist/contracts.d.ts.map +1 -1
  52. package/dist/contracts.js +14 -159
  53. package/dist/contracts.js.map +1 -1
  54. package/dist/errors.d.ts +15 -4
  55. package/dist/errors.d.ts.map +1 -1
  56. package/dist/errors.js +8 -0
  57. package/dist/errors.js.map +1 -1
  58. package/dist/html/document-adapter.d.ts +5 -0
  59. package/dist/html/document-adapter.d.ts.map +1 -0
  60. package/dist/html/document-adapter.js +17 -0
  61. package/dist/html/document-adapter.js.map +1 -0
  62. package/dist/html/index.d.ts +5 -0
  63. package/dist/html/index.d.ts.map +1 -0
  64. package/dist/html/index.js +3 -0
  65. package/dist/html/index.js.map +1 -0
  66. package/dist/html/parse.d.ts +26 -0
  67. package/dist/html/parse.d.ts.map +1 -0
  68. package/dist/html/parse.js +80 -0
  69. package/dist/html/parse.js.map +1 -0
  70. package/dist/html/validate.d.ts +14 -0
  71. package/dist/html/validate.d.ts.map +1 -0
  72. package/dist/html/validate.js +648 -0
  73. package/dist/html/validate.js.map +1 -0
  74. package/dist/index.d.ts +2 -2
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +1 -1
  77. package/dist/index.js.map +1 -1
  78. package/dist/preview/main.d.ts +10 -3
  79. package/dist/preview/main.d.ts.map +1 -1
  80. package/dist/preview/main.js +189 -89
  81. package/dist/preview/main.js.map +1 -1
  82. package/dist/project.d.ts +2 -0
  83. package/dist/project.d.ts.map +1 -1
  84. package/dist/project.js +4 -0
  85. package/dist/project.js.map +1 -1
  86. package/dist/renderer/browser.d.ts +11 -1
  87. package/dist/renderer/browser.d.ts.map +1 -1
  88. package/dist/renderer/browser.js +93 -14
  89. package/dist/renderer/browser.js.map +1 -1
  90. package/dist/renderer/index.d.ts +25 -5
  91. package/dist/renderer/index.d.ts.map +1 -1
  92. package/dist/renderer/index.js +82 -16
  93. package/dist/renderer/index.js.map +1 -1
  94. package/dist/runtime/bindings.d.ts +11 -0
  95. package/dist/runtime/bindings.d.ts.map +1 -0
  96. package/dist/runtime/bindings.js +164 -0
  97. package/dist/runtime/bindings.js.map +1 -0
  98. package/dist/runtime/diagnostics.d.ts +4 -0
  99. package/dist/runtime/diagnostics.d.ts.map +1 -0
  100. package/dist/runtime/diagnostics.js +107 -0
  101. package/dist/runtime/diagnostics.js.map +1 -0
  102. package/dist/runtime/document-adapter.d.ts +4 -0
  103. package/dist/runtime/document-adapter.d.ts.map +1 -0
  104. package/dist/runtime/document-adapter.js +19 -0
  105. package/dist/runtime/document-adapter.js.map +1 -0
  106. package/dist/runtime/host.d.ts +14 -0
  107. package/dist/runtime/host.d.ts.map +1 -0
  108. package/dist/runtime/host.js +596 -0
  109. package/dist/runtime/host.js.map +1 -0
  110. package/dist/runtime/index.d.ts +0 -29
  111. package/dist/runtime/index.d.ts.map +1 -1
  112. package/dist/runtime/index.js +0 -360
  113. package/dist/runtime/index.js.map +1 -1
  114. package/dist/runtime/media.d.ts.map +1 -1
  115. package/dist/runtime/media.js +20 -51
  116. package/dist/runtime/media.js.map +1 -1
  117. package/dist/scaffold.d.ts.map +1 -1
  118. package/dist/scaffold.js +177 -84
  119. package/dist/scaffold.js.map +1 -1
  120. package/dist/server/composition-html.d.ts +20 -0
  121. package/dist/server/composition-html.d.ts.map +1 -0
  122. package/dist/server/composition-html.js +45 -0
  123. package/dist/server/composition-html.js.map +1 -0
  124. package/dist/server/preview-html.d.ts.map +1 -1
  125. package/dist/server/preview-html.js +19 -14
  126. package/dist/server/preview-html.js.map +1 -1
  127. package/dist/server/server.d.ts.map +1 -1
  128. package/dist/server/server.js +94 -6
  129. package/dist/server/server.js.map +1 -1
  130. package/dist/version.d.ts +1 -1
  131. package/dist/version.js +1 -1
  132. package/docs/adr/0001-keep-composition-authoring-web-native.md +2 -0
  133. package/docs/adr/0006-seek-embedded-media-from-the-frame-clock.md +7 -1
  134. package/docs/adr/0007-make-html-documents-the-composition-unit.md +31 -0
  135. package/docs/adr/0008-share-the-composition-document-grammar.md +18 -0
  136. package/docs/adr/0009-composite-production-frames-in-software.md +37 -0
  137. package/docs/migration-0.4.md +279 -0
  138. package/docs/v0.1-design.md +78 -56
  139. package/examples/demo/README.md +8 -4
  140. package/examples/demo/compositions/demo.controller.js +120 -0
  141. package/examples/demo/compositions/demo.html +253 -0
  142. package/examples/demo/video.config.js +1 -1
  143. package/examples/video/README.md +61 -0
  144. package/examples/video/assets/clip.mp4 +0 -0
  145. package/examples/video/assets/clip.webm +0 -0
  146. package/examples/video/compositions/video-mp4.html +362 -0
  147. package/examples/video/compositions/video.html +362 -0
  148. package/examples/video/props/video.json +8 -0
  149. package/examples/video/scripts/make-clip.sh +109 -0
  150. package/examples/video/video.config.js +6 -0
  151. package/examples/webgl/README.md +30 -0
  152. package/examples/webgl/compositions/webgl.controller.js +200 -0
  153. package/examples/webgl/compositions/webgl.html +215 -0
  154. package/examples/webgl/props/webgl.json +6 -0
  155. package/examples/webgl/video.config.js +5 -0
  156. package/package.json +7 -3
  157. package/skills/frameyard/README.md +4 -0
  158. package/skills/frameyard/SKILL.md +40 -12
  159. package/skills/frameyard/references/audio-assets.md +25 -14
  160. package/skills/frameyard/references/bindings.md +73 -0
  161. package/skills/frameyard/references/common-mistakes.md +59 -0
  162. package/skills/frameyard/references/controllers.md +126 -0
  163. package/skills/frameyard/references/deterministic-authoring.md +143 -52
  164. package/skills/frameyard/references/diagnostics.md +90 -0
  165. package/skills/frameyard/references/failure-recovery.md +37 -14
  166. package/skills/frameyard/references/json-results.md +43 -9
  167. package/skills/frameyard/references/subtitles-karaoke.md +10 -18
  168. package/examples/demo/compositions/demo.js +0 -206
package/CHANGELOG.md CHANGED
@@ -8,6 +8,123 @@ Frameyard uses `0.x` versions until the composition, configuration, CLI,
8
8
  JSON-result, transcript, and skill contracts stabilize. Before `1.0.0`, a
9
9
  contract change may ship in a minor release and is called out explicitly below.
10
10
 
11
+ ## [0.5.0] - 2026-10-31
12
+
13
+ ### Added
14
+
15
+ - `examples/webgl/` demonstrates a frame-seeked WebGL shader driven by an
16
+ external controller.
17
+ - `examples/video/` demonstrates two-pass embedded video with the same
18
+ composition rendered from WebM and MP4 sources, plus a script that
19
+ regenerates both clips with FFmpeg.
20
+ - `test/examples.test.ts` captures a still from every bundled example.
21
+ - `pnpm compare-stills <a.png> <b.png>` reports an exact decoded-pixel diff and
22
+ exits nonzero on any difference, for checking determinism at the capture
23
+ boundary.
24
+ - The benchmark adds WebGL and embedded-video fixtures, `--concurrency`, and
25
+ bench-only `--browser-arg`/`--no-browser-arg` A/B runs. `bench/README.md`
26
+ documents the measurement recipe.
27
+
28
+ ### Changed
29
+
30
+ - `render` no longer requires `--out`. The default output is
31
+ `out/<composition-id>.mp4` inside the project root, and scaffolded projects
32
+ ignore `out/` in `.gitignore`.
33
+ - Production capture composites frames in software while WebGL remains on
34
+ SwiftShader, and opens and closes parallel browser sessions concurrently.
35
+ Sequential and `--concurrency 4` renders are substantially faster; capture
36
+ timing and pixels can change for existing projects. Determinism remains at
37
+ the capture boundary for the same pinned runtime and inputs. See
38
+ [ADR 0009](./docs/adr/0009-composite-production-frames-in-software.md).
39
+ - Static validation, the composition host, and preview share one browser-safe
40
+ composition descriptor for metadata, props, controller, animation, media, and
41
+ transcript declarations. This is an internal refactor with no authoring
42
+ contract change.
43
+
44
+ ### Fixed
45
+
46
+ - Embedded video seeks 1 ms past the frame time so millisecond-rounded WebM
47
+ timestamps select the intended source frame.
48
+ - Capture sessions stay hidden until the first seek, so an animated ancestor
49
+ cannot leave the load frame on screen in the captured still.
50
+
51
+ [0.5.0]: https://github.com/vladiantio/frameyard/compare/v0.4.0...v0.5.0
52
+
53
+ ## [0.4.0] - 2026-10-30
54
+
55
+ ### Breaking
56
+
57
+ - **Composition authoring model:** compositions are HTML documents, not
58
+ JavaScript modules. `video.config.js` entries point to `.html` files, and the
59
+ public `defineComposition` authoring path is removed. The `mount → update →
60
+ dispose` lifecycle remains only as the optional controller contract.
61
+ - **Authoring namespace:** `fy-composition`, `fy-transcript`, `data-fy-*`,
62
+ `--fy-*`, and `text/fy-controller` replace the corresponding
63
+ `frameyard`/`data-frameyard-*` names. Existing embedded-media attributes move
64
+ from `data-frameyard-*` to `data-fy-*`.
65
+ - **Executable code:** only the optional controller, inline or external, may
66
+ execute. Other executable `<script>` elements and inline `on*` handlers are
67
+ rejected.
68
+ - **Validation and karaoke:** domain validation and subtitle/karaoke rendering
69
+ move to the optional controller; no built-in subtitle renderer is added.
70
+ - **Diagnostics:** warnings are structured diagnostic objects with `severity`,
71
+ `code`, `message`, and optional `details`, not plain strings. Error envelopes
72
+ gain optional `error.details` and top-level `diagnostics`. Unsupported visual
73
+ elements inside a composition (`iframe`, `object`, `embed`) and `javascript:`
74
+ URLs are rejected.
75
+
76
+ ### Added
77
+
78
+ - Declarative HTML composition contract: `<fy-composition>` metadata, a
79
+ `data-fy="props"` default-props block, `data-fy-text`, `data-fy-attr-*`,
80
+ `data-fy-class-*`, `data-fy-if`, and `data-fy-repeat` bindings.
81
+ - Frame-scheduled CSS animation with `data-fy-anim-start`,
82
+ `data-fy-anim-duration`, and `data-fy-anim-easing`, plus `--fy-frame`,
83
+ `--fy-time`, `--fy-progress`, `--fy-fps`, and `--fy-duration` frame-state
84
+ variables.
85
+ - Optional composition controller, inline or external, with `mount`, `update`,
86
+ `dispose`, and `validateProps`. Inline controllers are extracted and served
87
+ through a virtual module URL so relative imports and `import.meta.url` work.
88
+ - Node-side static composition validation before Chromium in `check`, `still`,
89
+ and `render`, and on load in `dev`, with source-located diagnostics.
90
+ - Binding, animation, script, event-handler, unsupported-element, and
91
+ asset-reference validation.
92
+ - `entry`, `controller`, and top-level `diagnostics` in `check`, `still`, and
93
+ `render` JSON results.
94
+ - Agent-facing minimal skeleton, binding table, controller examples, and
95
+ common-mistakes guidance in the skill and scaffold.
96
+ - Injected composition host exposing `window.__fy` with metadata, resolved
97
+ audio/transcript clips, `load`, `seek`, `settle`, and `dispose`.
98
+ - HTML `<audio>` and `<fy-transcript>` declarations for the audio timeline and
99
+ transcript requirements.
100
+ - Same-origin iframe preview and a direct render/check/still path that share
101
+ the host API.
102
+
103
+ ### Changed
104
+
105
+ - Preview loads each composition document in a same-origin iframe; `check`,
106
+ `still`, and `render` navigate directly to the composition URL. The separate
107
+ preview-page render path is removed.
108
+ - Static validation and the composition host read metadata, default props,
109
+ controller declarations, animation, media, and transcript rules through one
110
+ browser-safe composition document reader. Controller `src` is project-relative
111
+ in host output; the authoring value is retained as `rawSrc`.
112
+ - `check` fails fast on static errors without launching Chromium; warnings
113
+ still allow frame evaluation. Nested `data-fy-repeat` is rejected with a
114
+ clear diagnostic; nested data uses the controller.
115
+ - `init` scaffolds an HTML composition and no longer generates a JavaScript
116
+ composition module.
117
+ - The agent skill, README, design baseline, and project guides document the
118
+ HTML model. See [the 0.4 migration guide](./docs/migration-0.4.md).
119
+
120
+ ### Removed
121
+
122
+ - JavaScript composition modules, `defineComposition`, and the
123
+ `data-frameyard-*` authoring attributes.
124
+ - The preview-page composition loading path used by the renderer.
125
+
126
+ [0.4.0]: https://github.com/vladiantio/frameyard/compare/v0.3.0...v0.4.0
127
+
11
128
  ## [0.3.0] - 2026-10-30
12
129
 
13
130
  ### Added
package/GLOSSARY.md CHANGED
@@ -18,14 +18,42 @@ _Avoid_: Scene, template, video
18
18
  The fixed dimensions, frame rate, and duration in frames that define a composition's output contract.
19
19
  _Avoid_: Render options, props
20
20
 
21
+ **Composition descriptor**:
22
+ The fixed facts read from an HTML composition before frame production: composition metadata, default props, and the controller declaration. It excludes per-load declarations such as audio clips, transcripts, and animation schedules.
23
+ _Avoid_: Composition config, parsed document
24
+
21
25
  **Composition lifecycle**:
22
- The `mount → update → dispose` sequence that governs a composition's frame production.
26
+ The host-driven sequence that loads an HTML composition, seeks it to frames, and releases it.
23
27
  _Avoid_: Render loop, playback lifecycle
24
28
 
29
+ **Controller lifecycle**:
30
+ The `mount → update → dispose` sequence a composition controller uses for per-frame computation.
31
+ _Avoid_: Composition lifecycle
32
+
25
33
  **Composition revision**:
26
34
  A specific version of a composition's source and metadata.
27
35
  _Avoid_: Build, release
28
36
 
37
+ **HTML composition**:
38
+ A composition whose source is an HTML document.
39
+ _Avoid_: HTML template, page
40
+
41
+ **Composition controller**:
42
+ An optional JavaScript controller, either inline in the composition document or in an external module, that performs per-frame computation an HTML composition's declarative HTML and CSS cannot express.
43
+ _Avoid_: Composition module, plugin
44
+
45
+ **Inline controller**:
46
+ A composition controller whose source is embedded in the composition document.
47
+ _Avoid_: Embedded script
48
+
49
+ **External controller**:
50
+ A composition controller whose source is a separate JavaScript module referenced by the composition document.
51
+ _Avoid_: Controller file
52
+
53
+ **Declarative binding**:
54
+ An HTML attribute that maps a prop into text, an attribute, a class, or element presence.
55
+ _Avoid_: Template expression, interpolation
56
+
29
57
  **Props**:
30
58
  The immutable, JSON-serializable inputs supplied to a composition for one render.
31
59
  _Avoid_: Options, settings, mutable state
@@ -48,6 +76,10 @@ _Avoid_: Playback-driven animation
48
76
  The single source of animation time, derived from the current frame and the composition's frame rate.
49
77
  _Avoid_: Wall clock, playback timer
50
78
 
79
+ **Frame-state variable**:
80
+ A CSS custom property whose value is derived from the current composition frame.
81
+ _Avoid_: Animation variable, clock variable
82
+
51
83
  **Seek safety**:
52
84
  The property that any frame can be produced correctly without depending on previously produced frames.
53
85
  _Avoid_: History-dependent updates
@@ -88,14 +120,26 @@ _Avoid_: Soundtrack, audio track, final cut
88
120
 
89
121
  ### Rendering
90
122
 
123
+ **Composition host**:
124
+ The injected runtime that loads an HTML composition, applies its bindings, and exposes its frame clock to preview and render.
125
+ _Avoid_: Preview runtime, render runtime
126
+
91
127
  **Preview**:
92
128
  An interactive, frame-accurate inspection of a composition using the same composition behavior as a render.
93
129
  _Avoid_: Visual editor
94
130
 
95
131
  **Check**:
96
- A validation operation that checks configuration, props, assets, audio, and transcript requirements, then mounts a composition and evaluates every frame without capturing or encoding.
132
+ A validation operation that first runs static composition validation, then loads a composition and evaluates every frame without capturing or encoding.
97
133
  _Avoid_: Test render, dry run
98
134
 
135
+ **Static composition validation**:
136
+ The Node-side validation of a composition document's metadata, bindings, controller declaration, scripts, and asset references before browser frame production.
137
+ _Avoid_: Lint, preflight
138
+
139
+ **Composition diagnostic**:
140
+ A structured error or warning about a composition's source, metadata, bindings, controller, assets, or frame production, with a stable code and optional source location.
141
+ _Avoid_: Log message, error string
142
+
99
143
  **Render**:
100
144
  The production of one complete video from a composition and a fixed set of props.
101
145
  _Avoid_: Recording, export