Skip to content

fix(core): the npm package no longer ships the unminified media sync runtime - #6515

Merged
miguel-heygen merged 3 commits into
mainfrom
fix/core-pack-runtime-source
Oct 27, 2026
Merged

miguel-heygen merged 3 commits into
mainfrom
fix/core-pack-runtime-source

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What

@hyperframes/core's npm package no longer ships the unminified browser media sync (dist/runtime/media.js and three files only it imports). The package is 57 KB smaller unpacked and 17 KB smaller packed, and every published entry point still resolves.

Why

src/runtime is excluded from core's tsc build: the runtime reaches users as the minified bundles (./runtime, ./runtime-script), and a runtime file only reaches dist when a module in the build imports it. Three such imports pulled runtime/media.ts in by accident:

  • runtime/timeline.ts imported two playbackRate.ts helpers through media.ts's re-exports;
  • runtime/state.ts type-imported RuntimeMediaClip from media.ts (a type-only import still adds the file to the program, so it is emitted);
  • runtime/clock.ts imported the MEDIA_HARD_SYNC_SECONDS constant from media.ts.

So core shipped the media sync loop as plain source next to the bundles, and every change to it counted against core's size budget about three times. A playback fix on top of this one was refused by the merge queue for exactly that: its code fit the bundles, but the extra unminified copy pushed core over its budget.

How

  • timeline.ts imports readElementPlaybackRate and readMediaStart from playbackRate.ts (where they are defined).
  • RuntimeMediaClip moves to runtime/types.ts; media.ts re-exports it, so every existing import keeps working.
  • MEDIA_HARD_SYNC_SECONDS moves to mediaSteer.ts, beside MEDIA_SYNC_TOLERANCE_SECONDS; media.ts and clock.ts import it from there.
  • mediaSteer.ts joins core's tsconfig.json files, because the published ./runtime/media-steer subpath needs it and it no longer arrives through media.ts.

No runtime behaviour changes: the bundles are built from the same sources, and only where a type and a constant are declared moves.

What I measured

npm pack --dry-run in packages/core, main against this branch, both built from clean:

packed unpacked files
main 1,674,483 B 4,084,370 B 449
this branch 1,656,898 B 4,027,107 B 441

Files that leave the package: dist/runtime/media, preloadMedia, timedClipHide and adapters/seek-dispatch (.js and .d.ts each). None is a published subpath, and no remaining file in the tarball references them.

  • ./runtime/media-steer from the packed tarball in a clean consumer: resolves and exports MEDIA_HARD_SYNC_SECONDS, MEDIA_SYNC_TOLERANCE_SECONDS, forgetSteering, isSteering, steerMedia.
  • verify:packed-manifests: 185 packed exports resolved, 175 Node exports executed, NodeNext declaration check and size budgets pass.
  • check:package-subpaths, check-package-cycles, oxfmt, oxlint, comment ratchet and fallow audit clean.
  • core typecheck (including the runtime config); tsc --noEmit in player, engine and studio.
  • core vitest run: 249 files, 5457 tests, 3 runs in a row.

What I did NOT exercise

  • A real publish to the registry: the tarball was checked through npm pack and the packed-consumer install that verify:packed-manifests does.

Test plan

  • Tarball before/after with npm pack --dry-run
  • Packed subpath import for ./runtime/media-steer
  • verify:packed-manifests, subpath and cycle checks
  • Typecheck in core, player, engine, studio; core unit tests 3x
  • Documentation updated (not applicable: no public API change)

@github-actions

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 271 (base branch 271), smooth 111 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

Unstable (2)

  • seqplainkeys-none-center-r0-root-z100: tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo false, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true
  • seqplainkeys-none-pct-r0-root-z100: tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo false, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true / tracking 0.06, pressJump 0, drop 0, reload 0, render 0.03, renderKey -, undo true, teleport true

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE · 0 blocker · 0 important · 0 nits

Scope

Read the full diff, including 3afaf9a, which only trims comments. Compared the files in core's tsc build on main and on this branch with tsc --listFilesOnly. Exactly four drop out: runtime/media, preloadMedia, timedClipHide and adapters/seek-dispatch. mediaSteer stays. No package exports any of the dropped files, and none is deep-imported through @hyperframes/core. The readElementPlaybackStart → readMediaStart swap is the same function: the old one only wrapped the new one. CI, regression, Windows, Comments and PR captures are green at this head.

@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit bd9b134 Oct 27, 2026
82 checks passed
@miguel-heygen
miguel-heygen deleted the fix/core-pack-runtime-source branch October 27, 2026 05:25
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