feat!: support loading TSR devices as 'plugins' #375
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.
About the Contributor
This pull request is posted on behalf of Superfly
Type of Contribution
This is a: Feature
Current Behavior
All the device integrations must be built into this repository. This sometimes means an organisation must make a private fork of this repository, when they have an integration which they are not allowed to make public (typically because a vendor restricts access to protocol docs)
New Behavior
This makes it possible to load extra device integrations from additional paths on disk.
This loading is currently a little naive and isn't attempting to check that the api is the same version as expected, or doing much sanitisation of the manifest or other data. Due to the limited scope of how to load these plugins, I suspect it will be acceptable to say that is not necessary.
To use this a folder should be constructed meeting the following requrements:
manifest.json
at the root of it, containing json in the format ofRecord<string, TSRDevicesManifestEntry>
translations.json
at the root of it, containing json in the format ofTranslationsBundle[]
require(...)
. This likely means having a package.json, be a commonjs project and having all necessary dependencies installed within the folder.require(...)
should have an export of the formexport const Devices: Record<string, DeviceEntry>
Then in the code using TSR, this can be loaded by:
It is possible to load extra devices on the
DevicesRegistry
while it is being used by aConductor
if needed, but it isn't possible to unload plugin paths currently, so this can 'leak' if used excessively.I opted to make this a separate
DevicesRegistry
class because playout-gateway needs access to the full manifest before the Conductor has been constructed. I also wanted to avoid adding any global state. Providing this class to the Conductor is optional, so it does not add complexity for those who do not want to make use of it.As a side effect of this change, the static manifest export has been removed, making this a breaking change.
To achieve this, a new
timeline-state-resolver-api
package has been added which contains the interfaces, schemas and other common code needed by these plugins and tsr itself.A
timeline-state-resolver-tools
package has also been added which contains a few scripts to generate and prepare translations, and process the device integration json-schemas. These scripts are refactored versions of ones that used to be part of the timeline-state-resolver package, and have been made a bit more generic to be reusable by plugins and tsr.There is an annoying quirk of this library, users of it must use the following yarn resolution for it to work properly
"cheerio": "1.0.0-rc.12"
. This is a known bug in the version of i18next-parser we use. It is fixed in the latest version of that library, which requires node 18 or later, and might require us to update i18next everywhere.Testing Instructions
This can be tested with quick-tsr, there is a commented out call to
loadDeviceIntegrationsFromPath()
, which can be enabled and given a correct path. To utilise it with sofie, the patch Sofie-Automation/sofie-core@release53...SuperFlyTV:sofie-core:feat/tsr-plugins can be usedOther Information
My testing plugin for this is https://github.com/SuperFlyTV/sofie-tsr-plugin-example, which is the atem module pulled out of this repository. Only imports (and tooling) needed to be updated to get the module running.
I haven't verified that the types in sofie blueprints or elsewhere work for this, I suspect there may be some fighting with TSR complaining that strings arent assignable to DeviceType
Status