Skip to content

Commit 33b803e

Browse files
committed
Merge remote-tracking branch 'upstream/release53' into upstream/fix-autoscroll-detaches-onair-line
2 parents 48c0c8d + aa2a5e0 commit 33b803e

File tree

328 files changed

+8774
-11451
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

328 files changed

+8774
-11451
lines changed

.github/actions/setup-meteor/action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ description: "Setup Meteor"
33
runs:
44
using: "composite"
55
steps:
6-
- run: curl "https://install.meteor.com/?release=3.1" | sh
6+
- run: curl "https://install.meteor.com/?release=3.1.2" | sh
77
shell: bash

.node-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
22.11
1+
22.13.1

meteor/.meteor/packages

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88

99
# but you can also edit it by hand.
1010

11-
meteor@2.0.1
12-
11+
meteor@2.1.0
12+
1313
1414

15-
mongo@2.0.2 # The database Meteor supports right now
15+
mongo@2.1.0 # The database Meteor supports right now
1616

17-
[email protected].9 # Enable ECMAScript2015+ syntax in app code
18-
typescript@5.4.3 # Enable TypeScript syntax in .ts and .tsx modules
17+
[email protected].10 # Enable ECMAScript2015+ syntax in app code
18+
typescript@5.6.3 # Enable TypeScript syntax in .ts and .tsx modules
1919

2020
[email protected] # Meteor's client-side reactive programming library
2121

meteor/.meteor/release

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1+

meteor/.meteor/versions

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
allow-deny@2.0.0
2-
1+
allow-deny@2.1.0
2+
33
44
55
@@ -8,9 +8,9 @@ [email protected]
88
99
1010
11-
ddp-client@3.0.3
11+
ddp-client@3.1.0
1212
13-
ddp-server@3.0.3
13+
ddp-server@3.1.0
1414
1515
1616
@@ -24,26 +24,26 @@ [email protected]
2424
2525
2626
27-
meteor@2.0.2
27+
meteor@2.1.0
2828
29-
modern-browsers@0.1.11
29+
modern-browsers@0.2.0
3030
3131
32-
mongo@2.0.3
32+
mongo@2.1.0
3333
3434
3535
36-
36+
3737
3838
3939
4040
4141
4242
4343
44-
socket-stream-client@0.5.3
44+
socket-stream-client@0.6.0
4545
4646
47-
47+
4848
4949

meteor/Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ RUN yarn install && yarn build
1515

1616
# BUILD IMAGE
1717
FROM node:22
18-
RUN curl "https://install.meteor.com/?release=3.1" | sh
18+
RUN curl "https://install.meteor.com/?release=3.1.2" | sh
1919

2020
# Temporary change the NODE_ENV env variable, so that all libraries are installed:
2121
ENV NODE_ENV_TMP $NODE_ENV
@@ -30,6 +30,8 @@ COPY meteor /opt/core/meteor
3030
COPY scripts /opt/core/scripts
3131
WORKDIR /opt/core/meteor
3232

33+
# remove the dev only assets from the webui output
34+
RUN rm -Rf /opt/core/packages/webui/dist/dev
3335
# move the webui to the correct place
3436
RUN rm -Rf /opt/core/meteor/public
3537
RUN cp -R /opt/core/packages/webui/dist /opt/core/meteor/public

meteor/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "1.53.0-in-development",
44
"private": true,
55
"engines": {
6-
"node": ">=22.11"
6+
"node": ">=22.13.1"
77
},
88
"scripts": {
99
"preinstall": "node -v",

meteor/server/api/__tests__/cleanup.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ async function setDefaultDatatoDB(env: DefaultEnvironment, now: number) {
410410
generationVersions: {} as any,
411411
timelineBlob: '' as any,
412412
timelineHash: '' as any,
413+
regenerateTimelineToken: undefined,
413414
})
414415
await TimelineDatastore.mutableCollection.insertAsync({
415416
_id: getRandomId(),
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { Meteor } from 'meteor/meteor'
2+
import { RundownPlaylistActivationId, ShowStyleBaseId } from '@sofie-automation/corelib/dist/dataModel/Ids'
3+
import { RundownPlaylists, ShowStyleBases, PieceInstances, PartInstances } from '../../collections'
4+
import { logger } from '../../logging'
5+
import { rundownPlaylistFieldSpecifier } from './reactiveContentCache'
6+
import {
7+
ContentCache,
8+
createReactiveContentCache,
9+
partInstanceFieldSpecifier,
10+
pieceInstanceFieldSpecifier,
11+
} from './reactiveContentCacheForPieceInstances'
12+
import { waitForAllObserversReady } from '../../publications/lib/lib'
13+
14+
const REACTIVITY_DEBOUNCE = 20
15+
16+
type ChangedHandler = (cache: ContentCache) => () => void
17+
18+
export class PieceInstancesObserver {
19+
#observers: Meteor.LiveQueryHandle[] = []
20+
#cache: ContentCache
21+
#cancelCache: () => void
22+
#cleanup: (() => void) | undefined
23+
#disposed = false
24+
25+
constructor(onChanged: ChangedHandler) {
26+
const { cache, cancel: cancelCache } = createReactiveContentCache(() => {
27+
this.#cleanup = onChanged(cache)
28+
if (this.#disposed) this.#cleanup()
29+
}, REACTIVITY_DEBOUNCE)
30+
31+
this.#cache = cache
32+
this.#cancelCache = cancelCache
33+
}
34+
35+
static async create(
36+
activationId: RundownPlaylistActivationId,
37+
showStyleBaseId: ShowStyleBaseId,
38+
onChanged: ChangedHandler
39+
): Promise<PieceInstancesObserver> {
40+
logger.silly(`Creating PieceInstancesObserver for activationId "${activationId}"`)
41+
42+
const observer = new PieceInstancesObserver(onChanged)
43+
44+
await observer.initObservers(activationId, showStyleBaseId)
45+
46+
return observer
47+
}
48+
49+
private async initObservers(activationId: RundownPlaylistActivationId, showStyleBaseId: ShowStyleBaseId) {
50+
this.#observers = await waitForAllObserversReady([
51+
RundownPlaylists.observeChanges(
52+
{
53+
activationId,
54+
},
55+
this.#cache.RundownPlaylists.link(),
56+
{
57+
projection: rundownPlaylistFieldSpecifier,
58+
}
59+
),
60+
ShowStyleBases.observeChanges(showStyleBaseId, this.#cache.ShowStyleBases.link()),
61+
PieceInstances.observeChanges(
62+
{
63+
playlistActivationId: activationId,
64+
reset: { $ne: true },
65+
disabled: { $ne: true },
66+
reportedStoppedPlayback: { $exists: false },
67+
'piece.virtual': { $ne: true },
68+
},
69+
this.#cache.PieceInstances.link(),
70+
{
71+
projection: pieceInstanceFieldSpecifier,
72+
}
73+
),
74+
PartInstances.observeChanges(
75+
{
76+
playlistActivationId: activationId,
77+
reset: { $ne: true },
78+
'timings.reportedStoppedPlayback': { $ne: true },
79+
},
80+
this.#cache.PartInstances.link(),
81+
{
82+
projection: partInstanceFieldSpecifier,
83+
}
84+
),
85+
])
86+
}
87+
88+
public get cache(): ContentCache {
89+
return this.#cache
90+
}
91+
92+
public stop = (): void => {
93+
this.#disposed = true
94+
this.#cancelCache()
95+
this.#observers.forEach((observer) => observer.stop())
96+
this.#cleanup?.()
97+
this.#cleanup = undefined
98+
}
99+
}

meteor/server/api/deviceTriggers/StudioDeviceTriggerManager.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,20 @@ import { protectString } from '../../lib/tempLib'
2525
import { StudioActionManager, StudioActionManagers } from './StudioActionManagers'
2626
import { DeviceTriggerMountedActionAdlibsPreview, DeviceTriggerMountedActions } from './observer'
2727
import { ContentCache } from './reactiveContentCache'
28+
import { ContentCache as PieceInstancesContentCache } from './reactiveContentCacheForPieceInstances'
2829
import { logger } from '../../logging'
2930
import { SomeAction, SomeBlueprintTrigger } from '@sofie-automation/blueprints-integration'
3031
import { DeviceActions } from '@sofie-automation/shared-lib/dist/core/model/ShowStyle'
3132
import { DummyReactiveVar } from '@sofie-automation/meteor-lib/dist/triggers/reactive-var'
3233
import { MeteorTriggersContext } from './triggersContext'
34+
import { TagsService } from './TagsService'
3335

3436
export class StudioDeviceTriggerManager {
3537
#lastShowStyleBaseId: ShowStyleBaseId | null = null
3638

37-
constructor(public studioId: StudioId) {
39+
lastCache: ContentCache | undefined
40+
41+
constructor(public studioId: StudioId, protected tagsService: TagsService) {
3842
if (StudioActionManagers.get(studioId)) {
3943
logger.error(`A StudioActionManager for "${studioId}" already exists`)
4044
return
@@ -45,6 +49,7 @@ export class StudioDeviceTriggerManager {
4549

4650
async updateTriggers(cache: ContentCache, showStyleBaseId: ShowStyleBaseId): Promise<void> {
4751
const studioId = this.studioId
52+
this.lastCache = cache
4853
this.#lastShowStyleBaseId = showStyleBaseId
4954

5055
const [showStyleBase, rundownPlaylist] = await Promise.all([
@@ -79,6 +84,8 @@ export class StudioDeviceTriggerManager {
7984
const upsertedDeviceTriggerMountedActionIds: DeviceTriggerMountedActionId[] = []
8085
const touchedActionIds: DeviceActionId[] = []
8186

87+
this.tagsService.clearObservedTags()
88+
8289
for (const rawTriggeredAction of allTriggeredActions) {
8390
const triggeredAction = convertDocument(rawTriggeredAction)
8491

@@ -163,6 +170,8 @@ export class StudioDeviceTriggerManager {
163170
sourceLayerType: undefined,
164171
sourceLayerName: undefined,
165172
styleClassNames: triggeredAction.styleClassNames,
173+
isActive: undefined,
174+
isNext: undefined,
166175
}),
167176
})
168177
} else {
@@ -174,6 +183,9 @@ export class StudioDeviceTriggerManager {
174183
)
175184

176185
addedPreviewIds.push(adLibPreviewId)
186+
187+
this.tagsService.observeTallyTags(adLib)
188+
const { isActive, isNext } = this.tagsService.getTallyStateFromTags(adLib)
177189
return DeviceTriggerMountedActionAdlibsPreview.upsertAsync(adLibPreviewId, {
178190
$set: literal<PreviewWrappedAdLib>({
179191
...adLib,
@@ -192,6 +204,8 @@ export class StudioDeviceTriggerManager {
192204
}
193205
: undefined,
194206
styleClassNames: triggeredAction.styleClassNames,
207+
isActive,
208+
isNext,
195209
}),
196210
})
197211
})
@@ -224,6 +238,18 @@ export class StudioDeviceTriggerManager {
224238
actionManager.deleteActionsOtherThan(touchedActionIds)
225239
}
226240

241+
protected async updateTriggersFromLastCache(): Promise<void> {
242+
if (!this.lastCache || !this.#lastShowStyleBaseId) return
243+
return this.updateTriggers(this.lastCache, this.#lastShowStyleBaseId)
244+
}
245+
246+
async updatePieceInstances(cache: PieceInstancesContentCache, showStyleBaseId: ShowStyleBaseId): Promise<void> {
247+
const shouldUpdateTriggers = this.tagsService.updatePieceInstances(cache, showStyleBaseId)
248+
if (shouldUpdateTriggers) {
249+
await this.updateTriggersFromLastCache()
250+
}
251+
}
252+
227253
async clearTriggers(): Promise<void> {
228254
const studioId = this.studioId
229255
const showStyleBaseId = this.#lastShowStyleBaseId

0 commit comments

Comments
 (0)