Skip to content

Commit 94b9839

Browse files
committed
fix: adjust reactive-var typings, and propogate current computation
1 parent 42249dd commit 94b9839

File tree

10 files changed

+157
-132
lines changed

10 files changed

+157
-132
lines changed

meteor/server/api/deviceTriggers/observer.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ MeteorStartupAsync(async () => {
4444
const manager = new StudioDeviceTriggerManager(studioId)
4545
const observer = new StudioObserver(studioId, (showStyleBaseId, cache) => {
4646
workInQueue(async () => {
47-
await manager.updateTriggers(cache, showStyleBaseId, null) // nocommit - confirm this
47+
await manager.updateTriggers(cache, showStyleBaseId, null)
4848
})
4949

5050
return () => {
@@ -117,10 +117,12 @@ export async function receiveInputDeviceTrigger(
117117
if (!actionManager)
118118
throw new Meteor.Error(500, `No Studio Action Manager available to handle trigger in Studio "${studioId}"`)
119119

120-
DeviceTriggerMountedActions.find({
120+
const mountedActions = DeviceTriggerMountedActions.find({
121121
deviceId,
122122
deviceTriggerId: triggerId,
123-
}).forEach((mountedAction) => {
123+
}).fetch()
124+
125+
for (const mountedAction of mountedActions) {
124126
if (values && !_.isMatch(values, mountedAction.values)) return
125127
const executableAction = actionManager.getAction(mountedAction.actionId)
126128
if (!executableAction)
@@ -132,6 +134,6 @@ export async function receiveInputDeviceTrigger(
132134
const context = actionManager.getContext()
133135
if (!context) throw new Meteor.Error(500, `Undefined Device Trigger context for studio "${studioId}"`)
134136

135-
executableAction.execute((t: ITranslatableMessage) => t.key ?? t, `${deviceId}: ${triggerId}`, context)
136-
})
137+
await executableAction.execute((t: ITranslatableMessage) => t.key ?? t, `${deviceId}: ${triggerId}`, context)
138+
}
137139
}

meteor/server/api/deviceTriggers/triggersContext.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export function hashSingleUseToken(token: string): string {
3838
return getHash(SINGLE_USE_TOKEN_SALT + token)
3939
}
4040

41-
class TriggersCollection2<DBInterface extends { _id: ProtectedString<any> }>
41+
class MeteorTriggersCollectionWrapper<DBInterface extends { _id: ProtectedString<any> }>
4242
implements TriggersAsyncCollection<DBInterface>
4343
{
4444
readonly #collection: AsyncOnlyReadOnlyMongoCollection<DBInterface>
@@ -75,14 +75,14 @@ export const MeteorTriggersContext: TriggersContext = {
7575

7676
isClient: false,
7777

78-
AdLibActions: new TriggersCollection2(AdLibActions),
79-
AdLibPieces: new TriggersCollection2(AdLibPieces),
80-
Parts: new TriggersCollection2(Parts),
81-
RundownBaselineAdLibActions: new TriggersCollection2(RundownBaselineAdLibActions),
82-
RundownBaselineAdLibPieces: new TriggersCollection2(RundownBaselineAdLibPieces),
83-
RundownPlaylists: new TriggersCollection2(RundownPlaylists),
84-
Rundowns: new TriggersCollection2(Rundowns),
85-
Segments: new TriggersCollection2(Segments),
78+
AdLibActions: new MeteorTriggersCollectionWrapper(AdLibActions),
79+
AdLibPieces: new MeteorTriggersCollectionWrapper(AdLibPieces),
80+
Parts: new MeteorTriggersCollectionWrapper(Parts),
81+
RundownBaselineAdLibActions: new MeteorTriggersCollectionWrapper(RundownBaselineAdLibActions),
82+
RundownBaselineAdLibPieces: new MeteorTriggersCollectionWrapper(RundownBaselineAdLibPieces),
83+
RundownPlaylists: new MeteorTriggersCollectionWrapper(RundownPlaylists),
84+
Rundowns: new MeteorTriggersCollectionWrapper(Rundowns),
85+
Segments: new MeteorTriggersCollectionWrapper(Segments),
8686

8787
hashSingleUseToken,
8888

packages/meteor-lib/src/triggers/actionFactory.ts

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
import { DeviceActions } from '@sofie-automation/shared-lib/dist/core/model/ShowStyle'
2727
import { UserError, UserErrorMessage } from '@sofie-automation/corelib/dist/error'
2828
import { MountedAdLibTriggerType } from '../api/MountedTriggers'
29-
import { DummyReactiveVar, ReactiveVar } from './reactive-var'
29+
import { DummyReactiveVar, TriggerReactiveVar } from './reactive-var'
3030
import { TriggersContext, TriggerTrackerComputation } from './triggersContext'
3131
import { assertNever } from '@sofie-automation/corelib/dist/lib'
3232

@@ -36,18 +36,18 @@ type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }
3636
type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U
3737

3838
export interface ReactivePlaylistActionContext {
39-
studioId: ReactiveVar<StudioId>
40-
rundownPlaylistId: ReactiveVar<RundownPlaylistId>
41-
rundownPlaylist: ReactiveVar<
39+
studioId: TriggerReactiveVar<StudioId>
40+
rundownPlaylistId: TriggerReactiveVar<RundownPlaylistId>
41+
rundownPlaylist: TriggerReactiveVar<
4242
Pick<DBRundownPlaylist, '_id' | 'name' | 'activationId' | 'nextPartInfo' | 'currentPartInfo'>
4343
>
4444

45-
currentRundownId: ReactiveVar<RundownId | null>
46-
currentSegmentPartIds: ReactiveVar<PartId[]>
47-
nextSegmentPartIds: ReactiveVar<PartId[]>
48-
currentPartInstanceId: ReactiveVar<PartInstanceId | null>
49-
currentPartId: ReactiveVar<PartId | null>
50-
nextPartId: ReactiveVar<PartId | null>
45+
currentRundownId: TriggerReactiveVar<RundownId | null>
46+
currentSegmentPartIds: TriggerReactiveVar<PartId[]>
47+
nextSegmentPartIds: TriggerReactiveVar<PartId[]>
48+
currentPartInstanceId: TriggerReactiveVar<PartInstanceId | null>
49+
currentPartId: TriggerReactiveVar<PartId | null>
50+
nextPartId: TriggerReactiveVar<PartId | null>
5151
}
5252

5353
interface PlainPlaylistContext {
@@ -111,7 +111,6 @@ async function createRundownPlaylistContext(
111111
if (filterChain.length < 1) {
112112
return undefined
113113
} else if (filterChain[0].object === 'view' && context.rundownPlaylistId) {
114-
// nocommit - rewrap to track on this computation?
115114
return context as ReactivePlaylistActionContext
116115
} else if (filterChain[0].object === 'view' && context.rundownPlaylist) {
117116
const playlistContext = context as PlainPlaylistContext
@@ -180,11 +179,11 @@ function createAdLibAction(
180179
)
181180
return
182181
}
183-
const currentPartInstanceId = innerCtx.rundownPlaylist.get().currentPartInfo?.partInstanceId
182+
const currentPartInstanceId = innerCtx.rundownPlaylist.get(null).currentPartInfo?.partInstanceId
184183

185184
const sourceLayerIdsToClear: string[] = []
186185

187-
// nocommit - discard the withComputation?
186+
// This withComputation is probably not needed, but is a nice safeguard
188187
const wrappedAdLibs = await triggersContext.withComputation(null, async () =>
189188
compiledAdLibFilter(innerCtx, null)
190189
)
@@ -197,7 +196,7 @@ function createAdLibAction(
197196
? triggersContext.MeteorCall.userAction.segmentAdLibPieceStart(
198197
e,
199198
ts,
200-
innerCtx.rundownPlaylistId.get(),
199+
innerCtx.rundownPlaylistId.get(null),
201200
currentPartInstanceId,
202201
wrappedAdLib.item._id,
203202
false
@@ -211,7 +210,7 @@ function createAdLibAction(
211210
? triggersContext.MeteorCall.userAction.baselineAdLibPieceStart(
212211
e,
213212
ts,
214-
innerCtx.rundownPlaylistId.get(),
213+
innerCtx.rundownPlaylistId.get(null),
215214
currentPartInstanceId,
216215
wrappedAdLib.item._id,
217216
false
@@ -224,7 +223,7 @@ function createAdLibAction(
224223
triggersContext.MeteorCall.userAction.executeAction(
225224
e,
226225
ts,
227-
innerCtx.rundownPlaylistId.get(),
226+
innerCtx.rundownPlaylistId.get(null),
228227
wrappedAdLib._id,
229228
wrappedAdLib.item.actionId,
230229
wrappedAdLib.item.userData,
@@ -237,7 +236,7 @@ function createAdLibAction(
237236
triggersContext.MeteorCall.userAction.executeAction(
238237
e,
239238
ts,
240-
innerCtx.rundownPlaylistId.get(),
239+
innerCtx.rundownPlaylistId.get(null),
241240
wrappedAdLib._id,
242241
wrappedAdLib.item.actionId,
243242
wrappedAdLib.item.userData,
@@ -254,7 +253,7 @@ function createAdLibAction(
254253
triggersContext.MeteorCall.userAction.sourceLayerStickyPieceStart(
255254
e,
256255
ts,
257-
innerCtx.rundownPlaylistId.get(),
256+
innerCtx.rundownPlaylistId.get(null),
258257
wrappedAdLib.sourceLayerId //
259258
)
260259
)
@@ -270,7 +269,7 @@ function createAdLibAction(
270269
triggersContext.MeteorCall.userAction.sourceLayerOnPartStop(
271270
e,
272271
ts,
273-
innerCtx.rundownPlaylistId.get(),
272+
innerCtx.rundownPlaylistId.get(null),
274273
currentPartInstanceId,
275274
sourceLayerIdsToClear
276275
)
@@ -463,7 +462,7 @@ export function createAction(
463462
triggersContext.MeteorCall.userAction.forceResetAndActivate(
464463
e,
465464
ts,
466-
ctx.rundownPlaylistId.get(),
465+
ctx.rundownPlaylistId.get(null),
467466
!!action.rehearsal || false
468467
)
469468
)
@@ -482,7 +481,7 @@ export function createAction(
482481
triggersContext.MeteorCall.userAction.activate(
483482
e,
484483
ts,
485-
ctx.rundownPlaylistId.get(),
484+
ctx.rundownPlaylistId.get(null),
486485
!!action.rehearsal || false
487486
)
488487
)
@@ -497,20 +496,20 @@ export function createAction(
497496
action,
498497
UserAction.DEACTIVATE_RUNDOWN_PLAYLIST,
499498
async (e, ts, ctx) =>
500-
triggersContext.MeteorCall.userAction.deactivate(e, ts, ctx.rundownPlaylistId.get())
499+
triggersContext.MeteorCall.userAction.deactivate(e, ts, ctx.rundownPlaylistId.get(null))
501500
)
502501
case PlayoutActions.activateAdlibTestingMode:
503502
return createUserActionWithCtx(
504503
triggersContext,
505504
action,
506505
UserAction.ACTIVATE_ADLIB_TESTING,
507506
async (e, ts, ctx) => {
508-
const rundownId = ctx.currentRundownId.get()
507+
const rundownId = ctx.currentRundownId.get(null)
509508
if (rundownId) {
510509
return triggersContext.MeteorCall.userAction.activateAdlibTestingMode(
511510
e,
512511
ts,
513-
ctx.rundownPlaylistId.get(),
512+
ctx.rundownPlaylistId.get(null),
514513
rundownId
515514
)
516515
} else {
@@ -526,21 +525,26 @@ export function createAction(
526525
triggersContext.MeteorCall.userAction.take(
527526
e,
528527
ts,
529-
ctx.rundownPlaylistId.get(),
530-
ctx.currentPartInstanceId.get()
528+
ctx.rundownPlaylistId.get(null),
529+
ctx.currentPartInstanceId.get(null)
531530
)
532531
)
533532
}
534533
case PlayoutActions.hold:
535534
return createUserActionWithCtx(triggersContext, action, UserAction.ACTIVATE_HOLD, async (e, ts, ctx) =>
536-
triggersContext.MeteorCall.userAction.activateHold(e, ts, ctx.rundownPlaylistId.get(), !!action.undo)
535+
triggersContext.MeteorCall.userAction.activateHold(
536+
e,
537+
ts,
538+
ctx.rundownPlaylistId.get(null),
539+
!!action.undo
540+
)
537541
)
538542
case PlayoutActions.disableNextPiece:
539543
return createUserActionWithCtx(triggersContext, action, UserAction.DISABLE_NEXT_PIECE, async (e, ts, ctx) =>
540544
triggersContext.MeteorCall.userAction.disableNextPiece(
541545
e,
542546
ts,
543-
ctx.rundownPlaylistId.get(),
547+
ctx.rundownPlaylistId.get(null),
544548
!!action.undo
545549
)
546550
)
@@ -559,7 +563,7 @@ export function createAction(
559563
e,
560564
ts,
561565
triggersContext.hashSingleUseToken(tokenResult.result),
562-
ctx.rundownPlaylistId.get(),
566+
ctx.rundownPlaylistId.get(null),
563567
`action`,
564568
false
565569
)
@@ -571,7 +575,7 @@ export function createAction(
571575
triggersContext.MeteorCall.userAction.moveNext(
572576
e,
573577
ts,
574-
ctx.rundownPlaylistId.get(),
578+
ctx.rundownPlaylistId.get(null),
575579
action.parts ?? 0,
576580
action.segments ?? 0
577581
)
@@ -587,7 +591,11 @@ export function createAction(
587591
async (e, ts, ctx) =>
588592
// TODO: Needs some handling of the response. Perhaps this should switch to
589593
// an event on the RundownViewEventBus, if ran on the client?
590-
triggersContext.MeteorCall.userAction.resyncRundownPlaylist(e, ts, ctx.rundownPlaylistId.get())
594+
triggersContext.MeteorCall.userAction.resyncRundownPlaylist(
595+
e,
596+
ts,
597+
ctx.rundownPlaylistId.get(null)
598+
)
591599
)
592600
}
593601
case PlayoutActions.resetRundownPlaylist:
@@ -599,7 +607,11 @@ export function createAction(
599607
action,
600608
UserAction.RESET_RUNDOWN_PLAYLIST,
601609
async (e, ts, ctx) =>
602-
triggersContext.MeteorCall.userAction.resetRundownPlaylist(e, ts, ctx.rundownPlaylistId.get())
610+
triggersContext.MeteorCall.userAction.resetRundownPlaylist(
611+
e,
612+
ts,
613+
ctx.rundownPlaylistId.get(null)
614+
)
603615
)
604616
}
605617
case PlayoutActions.resyncRundownPlaylist:
@@ -608,14 +620,14 @@ export function createAction(
608620
action,
609621
UserAction.RESYNC_RUNDOWN_PLAYLIST,
610622
async (e, ts, ctx) =>
611-
triggersContext.MeteorCall.userAction.resyncRundownPlaylist(e, ts, ctx.rundownPlaylistId.get())
623+
triggersContext.MeteorCall.userAction.resyncRundownPlaylist(e, ts, ctx.rundownPlaylistId.get(null))
612624
)
613625
case PlayoutActions.switchRouteSet:
614626
return createUserActionWithCtx(triggersContext, action, UserAction.SWITCH_ROUTE_SET, async (e, ts, ctx) =>
615627
triggersContext.MeteorCall.userAction.switchRouteSet(
616628
e,
617629
ts,
618-
ctx.studioId.get(),
630+
ctx.studioId.get(null),
619631
action.routeSetId,
620632
action.state
621633
)

packages/meteor-lib/src/triggers/actionFilterChainCompilers.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -505,16 +505,16 @@ export function compileAdLibFilter(
505505
let adLibActions: IWrappedAdLib[] = []
506506
const segmentPartIds =
507507
adLibPieceTypeFilter.segment === 'current'
508-
? context.currentSegmentPartIds.get()
508+
? context.currentSegmentPartIds.get(computation)
509509
: adLibPieceTypeFilter.segment === 'next'
510-
? context.nextSegmentPartIds.get()
510+
? context.nextSegmentPartIds.get(computation)
511511
: undefined
512512

513513
const singlePartId =
514514
adLibPieceTypeFilter.part === 'current'
515-
? context.currentPartId.get()
515+
? context.currentPartId.get(computation)
516516
: adLibPieceTypeFilter.part === 'next'
517-
? context.nextPartId.get()
517+
? context.nextPartId.get(computation)
518518
: undefined
519519

520520
/** Note: undefined means that all parts are to be considered */
@@ -554,7 +554,7 @@ export function compileAdLibFilter(
554554
}
555555
}
556556

557-
const currentRundownId = context.currentRundownId.get()
557+
const currentRundownId = context.currentRundownId.get(computation)
558558
if (!skip && currentRundownId) {
559559
if (adLibPieceTypeFilter.global === undefined || adLibPieceTypeFilter.global === true)
560560
rundownBaselineAdLibItems = (
@@ -597,7 +597,7 @@ export function compileAdLibFilter(
597597
}
598598
}
599599

600-
const currentRundownId = context.currentRundownId.get()
600+
const currentRundownId = context.currentRundownId.get(computation)
601601
if (!skip && currentRundownId) {
602602
if (adLibActionTypeFilter.global === undefined || adLibActionTypeFilter.global === true)
603603
rundownBaselineAdLibActions = (
@@ -636,7 +636,7 @@ export function compileAdLibFilter(
636636
// Note: We need to return an array from within memoizedIsolatedAutorun,
637637
// because _.isEqual (used in memoizedIsolatedAutorun) doesn't work with Maps..
638638

639-
const rundownPlaylistId = context.rundownPlaylistId.get()
639+
const rundownPlaylistId = context.rundownPlaylistId.get(computation)
640640
const rundownRanks = await triggersContext.memoizedIsolatedAutorun(
641641
computation,
642642
async (computation) => {

packages/meteor-lib/src/triggers/reactive-var.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import type { TriggerTrackerComputation } from './triggersContext'
2+
13
// Copied from Meteor
2-
export interface ReactiveVar<T> {
4+
export interface TriggerReactiveVar<T> {
35
/**
46
* Returns the current value of the ReactiveVar, establishing a reactive dependency.
57
*/
6-
get(): T
8+
get(computation: TriggerTrackerComputation | null): T
79
/**
810
* Sets the current value of the ReactiveVar, invalidating the Computations that called `get` if `newValue` is different from the old value.
911
*/
@@ -14,7 +16,7 @@ export interface ReactiveVar<T> {
1416
* This just looks like a ReactiveVar, but is not reactive.
1517
* It's used to use the same interface/typings, but when code is run on both client and server side.
1618
* */
17-
export class DummyReactiveVar<T> implements ReactiveVar<T> {
19+
export class DummyReactiveVar<T> implements TriggerReactiveVar<T> {
1820
constructor(private value: T) {}
1921
public get(): T {
2022
return this.value

0 commit comments

Comments
 (0)