Skip to content

Commit 807baf3

Browse files
authored
feat: emit ingest 'user edit' operations from adlib actions (Sofie-Automation#1671)
1 parent c8236fb commit 807baf3

14 files changed

Lines changed: 125 additions & 11 deletions

File tree

packages/blueprints-integration/src/api/studio.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type {
1717
IngestRundown,
1818
MutableIngestRundown,
1919
UserOperationChange,
20+
PlayoutOperationChange,
2021
} from '../ingest.js'
2122
import type {
2223
ExpectedPlayoutItemGeneric,
@@ -137,7 +138,7 @@ export interface StudioBlueprintManifest<
137138
mutableIngestRundown: MutableIngestRundown<any, any, any>,
138139
nrcsIngestRundown: IngestRundown,
139140
previousNrcsIngestRundown: IngestRundown | undefined,
140-
changes: NrcsIngestChangeDetails | UserOperationChange
141+
changes: NrcsIngestChangeDetails | UserOperationChange | PlayoutOperationChange
141142
) => Promise<void>
142143
}
143144

packages/blueprints-integration/src/context/adlibActionContext.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { DatastorePersistenceMode, Time } from '../common.js'
22
import type { IEventContext } from './index.js'
33
import type { IShowStyleUserContext } from './showStyleContext.js'
44
import { IPartAndPieceActionContext } from './partsAndPieceActionContext.js'
5-
import { IExecuteTSRActionsContext } from './executeTsrActionContext.js'
5+
import { IExecuteTSRActionsContext, ITriggerIngestChangeContext } from './executeTsrActionContext.js'
66
import { IBlueprintPart, IBlueprintPartInstance, IBlueprintPiece } from '../index.js'
77
import { IRouteSetMethods } from './routeSetContext.js'
88

@@ -27,6 +27,7 @@ export interface IActionExecutionContext
2727
IDataStoreMethods,
2828
IPartAndPieceActionContext,
2929
IExecuteTSRActionsContext,
30+
ITriggerIngestChangeContext,
3031
IRouteSetMethods {
3132
/** Fetch the showstyle config for the specified part */
3233
// getNextShowStyleConfig(): Readonly<{ [key: string]: ConfigItemValue }>

packages/blueprints-integration/src/context/executeTsrActionContext.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,14 @@ export interface IExecuteTSRActionsContext {
1313
timeoutMs?: number
1414
): Promise<TSR.ActionExecutionResult>
1515
}
16+
17+
export interface ITriggerIngestChangeContext {
18+
/**
19+
* Execute an ingest operation
20+
* This dispatches the operation but does not wait for it to be processed
21+
* Note: This should be used with caution, it will not be good for performance to trigger a lot of ingest operations
22+
* during playout of a rundown, especially if they need to make changes to many segments
23+
* @param operation The blueprint defined payload for the operation
24+
*/
25+
emitIngestOperation(operation: unknown): Promise<void>
26+
}

packages/blueprints-integration/src/context/onSetAsNextContext.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import {
1010
IEventContext,
1111
IShowStyleUserContext,
1212
} from '../index.js'
13+
import { ITriggerIngestChangeContext } from './executeTsrActionContext.js'
1314
import { BlueprintQuickLookInfo } from './quickLoopInfo.js'
1415
import { ReadonlyDeep } from 'type-fest'
1516

1617
/**
1718
* Context in which 'current' is the part currently on air, and 'next' is the partInstance being set as Next
1819
* This is similar to `IPartAndPieceActionContext`, but has more limits on what is allowed to be changed.
1920
*/
20-
export interface IOnSetAsNextContext extends IShowStyleUserContext, IEventContext {
21+
export interface IOnSetAsNextContext extends IShowStyleUserContext, IEventContext, ITriggerIngestChangeContext {
2122
/** Information about the current loop, if there is one */
2223
readonly quickLoopInfo: BlueprintQuickLookInfo | null
2324

packages/blueprints-integration/src/context/onTakeContext.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import { IBlueprintPart, IBlueprintPiece, IEventContext, IShowStyleUserContext, Time } from '../index.js'
22
import { IPartAndPieceActionContext } from './partsAndPieceActionContext.js'
3-
import { IExecuteTSRActionsContext } from './executeTsrActionContext.js'
3+
import { IExecuteTSRActionsContext, ITriggerIngestChangeContext } from './executeTsrActionContext.js'
44

55
/**
66
* Context in which 'current' is the partInstance we're leaving, and 'next' is the partInstance we're taking
77
*/
88
export interface IOnTakeContext
9-
extends IPartAndPieceActionContext, IShowStyleUserContext, IEventContext, IExecuteTSRActionsContext {
9+
extends
10+
IPartAndPieceActionContext,
11+
IShowStyleUserContext,
12+
IEventContext,
13+
IExecuteTSRActionsContext,
14+
ITriggerIngestChangeContext {
1015
/** Inform core that a take out of the taken partinstance should be blocked until the specified time */
1116
blockTakeUntil(time: Time | null): Promise<void>
1217
/**

packages/blueprints-integration/src/ingest.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ export enum IngestChangeType {
8484
Ingest = 'ingest',
8585
/** Indicate that this change is from user operations */
8686
User = 'user',
87+
/** Indicate that this change is from playout operations */
88+
Playout = 'playout',
8789
}
8890

8991
/**
@@ -191,6 +193,19 @@ export interface UserOperationChange<TCustomBlueprintOperations extends { id: st
191193
operationTarget: UserOperationTarget
192194
operation: DefaultUserOperations | TCustomBlueprintOperations
193195
}
196+
export interface PlayoutOperationChange {
197+
/** Indicate that this change is from playout operations */
198+
source: IngestChangeType.Playout
199+
200+
/** If known and valid, the id of the segment when this operation occurred */
201+
currentSegmentId: string | null
202+
/** If known and valid, the id of the part when this operation occurred */
203+
currentPartId: string | null
204+
205+
/** The blueprint defined payload for the operation */
206+
operation: unknown
207+
}
208+
194209
/**
195210
* The MutableIngestRundown is used to modify the contents of an IngestRundown during ingest.
196211
* The public properties and methods are used i blueprints to selectively apply incoming

packages/corelib/src/worker/ingest.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
BucketAdLibId,
44
BucketId,
55
ExpectedPackageId,
6+
PartId,
67
RundownId,
78
SegmentId,
89
ShowStyleBaseId,
@@ -123,6 +124,11 @@ export enum IngestJobs {
123124
*/
124125
UserExecuteChangeOperation = 'userExecuteChangeOperation',
125126

127+
/**
128+
* Playout executed a change operation
129+
*/
130+
PlayoutExecuteChangeOperation = 'playoutExecuteChangeOperation',
131+
126132
// For now these are in this queue, but if this gets split up to be per rundown, then a single bucket queue will be needed
127133
BucketItemImport = 'bucketItemImport',
128134
BucketItemRegenerate = 'bucketItemRegenerate',
@@ -242,6 +248,12 @@ export interface UserExecuteChangeOperationProps extends IngestPropsBase {
242248
operation: { id: string; [key: string]: any }
243249
}
244250

251+
export interface PlayoutExecuteChangeOperationProps extends IngestPropsBase {
252+
segmentId: SegmentId | null
253+
partId: PartId | null
254+
operation: unknown
255+
}
256+
245257
export interface BucketItemImportProps {
246258
bucketId: BucketId
247259
showStyleBaseId: ShowStyleBaseId
@@ -310,6 +322,7 @@ export type IngestJobFunc = {
310322
[IngestJobs.UserRemoveRundown]: (data: UserRemoveRundownProps) => void
311323
[IngestJobs.UserUnsyncRundown]: (data: UserUnsyncRundownProps) => void
312324
[IngestJobs.UserExecuteChangeOperation]: (data: UserExecuteChangeOperationProps) => void
325+
[IngestJobs.PlayoutExecuteChangeOperation]: (data: PlayoutExecuteChangeOperationProps) => void
313326

314327
[IngestJobs.BucketItemImport]: (data: BucketItemImportProps) => void
315328
[IngestJobs.BucketItemRegenerate]: (data: BucketItemRegenerateProps) => void

packages/job-worker/src/blueprints/context/OnSetAsNextContext.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { BlueprintQuickLookInfo } from '@sofie-automation/blueprints-integration
2626
import { DBPart } from '@sofie-automation/corelib/dist/dataModel/Part'
2727
import { selectNewPartWithOffsets } from '../../playout/moveNextPart.js'
2828
import { getOrderedPartsAfterPlayhead } from '../../playout/lookahead/util.js'
29-
import { convertPartToBlueprints } from './lib.js'
29+
import { convertPartToBlueprints, emitIngestOperation } from './lib.js'
3030

3131
export class OnSetAsNextContext
3232
extends ShowStyleUserContext
@@ -156,6 +156,10 @@ export class OnSetAsNextContext
156156
return !!this.pendingMoveNextPart.selectedPart
157157
}
158158

159+
async emitIngestOperation(operation: unknown): Promise<void> {
160+
await emitIngestOperation(this.jobContext, this.playoutModel, operation)
161+
}
162+
159163
getCurrentTime(): number {
160164
return getCurrentTime()
161165
}

packages/job-worker/src/blueprints/context/OnTakeContext.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import {
3030
} from './services/PartAndPieceInstanceActionService.js'
3131
import { BlueprintQuickLookInfo } from '@sofie-automation/blueprints-integration/dist/context/quickLoopInfo'
3232
import { getOrderedPartsAfterPlayhead } from '../../playout/lookahead/util.js'
33-
import { convertPartToBlueprints } from './lib.js'
33+
import { convertPartToBlueprints, emitIngestOperation } from './lib.js'
3434

3535
export class OnTakeContext extends ShowStyleUserContext implements IOnTakeContext, IEventContext {
3636
public isTakeAborted: boolean
@@ -182,6 +182,10 @@ export class OnTakeContext extends ShowStyleUserContext implements IOnTakeContex
182182
)
183183
}
184184

185+
async emitIngestOperation(operation: unknown): Promise<void> {
186+
await emitIngestOperation(this._context, this._playoutModel, operation)
187+
}
188+
185189
getCurrentTime(): number {
186190
return getCurrentTime()
187191
}

packages/job-worker/src/blueprints/context/adlibActions.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
import { BlueprintQuickLookInfo } from '@sofie-automation/blueprints-integration/dist/context/quickLoopInfo'
3838
import { setNextPartFromPart } from '../../playout/setNext.js'
3939
import { getOrderedPartsAfterPlayhead } from '../../playout/lookahead/util.js'
40-
import { convertPartToBlueprints } from './lib.js'
40+
import { convertPartToBlueprints, emitIngestOperation } from './lib.js'
4141

4242
export class DatastoreActionExecutionContext
4343
extends ShowStyleUserContext
@@ -278,6 +278,10 @@ export class ActionExecutionContext extends ShowStyleUserContext implements IAct
278278
})
279279
}
280280

281+
async emitIngestOperation(operation: unknown): Promise<void> {
282+
await emitIngestOperation(this._context, this._playoutModel, operation)
283+
}
284+
281285
getCurrentTime(): number {
282286
return getCurrentTime()
283287
}

0 commit comments

Comments
 (0)