@@ -2,6 +2,7 @@ import { normalizeResolveRequest, normalizeStreamCandidate } from "./contracts.m
22import { addEvidenceError , newEvidenceRecord , recordStage , summarizeEvidence } from "./evidence.mjs" ;
33import { validateMediaCandidates } from "./media-validator.mjs" ;
44import { planRepair } from "./repair-brain.mjs" ;
5+ import { presentStreamCandidates } from "./stream-presentation.mjs" ;
56
67const PIPELINE = Object . freeze ( [ "homepage" , "search" , "identity" , "detail" , "episode" , "player" , "media" , "validation" ] ) ;
78
@@ -10,6 +11,10 @@ export class ResolverCore {
1011 this . maxRepairHypotheses = Math . max ( 1 , Math . min ( 3 , Number ( options . maxRepairHypotheses ?? 3 ) ) ) ;
1112 this . mediaValidator = options . mediaValidator ?? validateMediaCandidates ;
1213 this . mediaValidationOptions = options . mediaValidationOptions ?? { } ;
14+ // Optional shared metadata resolver (normally TMDB-backed). Metadata enriches
15+ // presentation only: a metadata outage must never turn a playable provider into
16+ // a provider failure or fabricate media facts.
17+ this . metadataResolver = typeof options . metadataResolver === "function" ? options . metadataResolver : null ;
1318 }
1419
1520 async resolve ( { provider, adapter, request, fixtureId = "adhoc" , clientRef = "unknown" , runtimeCompatibility = null } ) {
@@ -36,6 +41,15 @@ export class ResolverCore {
3641 streams : [ ] ,
3742 } ;
3843
44+ if ( this . metadataResolver ) {
45+ try {
46+ const metadata = await this . metadataResolver ( canonical ) ;
47+ if ( metadata && typeof metadata === "object" ) context . state . coreMetadata = metadata ;
48+ } catch ( error ) {
49+ context . state . coreMetadataError = String ( error ?. message ?? error ) ;
50+ }
51+ }
52+
3953 try {
4054 if ( typeof adapter . discover === "function" ) {
4155 const discovery = await adapter . discover ( context ) ;
@@ -71,6 +85,7 @@ export class ResolverCore {
7185
7286 if ( stage === "media" ) {
7387 context . streams = normalizeStreams ( result , provider . id ) ;
88+ context . streams = presentStreamCandidates ( context . streams , presentationMetadata ( context ) , provider ) ;
7489 evidence . playableStreams = 0 ;
7590 recordStage ( evidence , stage , stageEvidence ( stage , { ...asObject ( result ) , streams : context . streams } ) ) ;
7691 } else if ( stage === "validation" ) {
@@ -192,6 +207,22 @@ function normalizeStreams(result, providerId) {
192207 return out ;
193208}
194209
210+ function presentationMetadata ( context ) {
211+ const request = context . request ?? { } ;
212+ const shared = context . state . coreMetadata && typeof context . state . coreMetadata === "object"
213+ ? context . state . coreMetadata
214+ : { } ;
215+ const providerMetadata = context . state . metadata && typeof context . state . metadata === "object"
216+ ? context . state . metadata
217+ : { } ;
218+ return {
219+ title : request . title ?? null ,
220+ year : request . year ?? null ,
221+ ...shared ,
222+ ...providerMetadata ,
223+ } ;
224+ }
225+
195226function applyValidationResult ( context , result = { } ) {
196227 const rows = Array . isArray ( result . results ) ? result . results : [ ] ;
197228 const byUrl = new Map ( rows . map ( ( row ) => [ row ?. candidate ?. url , row ?. validation ] ) ) ;
0 commit comments