Skip to content

Commit 2f58d71

Browse files
committed
feat: rework ExpectedPackages generation/management to share documents within rundown/bucket
1 parent f925ec0 commit 2f58d71

File tree

23 files changed

+569
-526
lines changed

23 files changed

+569
-526
lines changed

meteor/server/api/ingest/packageInfo.ts

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,29 @@ export async function onUpdatedPackageInfo(packageId: ExpectedPackageId, _doc: P
2525
return
2626
}
2727

28-
if (pkg.package.listenToPackageInfoUpdates) {
29-
for (const source of pkg.ingestSources) {
30-
switch (source.fromPieceType) {
31-
case ExpectedPackageDBType.PIECE:
32-
case ExpectedPackageDBType.ADLIB_PIECE:
33-
case ExpectedPackageDBType.ADLIB_ACTION:
34-
case ExpectedPackageDBType.BASELINE_ADLIB_PIECE:
35-
case ExpectedPackageDBType.BASELINE_ADLIB_ACTION:
36-
case ExpectedPackageDBType.BASELINE_PIECE:
37-
case ExpectedPackageDBType.RUNDOWN_BASELINE_OBJECTS:
38-
onUpdatedPackageInfoForRundownDebounce(pkg)
39-
break
40-
case ExpectedPackageDBType.BUCKET_ADLIB:
41-
case ExpectedPackageDBType.BUCKET_ADLIB_ACTION:
42-
onUpdatedPackageInfoForBucketItemDebounce(pkg, source)
43-
break
44-
case ExpectedPackageDBType.STUDIO_BASELINE_OBJECTS:
45-
onUpdatedPackageInfoForStudioBaselineDebounce(pkg)
46-
break
47-
default:
48-
assertNever(source)
49-
break
50-
}
28+
for (const source of pkg.ingestSources) {
29+
if (!source.listenToPackageInfoUpdates) continue
30+
31+
switch (source.fromPieceType) {
32+
case ExpectedPackageDBType.PIECE:
33+
case ExpectedPackageDBType.ADLIB_PIECE:
34+
case ExpectedPackageDBType.ADLIB_ACTION:
35+
case ExpectedPackageDBType.BASELINE_PIECE:
36+
case ExpectedPackageDBType.BASELINE_ADLIB_PIECE:
37+
case ExpectedPackageDBType.BASELINE_ADLIB_ACTION:
38+
case ExpectedPackageDBType.RUNDOWN_BASELINE_OBJECTS:
39+
onUpdatedPackageInfoForRundownDebounce(pkg)
40+
break
41+
case ExpectedPackageDBType.BUCKET_ADLIB:
42+
case ExpectedPackageDBType.BUCKET_ADLIB_ACTION:
43+
onUpdatedPackageInfoForBucketItemDebounce(pkg, source)
44+
break
45+
case ExpectedPackageDBType.STUDIO_BASELINE_OBJECTS:
46+
onUpdatedPackageInfoForStudioBaselineDebounce(pkg)
47+
break
48+
default:
49+
assertNever(source)
50+
break
5151
}
5252
}
5353
}

meteor/server/migration/X_X_X.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ export const addSteps = addMigrationSteps(CURRENT_SYSTEM_VERSION, [
5555
pieceId: pkg.pieceId,
5656
partId: pkg.partId,
5757
segmentId: pkg.segmentId,
58+
blueprintPackageId: pkg.blueprintPackageId,
59+
listenToPackageInfoUpdates: pkg.listenToPackageInfoUpdates,
5860
}
5961
break
6062
case PackagesPreR53.ExpectedPackageDBType.ADLIB_ACTION:
@@ -64,26 +66,34 @@ export const addSteps = addMigrationSteps(CURRENT_SYSTEM_VERSION, [
6466
pieceId: pkg.pieceId,
6567
partId: pkg.partId,
6668
segmentId: pkg.segmentId,
69+
blueprintPackageId: pkg.blueprintPackageId,
70+
listenToPackageInfoUpdates: pkg.listenToPackageInfoUpdates,
6771
}
6872
break
6973
case PackagesPreR53.ExpectedPackageDBType.BASELINE_ADLIB_PIECE:
7074
rundownId = pkg.rundownId
7175
ingestSource = {
7276
fromPieceType: pkg.fromPieceType,
7377
pieceId: pkg.pieceId,
78+
blueprintPackageId: pkg.blueprintPackageId,
79+
listenToPackageInfoUpdates: pkg.listenToPackageInfoUpdates,
7480
}
7581
break
7682
case PackagesPreR53.ExpectedPackageDBType.BASELINE_ADLIB_ACTION:
7783
rundownId = pkg.rundownId
7884
ingestSource = {
7985
fromPieceType: pkg.fromPieceType,
8086
pieceId: pkg.pieceId,
87+
blueprintPackageId: pkg.blueprintPackageId,
88+
listenToPackageInfoUpdates: pkg.listenToPackageInfoUpdates,
8189
}
8290
break
8391
case PackagesPreR53.ExpectedPackageDBType.RUNDOWN_BASELINE_OBJECTS:
8492
rundownId = pkg.rundownId
8593
ingestSource = {
8694
fromPieceType: pkg.fromPieceType,
95+
blueprintPackageId: pkg.blueprintPackageId,
96+
listenToPackageInfoUpdates: pkg.listenToPackageInfoUpdates,
8797
}
8898
break
8999
case PackagesPreR53.ExpectedPackageDBType.BUCKET_ADLIB:
@@ -92,6 +102,8 @@ export const addSteps = addMigrationSteps(CURRENT_SYSTEM_VERSION, [
92102
fromPieceType: pkg.fromPieceType,
93103
pieceId: pkg.pieceId,
94104
pieceExternalId: pkg.pieceExternalId,
105+
blueprintPackageId: pkg.blueprintPackageId,
106+
listenToPackageInfoUpdates: pkg.listenToPackageInfoUpdates,
95107
}
96108
break
97109
case PackagesPreR53.ExpectedPackageDBType.BUCKET_ADLIB_ACTION:
@@ -100,11 +112,15 @@ export const addSteps = addMigrationSteps(CURRENT_SYSTEM_VERSION, [
100112
fromPieceType: pkg.fromPieceType,
101113
pieceId: pkg.pieceId,
102114
pieceExternalId: pkg.pieceExternalId,
115+
blueprintPackageId: pkg.blueprintPackageId,
116+
listenToPackageInfoUpdates: pkg.listenToPackageInfoUpdates,
103117
}
104118
break
105119
case PackagesPreR53.ExpectedPackageDBType.STUDIO_BASELINE_OBJECTS:
106120
ingestSource = {
107121
fromPieceType: pkg.fromPieceType,
122+
blueprintPackageId: pkg.blueprintPackageId,
123+
listenToPackageInfoUpdates: pkg.listenToPackageInfoUpdates,
108124
}
109125
break
110126
default:

meteor/server/publications/pieceContentStatusUI/checkPieceContentStatus.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ import {
1111
VTContent,
1212
} from '@sofie-automation/blueprints-integration'
1313
import {
14-
ExpectedPackageDBType,
1514
getExpectedPackageIdForPieceInstance,
16-
getExpectedPackageIdFromIngestSource,
15+
getExpectedPackageIdNew,
1716
} from '@sofie-automation/corelib/dist/dataModel/ExpectedPackages'
1817
import {
1918
BucketId,
@@ -670,21 +669,7 @@ async function checkPieceContentExpectedPackageStatus(
670669

671670
checkedPackageContainers.add(matchedPackageContainer[0])
672671

673-
const expectedPackageIds = [
674-
// Synthesize the expected packageId from the piece
675-
getExpectedPackageIdFromIngestSource(
676-
packageOwnerId,
677-
{
678-
fromPieceType: ExpectedPackageDBType.PIECE,
679-
// HACK: This shouldn't be cast as any, because this could be a bucket piece, but that gives the same result
680-
pieceId: piece._id as any,
681-
// HACK: We need a value, but the method doesn't use them..
682-
partId: piece._id as any,
683-
segmentId: piece._id as any,
684-
},
685-
expectedPackage._id
686-
),
687-
]
672+
const expectedPackageIds = [getExpectedPackageIdNew(packageOwnerId, expectedPackage)]
688673
if (piece.pieceInstanceId) {
689674
// If this is a PieceInstance, try looking up the PieceInstance first
690675
expectedPackageIds.unshift(

packages/corelib/src/dataModel/ExpectedPackages.ts

Lines changed: 37 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ExpectedPackage, Time } from '@sofie-automation/blueprints-integration'
2-
import { protectString, unprotectString } from '../protectedString.js'
3-
import { getHash, assertNever } from '../lib.js'
2+
import { protectString } from '../protectedString.js'
3+
import { getHash, hashObj } from '../lib.js'
44
import {
55
AdLibActionId,
66
BucketAdLibActionId,
@@ -52,33 +52,43 @@ export interface ExpectedPackageDB {
5252

5353
created: Time
5454

55-
package: ReadonlyDeep<ExpectedPackage.Any>
55+
package: ReadonlyDeep<Omit<ExpectedPackage.Base, 'listenToPackageInfoUpdates'>>
5656

57-
// HACK: This should be ExpectedPackageIngestSource[], but for the first iteration this is limited to a single source
58-
ingestSources: [ExpectedPackageIngestSource]
57+
/**
58+
* The ingest sources that generated this package.
59+
*/
60+
ingestSources: ExpectedPackageIngestSource[]
5961

6062
// playoutSources: {
6163
// /** Any playout PieceInstance. This is limited to the current and next partInstances */
6264
// pieceInstanceIds: PieceInstanceId[]
6365
// }
6466
}
6567

66-
export interface ExpectedPackageIngestSourceBucketPiece {
68+
export interface ExpectedPackageIngestSourceBase {
69+
/** The id of the package as known by the blueprints */
70+
blueprintPackageId: string
71+
72+
/** Whether the blueprints are listening for updates to packageInfos for this package */
73+
listenToPackageInfoUpdates: boolean | undefined
74+
}
75+
76+
export interface ExpectedPackageIngestSourceBucketAdlibPiece extends ExpectedPackageIngestSourceBase {
6777
fromPieceType: ExpectedPackageDBType.BUCKET_ADLIB
6878
/** The Bucket adlib this package belongs to */
6979
pieceId: BucketAdLibId
7080
/** The `externalId` of the Bucket adlib this package belongs to */
7181
pieceExternalId: string
7282
}
73-
export interface ExpectedPackageIngestSourceBucketAdlibAction {
83+
export interface ExpectedPackageIngestSourceBucketAdlibAction extends ExpectedPackageIngestSourceBase {
7484
fromPieceType: ExpectedPackageDBType.BUCKET_ADLIB_ACTION
7585
/** The Bucket adlib-action this package belongs to */
7686
pieceId: BucketAdLibActionId
7787
/** The `externalId` of the Bucket adlib-action this package belongs to */
7888
pieceExternalId: string
7989
}
8090

81-
export interface ExpectedPackageIngestSourcePiece {
91+
export interface ExpectedPackageIngestSourcePiece extends ExpectedPackageIngestSourceBase {
8292
fromPieceType: ExpectedPackageDBType.PIECE | ExpectedPackageDBType.ADLIB_PIECE
8393
/** The Piece this package belongs to */
8494
pieceId: PieceId
@@ -87,7 +97,7 @@ export interface ExpectedPackageIngestSourcePiece {
8797
/** The Segment this package belongs to */
8898
segmentId: SegmentId
8999
}
90-
export interface ExpectedPackageIngestSourceAdlibAction {
100+
export interface ExpectedPackageIngestSourceAdlibAction extends ExpectedPackageIngestSourceBase {
91101
fromPieceType: ExpectedPackageDBType.ADLIB_ACTION
92102
/** The Piece this package belongs to */
93103
pieceId: AdLibActionId
@@ -96,34 +106,34 @@ export interface ExpectedPackageIngestSourceAdlibAction {
96106
/** The Segment this package belongs to */
97107
segmentId: SegmentId
98108
}
99-
export interface ExpectedPackageIngestSourceBaselinePiece {
109+
export interface ExpectedPackageIngestSourceBaselinePiece extends ExpectedPackageIngestSourceBase {
100110
fromPieceType: ExpectedPackageDBType.BASELINE_PIECE
101111
/** The Piece this package belongs to */
102112
pieceId: PieceId
103113
}
104-
export interface ExpectedPackageIngestSourceBaselineAdlibPiece {
114+
export interface ExpectedPackageIngestSourceBaselineAdlibPiece extends ExpectedPackageIngestSourceBase {
105115
fromPieceType: ExpectedPackageDBType.BASELINE_ADLIB_PIECE
106116
/** The Piece this package belongs to */
107117
pieceId: PieceId
108118
}
109-
export interface ExpectedPackageIngestSourceBaselineAdlibAction {
119+
export interface ExpectedPackageIngestSourceBaselineAdlibAction extends ExpectedPackageIngestSourceBase {
110120
fromPieceType: ExpectedPackageDBType.BASELINE_ADLIB_ACTION
111121
/** The Piece this package belongs to */
112122
pieceId: RundownBaselineAdLibActionId
113123
}
114-
export interface ExpectedPackageIngestSourceBaselineObjects {
124+
export interface ExpectedPackageIngestSourceBaselineObjects extends ExpectedPackageIngestSourceBase {
115125
fromPieceType: ExpectedPackageDBType.RUNDOWN_BASELINE_OBJECTS
116126
}
117127

118-
export interface ExpectedPackageIngestSourceStudioBaseline {
128+
export interface ExpectedPackageIngestSourceStudioBaseline extends ExpectedPackageIngestSourceBase {
119129
// Future: Technically this is a playout source, but for now it needs to be treated as an ingest source
120130
fromPieceType: ExpectedPackageDBType.STUDIO_BASELINE_OBJECTS
121131
}
122132

123133
export type ExpectedPackageIngestSourcePart = ExpectedPackageIngestSourcePiece | ExpectedPackageIngestSourceAdlibAction
124134

125135
export type ExpectedPackageIngestSourceBucket =
126-
| ExpectedPackageIngestSourceBucketPiece
136+
| ExpectedPackageIngestSourceBucketAdlibPiece
127137
| ExpectedPackageIngestSourceBucketAdlibAction
128138

129139
export type ExpectedPackageIngestSourceRundownBaseline =
@@ -152,57 +162,21 @@ export function getExpectedPackageIdForPieceInstance(
152162
}
153163

154164
/**
155-
* Generate the temporary expectedPackageId for the given package.
156-
* Note: This will soon be replaced with a new flow based on the contentVersionHash once shared ownership is implemented.
165+
* Generate the expectedPackageId for the given expectedPackage.
166+
* This is a stable id derived from the package and its parent. This document is expected to be owned by multiple sources.
157167
*/
158-
export function getExpectedPackageIdFromIngestSource(
168+
export function getExpectedPackageIdNew(
159169
/** Preferably a RundownId or BucketId, but StudioId is allowed when not owned by a rundown or bucket */
160170
parentId: RundownId | StudioId | BucketId,
161-
source: ExpectedPackageIngestSource,
162171
/** The locally unique id of the expectedPackage */
163-
localExpectedPackageId: ExpectedPackage.Base['_id']
172+
expectedPackage: ReadonlyDeep<Omit<ExpectedPackage.Base, 'listenToPackageInfoUpdates'>>
164173
): ExpectedPackageId {
165-
let ownerId: string
166-
const ownerPieceType = source.fromPieceType
167-
switch (source.fromPieceType) {
168-
case ExpectedPackageDBType.PIECE:
169-
case ExpectedPackageDBType.ADLIB_PIECE:
170-
case ExpectedPackageDBType.ADLIB_ACTION:
171-
case ExpectedPackageDBType.BASELINE_PIECE:
172-
case ExpectedPackageDBType.BASELINE_ADLIB_PIECE:
173-
case ExpectedPackageDBType.BASELINE_ADLIB_ACTION:
174-
ownerId = unprotectString(source.pieceId)
175-
break
176-
case ExpectedPackageDBType.RUNDOWN_BASELINE_OBJECTS:
177-
ownerId = 'rundownBaselineObjects'
178-
break
179-
case ExpectedPackageDBType.STUDIO_BASELINE_OBJECTS:
180-
ownerId = 'studioBaseline'
181-
break
182-
case ExpectedPackageDBType.BUCKET_ADLIB:
183-
case ExpectedPackageDBType.BUCKET_ADLIB_ACTION:
184-
ownerId = unprotectString(source.pieceId)
185-
break
186-
187-
default:
188-
assertNever(source)
189-
throw new Error(`Unknown fromPieceType "${ownerPieceType}"`)
190-
}
191-
return protectString(`${parentId}_${ownerId}_${getHash(localExpectedPackageId)}`)
174+
// This may be too agressive, but we don't know how to merge some of the properties
175+
const objHash = hashObj({
176+
...expectedPackage,
177+
_id: '', // Ignore the _id, this is not guaranteed to be stable
178+
listenToPackageInfoUpdates: false, // Not relevant for the hash
179+
} satisfies ReadonlyDeep<ExpectedPackage.Base>)
180+
181+
return protectString(`${parentId}_${getHash(objHash)}`)
192182
}
193-
194-
// Future implementation of id generation, once shared ownership is implemented
195-
// export function getExpectedPackageIdNew(
196-
// /** _id of the rundown*/
197-
// rundownId: RundownId,
198-
// /** The locally unique id of the expectedPackage */
199-
// expectedPackage: ReadonlyDeep<ExpectedPackage.Any>
200-
// ): ExpectedPackageId {
201-
// // This may be too agressive, but we don't know how to merge some of the properties
202-
// const objHash = hashObj({
203-
// ...expectedPackage,
204-
// listenToPackageInfoUpdates: false, // Not relevant for the hash
205-
// } satisfies ReadonlyDeep<ExpectedPackage.Any>)
206-
207-
// return protectString(`${rundownId}_${getHash(objHash)}`)
208-
// }

0 commit comments

Comments
 (0)