feat: update @svta/cml-cmcd to 2.4.0 - [Claude Code]#5
Open
littlespex wants to merge 16 commits into
Open
Conversation
Captures the design for adopting CmcdReporter's new auto-firing state-change semantics, replacing CmcdRequestCollector with the library's CmcdReportRecorder, and adding throttled `pt` tracking. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eight-task TDD plan derived from the design at docs/superpowers/specs/2026-05-27-cmcd-v2.4-update-design.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2.4.0 adds CmcdReporter.update() auto-firing of state-change events and ships CmcdReportRecorder as an official test helper. Also bumps @svta/cml-request to 1.0.13 (its peer-dep range required 2.3.2 exactly). Fixes the `prepare` githook installer to resolve the actual git hooks directory when `.git` is a worktree file (otherwise `npm install` fails in a worktree with ENOTDIR). Behavior adjustments in this codebase follow in subsequent commits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Subscribes CmcdController to PLAYBACK_TIME_UPDATED and writes pt (playhead time in ms) directly to the reporter's persistent store, throttled to 4 Hz. The listener also validates that e.time is a finite, non-negative number before forwarding — CMCD spec requires pt to be a non-negative integer. Both auto-fired state-change events and TIME_INTERVAL reports now see fresh pt without the controller plumbing it at every event site. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Under @svta/cml-cmcd 2.4.0, CmcdReporter.update({sta}) auto-fires the
PLAY_STATE event, and a follow-up recordEvent('ps', ...) is dedup-
suppressed, silently dropping its data argument. This change folds the
prior two-call pattern into a single update({ ...continuousMetrics, sta })
call so enrichment fields (ltc, bl, mtp, pt, msd, ...) ride the auto-fire.
Adds _gatherContinuousMetrics() helper as the single source of truth for
fields pulled from CmcdModel at each event site.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Renames triggerCmcdEventMode -> _recordNonStateEvent to match the @svta/cml-cmcd 2.4.0 canonical pattern: continuous metrics flow through update() into the persistent data store, and recordEvent() carries only ephemeral per-event payload. Updates _onPlayerError to pass ec as a string array per CTA-5004-B / the 2.4.0 Cmcd.ec type. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sn is now managed internally by CmcdReporter; dash.js no longer tracks or sets it anywhere. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the locally maintained XHR-patching helper with the CmcdReportRecorder shipped from @svta/cml-cmcd 2.4.0. Single attach- level waitTimeout replaces per-call timeouts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cosmetic cleanup from code review. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
End-to-end witness of the v2.4.0 update + recordEvent consolidation: verifies that pt / ltc / bl / mtp show up in real PLAY_STATE event reports rather than being silently dropped by the reporter's dedup. Also adds 'pt' to the play-state target's enabledKeys so the new assertion has at least one continuous-metric signal to find. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings the response-received path in line with the rest of the 2.4.0-aligned pattern: continuous metrics flow through update() into the persistent data store, and only ephemeral per-response payload (CMSD headers) rides the recordResponseReceived() data argument. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add bl and mtp to the PLAY_STATE event target's enabledKeys and require >=2 distinct enrichment fields in the emitted report. The earlier >=1 check passed on pt alone, leaving the bl/mtp portion of the regression intent unverified. ltc is excluded because PlaybackController.getCurrentLiveLatency() returns NaN for VOD streams. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR upgrades CMCD reporting to @svta/cml-cmcd 2.4.0 and adapts dash.js event-mode reporting to the library’s new update() auto-fire semantics.
Changes:
- Refactors
CmcdControllerto consolidate PLAY_STATE updates, add throttledpttracking, and separate state-change from non-state event reporting. - Migrates CMCD v2 functional tests from the local request collector to
CmcdReportRecorderand adds regression coverage for enriched event payloads. - Bumps CMCD-related dependencies and adjusts the git hook installer for worktree
.gitfiles.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/streaming/controllers/CmcdController.js |
Updates CMCD event/reporting logic for 2.4.0 semantics and adds pt listener support. |
test/unit/test/streaming/streaming.controllers.CmcdController.js |
Adds unit coverage for pt, PLAY_STATE enrichment, throttling, invalid times, and ERROR ec shape. |
test/functional/test/feature-support/cmcd-v2.js |
Migrates functional CMCD v2 tests to CmcdReportRecorder and adds event enrichment assertions. |
test/functional/helpers/CmcdRequestCollector.js |
Removes the now-superseded local functional-test collector helper. |
package.json |
Updates @svta/cml-cmcd and @svta/cml-request dependency versions. |
package-lock.json |
Locks the updated dependency versions. |
githook.cjs |
Attempts to resolve the actual git hooks directory for worktree checkouts. |
docs/superpowers/specs/2026-05-27-cmcd-v2.4-update-design.md |
Adds the implementation design for the CMCD 2.4.0 upgrade. |
docs/superpowers/plans/2026-05-27-cmcd-v2.4-update.md |
Adds the task-by-task implementation plan for the CMCD 2.4.0 upgrade. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Remove docs/superpowers/{plans,specs} — these were branch-local design
artifacts that don't belong in the upstream PR.
- Revert githook.cjs to its pre-branch state. The worktree-aware
resolver was only needed to make `npm install` succeed in this
development worktree; it is not core to the CMCD upgrade.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rdering - CmcdModel.getGenericCmcdData() now always sets bg (true or false based on document.hidden), so hidden->visible transitions round-trip through the reporter's persistent store. The previous code only set bg:true when hidden and left it unset when visible, which let a stale bg:true persist after the tab became visible again and leak into unrelated event-mode payloads. The library's emission filter handles wire-format semantics: bg:false is stripped on non-`e=b` events and emitted as `?0` on `e=b` per CTA-5004-B and the 2.4.0 carve-out. - _onPlaybackTimeUpdated now calls _rebuildReporterIfNeeded() before writing pt to the reporter, so a time update that arrives after MANIFEST_LOADED but before the next state change lands on the new reporter (the one that will actually emit) rather than on the old reporter that's about to be discarded by the rebuild. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match the version pinning style of the other @svta/cml-* packages in package.json (none of which use carets). The earlier ^2.4.0 would silently float onto 2.x minor updates and bypass review for behavior-shifting library changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The lockfile had accumulated ~5500 lines of unrelated transitive-dep drift from earlier installs in this branch. Restored to the base lockfile and applied only the four changes the CML bumps actually require: - top-level deps: @svta/cml-cmcd 2.3.2 -> 2.4.0 - top-level deps: @svta/cml-request 1.0.12 -> 1.0.13 - node_modules/@svta/cml-cmcd: version/resolved/integrity to 2.4.0 - node_modules/@svta/cml-request: version/resolved/integrity to 1.0.13 and its peer-dep pin on @svta/cml-cmcd updated to 2.4.0 Net diff vs base: 9 insertions / 9 deletions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Upgrades
@svta/cml-cmcdfrom 2.3.2 to ^2.4.0 and adapts dash.js to the newCmcdReportersemantics. The headline change in 2.4.0:update()auto-fires the corresponding state-change event when a tracked field changes, and a follow-uprecordEvent()for the same event is dedup-suppressed — silently dropping itsdataargument.The existing dash.js pattern hit this footgun in
_onPlaybackStateChange:update({sta})thenrecordEvent('ps', cmcdData)was silently losingbl,mtp,pt,ltc,msdenrichment under 2.4.0. This PR consolidates that into a singleupdate({ ...continuousMetrics, sta })call so the auto-fire emits the full payload. It also splits state-change vs non-state event paths cleanly, adds throttledpttracking viaPLAYBACK_TIME_UPDATED, and replaces the localCmcdRequestCollectorfunctional-test helper with the library's newCmcdReportRecorder.What changed
package.json— bump@svta/cml-cmcd2.3.2 → ^2.4.0 and@svta/cml-request1.0.12 → 1.0.13 (peer-dep alignment).src/streaming/controllers/CmcdController.js:_gatherContinuousMetrics()helper as the single source of truth for fields pulled fromCmcdModel._onPlaybackStateChangeto a single consolidatedupdate({ ..._gatherContinuousMetrics(), sta: state })call. This is the dedup-footgun fix.triggerCmcdEventMode→_recordNonStateEvent. Continuous metrics flow throughupdate(); only ephemeral per-event payload (e.g.,ec) ridesrecordEvent()'s data arg._onPlayerErrornow passes{ ec: [String(code)] }(array form per CTA-5004-B / the 2.4.0Cmcd.ectype)._handleResponseReceivednow also uses_gatherContinuousMetrics()— continuous metrics persist into the store viaupdate(), only ephemeral CMSD-derived data ridesrecordResponseReceived()'s data arg._onPlaybackTimeUpdatedlistener (4 Hz; validatese.timeis a finite non-negative number) that writesptdirectly to the reporter's persistent store. Subscribed in_initializeEventBus, unsubscribed inreset, state reset in_resetInitialSettings.test/unit/test/streaming/streaming.controllers.CmcdController.js— new tests:ptlands in event payload after listener fires; throttle suppresses second fire within window; invalide.timevalues are ignored; PLAY_STATE event includesltc+ptenrichment (regression test for the footgun); ERROR event carriesecasstring[].test/functional/test/feature-support/cmcd-v2.js— migrated from localCmcdRequestCollectortoCmcdReportRecorderfrom@svta/cml-cmcd. Single attach-levelwaitTimeoutreplaces per-call timeouts. Added end-to-end assertion that PLAY_STATE event reports carry≥2continuous-metric enrichment fields (pt/bl/mtp).test/functional/helpers/CmcdRequestCollector.js— deleted (superseded).githook.cjs— fixed thepreparescript's hook installer to resolve the actual git hooks directory when.gitis a worktree file (was failing with ENOTDIR in worktrees).Design and plan
docs/superpowers/specs/2026-05-27-cmcd-v2.4-update-design.mddocs/superpowers/plans/2026-05-27-cmcd-v2.4-update.mdBehavior deltas to be aware of
update(prData)in_onPlaybackRateChangednow auto-fires a PLAYBACK_RATE event-mode report when an event target subscribes to theprevent. This is correct per CTA-5004-B but is a visible behavior change for event-target consumers that weren't previously receiving PLAYBACK_RATE events.ecshape change. ERROR event payloads now carryecasstring[](was a scalar). Required by 2.4.0 typings and CTA-5004-B's list notation. Downstream CMCD event validators parsing error payloads should accept array form.ptis now emitted in event-mode reports. Previously not reported by dash.js at all; now flows into the persistent store at 4 Hz fromPLAYBACK_TIME_UPDATED.HTTPLoaderalready treats any 2xx as success.Test Plan
npm run lint— cleannpm test— 3670 passing, 0 failing (+12 new unit tests in this branch)npm run test-functional— exit 0 (CMCD-specific: Query 7/8 with pre-existing unrelated flake, Header 6/6, Event 10/10, Key Filtering 6/6, Version 6/6)npm run build— modern + legacy both cleansamples/cmcd/cmcd-v2.htmlin a browser: PLAY_STATE event report showssta,pt,bl,mtp; playback rate change triggers aprevent reportsn(now reporter-internal)🤖 Generated with Claude Code