Skip to content

feat(core): add compiler entry point and runtime composition fixes#6

Closed
miguel-heygen wants to merge 1 commit intoinitial-code-portfrom
feat/core-compiler
Closed

feat(core): add compiler entry point and runtime composition fixes#6
miguel-heygen wants to merge 1 commit intoinitial-code-portfrom
feat/core-compiler

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

@miguel-heygen miguel-heygen commented Mar 21, 2026

What

Added a new HTML bundler and compiler module to the core package that can bundle HyperFrames projects into self-contained HTML files.

Why

This enables packaging HyperFrames projects into single HTML files for easier distribution and deployment, eliminating the need for separate asset files and external dependencies.

How

  • Created htmlBundler.ts with bundleToSingleHtml() function that:
    • Injects the HyperFrames runtime script
    • Inlines local CSS and JavaScript files
    • Inlines sub-composition HTML fragments via data-composition-src
    • Converts small textual assets to data URLs
    • Enforces composition pixel sizing and heals missing composition IDs
  • Added htmlCompiler.ts with compileHtml() function for timing compilation with optional media duration probing
  • Created staticGuard.ts for validating HyperFrame HTML contracts
  • Updated package exports to include the new ./compiler entry point
  • Moved cheerio and esbuild to optional dependencies since they're only needed for bundling
  • Enhanced runtime initialization to better handle inlined compositions and child timeline discovery
  • Improved visibility management to skip elements inside sub-compositions

Test plan

  • Unit tests added/updated
  • Manual testing performed
  • Documentation updated (if applicable)

Add @hyperframes/core/compiler — shared HTML bundler for studio and CLI.
- bundleToSingleHtml(): runtime injection + sub-composition inlining
- compileHtml(): timing compilation with optional ffprobe
- validateHyperframeHtmlContract(): static guard
- Path traversal protection via safePath() on all resolve calls

Runtime fixes for composition rendering:
- childrenBound flag prevents premature timeline skip
- Visibility adapter skips sub-composition elements
- Deferred rebinding for inlined compositions
- className fallback for timeline clip labels
Copy link
Copy Markdown
Collaborator Author

miguel-heygen commented Mar 21, 2026

miguel-heygen added a commit that referenced this pull request Mar 31, 2026
…tsx split (#144)

## Summary

Full code quality review of the studio package, fixing 22 of 25 findings. Removes dead code, extracts modules from App.tsx, fixes accessibility and performance issues.

## Critical fixes (3)

- **`aria-valuenow`** on seek bar now updates imperatively via `liveTime.subscribe` — screen readers previously always reported position 0
- **Speed menu** closes on outside click (was permanently stuck open)
- **RenderQueue auto-scroll** moved from render phase to `useEffect` (was violating React render purity via `queueMicrotask` during render)

## Dead code removed (-331 lines)

| File | Lines | Why dead |
|---|---|---|
| `PreviewPanel.tsx` | 180 | Replaced by NLELayout + NLEPreview |
| `useCodeEditor.ts` | 80 | Exported but never imported |
| `formatTick` alias | 2 | Deprecated, unused |
| `onClipChange` prop | 5 | Declared, never used |
| `trackH` prop | 5 | Declared, never used |
| `editRange*` + updaters in store | 60 | Never read or written |

## App.tsx extraction

| Extracted to | Lines | What |
|---|---|---|
| `components/LintModal.tsx` | 130 | Lint results modal + LintFinding type |
| `components/MediaPreview.tsx` | 75 | Image/video/audio/font file previewer |
| `utils/mediaTypes.ts` | 15 | Shared regex constants (App.tsx and AssetsTab.tsx had diverged copies) |

## Performance fixes

- `useMemo` for `compositions`/`assets` derivation from `fileTree`
- `useMemo` for `buildTree(files)` in FileTree
- Debounced `handleContentChange` PUT (600ms — was firing on every keystroke)
- CompositionsTab iframe hover debounced (300ms — was mounting immediately)
- `VideoFrameThumbnail` re-extracts frame when `src` prop changes

## Not addressed (3 — low priority)

- #6: SystemIcons consolidation (large refactor across many files)
- #16-17: Overlay dismiss pattern standardization
- #18: Inline SVG → Phosphor replacement (gradual, per-PR)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@miguel-heygen miguel-heygen deleted the feat/core-compiler branch April 6, 2026 23:25
vanceingalls added a commit that referenced this pull request Apr 16, 2026
Blockers:
- #2: late_init_set false positive on fractional opacity (0.5 matched as 0)
  Fixed: /opacity\s*:\s*0(?![.\d])/ negative lookahead
- #3: scene-1 prefix skip matches scene 10+ (s1- matches s10-)
  Fixed: extract full number and compare exactly

High severity:
- #4: autoAlpha not covered by late_init_set
  Fixed: checks both opacity and autoAlpha
- #5: al() crashes on non-hex colors (#fff shorthand, rgb(), null)
  Fixed: guard + shorthand expansion + NaN fallback
- #6: "Full palette" with null bg crashes isDark
  Fixed: null guard defaults to dark
- #7: template literals missed by tl_from_in_multiscene
  Fixed: regex includes backtick quotes

Medium:
- #9: no retry limit on eval failures → infinite loop
  Fixed: max 2 retries, then escalate to user
- #10: vague ID convention
  Fixed: explicit s{N}- prefix rule in multi-scene.md
- #11: visual-style.md backward compat
  Fixed: Step 0b checks both filenames
- #13: preview_html script injection
  Fixed: documented prohibition in design-picker.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant