Skip to content

Conversation

@Julusian
Copy link
Member

@Julusian Julusian commented Dec 16, 2025

About the Contributor

This pull request is posted on behalf of Superfly

Type of Contribution

This is a: Code improvement

Depends upon Sofie-Automation/sofie-timeline-state-resolver#412

Current Behavior

When using a TSR plugin, it requires some messy type casting to be able to create timeline objects for the plugin.

This is the sofie-core side of a solution to that problem.

To use it, inside of blueprints you can add a file such as tsr-extend.d.ts:

import type { FakeDeviceType, TimelineContentFakeAny } from './test-types.js'

declare module 'timeline-state-resolver-types' {
	interface TimelineContentMap {
		[FakeDeviceType]: TimelineContentFakeAny
	}
}

Blueprints will be happy with these custom types.

In order for this to work, some usages of DeviceType have to be replaced with DeviceTypeExt, so that they accept the custom DeviceTypes.

Testing Instructions

Other Information

Status

  • PR is ready to be reviewed.
  • The functionality has been tested by the author.
  • Relevant unit tests has been added / updated.
  • Relevant documentation (code comments, system documentation) has been added / updated.

Summary by CodeRabbit

  • Documentation

    • Added comprehensive guide for integrating custom TSR plugins with Sofie blueprints, including examples of defining custom timeline types and device configurations.
  • Improvements

    • Enhanced timeline type system to support extended device type specifications for improved customization.
    • Added session tracking capability to timeline keyframes for advanced integration scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

@Julusian Julusian requested a review from a team as a code owner December 16, 2025 15:33
@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The pull request updates type constraints for timeline objects and keyframes from TSR.DeviceType to TSR.DeviceTypeExt across multiple packages. An optional abSession field is added to TimelineKeyframeCoreExt, and documentation is added explaining TSR plugin integration patterns with Sofie blueprints.

Changes

Cohort / File(s) Summary
Type constraint updates
packages/blueprints-integration/src/timeline.ts, packages/shared-lib/src/core/model/Timeline.ts
Updated generic constraints for OnGenerateTimelineObj, TimelineObjectCoreExt, and TimelineKeyframeCoreExt to require TSR.DeviceTypeExt instead of TSR.DeviceType, tightening the allowed deviceType shape for timeline content.
TimelineKeyframeCoreExt enhancement
packages/shared-lib/src/core/model/Timeline.ts
Added optional abSession field of type { poolName: string; playerId: number | string } to TimelineKeyframeCoreExt and reordered generics (TContent, TKeyframeMetadata).
Documentation
packages/documentation/docs/for-developers/device-integrations/tsr-plugins.md
Added new "Using in Sofie blueprints" subsection explaining TSR plugin integration, including how to define custom timeline types in tsr-types.d.ts and providing example structures for custom device types.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Verify that TSR.DeviceTypeExt is the correct and compatible type constraint replacement across all affected interfaces
  • Confirm that the new optional abSession field and generic reordering in TimelineKeyframeCoreExt maintain backward compatibility
  • Review documentation examples for accuracy and completeness in the TSR plugin integration section

Poem

🐰 Type constraints now grow lean and tight,
DeviceTypeExt brings clarity bright!
With sessions stored, the keyframes dance,
While blueprints waltz in Sofie's expanse. ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: support custom types from tsr plugins' directly and clearly summarizes the main change—enabling blueprints to use custom device types from TSR plugins without type casting, which is the core objective of this changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Comment @coderabbitai help to get the list of available commands and usage tips.

@Julusian
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/shared-lib/src/core/model/Timeline.ts (1)

39-39: Critical: DeviceTypeExt does not exist in timeline-state-resolver-types.

Same issue as in packages/blueprints-integration/src/timeline.ts. The pipeline failures confirm that TSR.DeviceTypeExt is not available in the current version of timeline-state-resolver-types. This PR cannot be merged until the dependency on Sofie-Automation/sofie-timeline-state-resolver#412 is resolved.

🧹 Nitpick comments (1)
packages/documentation/docs/for-developers/device-integrations/tsr-plugins.md (1)

124-124: Optional: Consider simplifying "all of the" to "all the".

The phrase "all of the" can be simplified to "all the" for a more concise style.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d308900 and 836b9a0.

📒 Files selected for processing (3)
  • packages/blueprints-integration/src/timeline.ts (1 hunks)
  • packages/documentation/docs/for-developers/device-integrations/tsr-plugins.md (1 hunks)
  • packages/shared-lib/src/core/model/Timeline.ts (2 hunks)
🧰 Additional context used
🪛 GitHub Actions: Node CI
packages/shared-lib/src/core/model/Timeline.ts

[error] 39-39: TS2724: '/home/runner/work/sofie-core/sofie-core/packages/node_modules/timeline-state-resolver-types/dist/index' has no exported member named 'DeviceTypeExt'. Did you mean 'DeviceType'?


[error] 62-62: TS2724: '/home/runner/work/sofie-core/sofie-core/packages/node_modules/timeline-state-resolver-types/dist/index' has no exported member named 'DeviceTypeExt'. Did you mean 'DeviceType'?

🪛 LanguageTool
packages/documentation/docs/for-developers/device-integrations/tsr-plugins.md

[style] ~124-~124: Consider removing “of” to be more concise
Context: ... { input: number } } ``` With this, all of the sofie timeline object and tsr types wil...

(ALL_OF_THE)

🪛 markdownlint-cli2 (0.18.1)
packages/documentation/docs/for-developers/device-integrations/tsr-plugins.md

92-92: Hard tabs
Column: 1

(MD010, no-hard-tabs)


93-93: Hard tabs
Column: 1

(MD010, no-hard-tabs)


94-94: Hard tabs
Column: 1

(MD010, no-hard-tabs)


106-106: Hard tabs
Column: 1

(MD010, no-hard-tabs)


112-112: Hard tabs
Column: 1

(MD010, no-hard-tabs)


113-113: Hard tabs
Column: 1

(MD010, no-hard-tabs)


117-117: Hard tabs
Column: 1

(MD010, no-hard-tabs)


118-118: Hard tabs
Column: 1

(MD010, no-hard-tabs)


119-119: Hard tabs
Column: 1

(MD010, no-hard-tabs)


120-120: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🔇 Additional comments (2)
packages/shared-lib/src/core/model/Timeline.ts (1)

61-73: Clarify the purpose and scope of the keyframe-level abSession field.

The addition of abSession to TimelineKeyframeCoreExt (lines 69-72) is a distinct feature from the object-level abSessions property in TimelineObjectCoreExt. While abSessions manages named sessions at the object level, abSession enables per-keyframe player selection within an AB pool. Confirm whether this per-keyframe capability is intentional and documented in the PR.

Additionally, the reference to a critical DeviceTypeExt issue on line 62 could not be located in the codebase. Please clarify what specific concern was raised earlier about DeviceTypeExt.

packages/blueprints-integration/src/timeline.ts (1)

21-21: Verify if DeviceTypeExt is now available in the current timeline-state-resolver-types version.

The code in both packages/shared-lib/src/core/model/Timeline.ts and packages/blueprints-integration/src/timeline.ts uses TSR.DeviceTypeExt in generic type constraints. The project depends on timeline-state-resolver-types@10.0.0-nightly-release53-20251030-091938-982ec3103.0, a nightly build from October 30, 2025.

While the original pipeline error indicated that DeviceTypeExt was missing, the current nightly version appears to be recent enough to potentially include the fix from the referenced dependency PR. Confirm whether:

  1. The dependency PR (Sofie-Automation/sofie-timeline-state-resolver#412) has been merged
  2. The nightly version currently specified includes the DeviceTypeExt export
  3. The project compiles without the TS2724 error

If the issue persists, ensure the dependency PR is merged and update the package version accordingly.

@Julusian Julusian force-pushed the feat/support-tsr-plugin-types branch from 836b9a0 to c9e9f99 Compare December 17, 2025 14:47
@codecov
Copy link

codecov bot commented Dec 17, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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