/** * SimidSession — IAB SIMID 1.2 (Secure Interactive Media Interface Definition) implementation. * * SIMID 1.2 session initialization sequence: * 1. Creative → Player : createSession (with sessionId) * 2. Player → Creative: resolve (acks createSession) * 3. Player → Creative: SIMID:Player:init (environmentData + creativeData) * 4. Creative → Player : resolve (acks init) * 5. Creative → Player : SIMID:Creative:ready * 6. Player → Creative: SIMID:Player:startCreative * 7. Creative → Player : resolve (acks startCreative) * * Message format notes: * - Some SIMID creatives post messages as JSON-encoded strings rather than plain objects. * handleMessage() handles both via parseMessageData(). * - The outgoing format mirrors the incoming format: if the creative sends JSON strings * (i.e. JSON.parse(event.data) is used on the creative side), the player also sends * JSON strings so they parse correctly. Format is auto-detected on the first message. * - Older creatives may skip createSession and go straight to SIMID:Creative:ready. * onCreativeReady() falls back to sending init + startCreative in that case. * * Spec: https://iabtechlab.com/standards/simid/ */ export declare const SIMID_PLAYER: { readonly INIT: "SIMID:Player:init"; readonly START_CREATIVE: "SIMID:Player:startCreative"; readonly AD_PROGRESS: "SIMID:Player:adProgress"; readonly AD_PAUSED: "SIMID:Player:adPaused"; readonly AD_PLAYING: "SIMID:Player:adPlaying"; readonly AD_STOPPED: "SIMID:Player:adStopped"; readonly AD_SKIPPED: "SIMID:Player:adSkipped"; readonly AD_VOLUME: "SIMID:Player:adVolume"; readonly AD_DURATION_CHANGE: "SIMID:Player:adDurationChange"; readonly RESIZE: "SIMID:Player:resize"; readonly FATAL: "SIMID:Player:fatal"; readonly LOG: "SIMID:Player:log"; readonly APP_BACKGROUNDED: "SIMID:Player:appBackgrounded"; readonly APP_FOREGROUNDED: "SIMID:Player:appForegrounded"; /** Player resolves a creative request (spec type: "resolve") */ readonly RESOLVE: "resolve"; /** Player rejects a creative request (spec type: "reject") */ readonly REJECT: "reject"; }; /** SIMID 1.2 media event types — player bridges ad video DOM events to these postMessages. */ export declare const SIMID_MEDIA: { readonly DURATION_CHANGE: "SIMID:Media:durationchange"; readonly ENDED: "SIMID:Media:ended"; readonly ERROR: "SIMID:Media:error"; readonly PAUSE: "SIMID:Media:pause"; readonly PLAY: "SIMID:Media:play"; readonly PLAYING: "SIMID:Media:playing"; readonly SEEKED: "SIMID:Media:seeked"; readonly SEEKING: "SIMID:Media:seeking"; readonly STALLED: "SIMID:Media:stalled"; readonly TIME_UPDATE: "SIMID:Media:timeupdate"; readonly VOLUME_CHANGE: "SIMID:Media:volumechange"; }; export declare const SIMID_CREATIVE: { readonly READY: "SIMID:Creative:ready"; readonly GET_MEDIA_STATE: "SIMID:Creative:getMediaState"; readonly RESOLVE: "SIMID:Creative:resolve"; readonly REJECT: "SIMID:Creative:reject"; readonly REQUEST_FULLSCREEN: "SIMID:Creative:requestFullscreen"; readonly REQUEST_RESIZE: "SIMID:Creative:requestResize"; readonly CLICK_THROUGH: "SIMID:Creative:clickThrough"; readonly REPORT_TRACKING: "SIMID:Creative:reportTracking"; readonly REQUEST_SKIP: "SIMID:Creative:requestSkip"; readonly REQUEST_STOP: "SIMID:Creative:requestStop"; readonly REQUEST_PAUSE: "SIMID:Creative:requestPause"; readonly REQUEST_PLAY: "SIMID:Creative:requestPlay"; readonly REQUEST_CHANGE_AD_DURATION: "SIMID:Creative:requestChangeAdDuration"; readonly FATAL: "SIMID:Creative:fatal"; readonly LOG: "SIMID:Creative:log"; }; export type SimidCallbacks = { onSkip: () => void; onStop: () => void; onPause: () => void; onPlay: () => void; onClickThrough: (url: string) => void; onTrackingEvent: (event: string, data?: any) => void; onFatal: (errorCode: number, reason: string) => void; onLog?: (data: any) => void; /** * Called when the creative requests a duration change (SIMID:Creative:requestChangeAdDuration). * The handler receives the requested delta in seconds and resolve/reject callbacks. * If omitted the player auto-rejects the request. */ onRequestChangeAdDuration?: (durationChange: number, resolve: () => void, reject: (errorCode: number, reason: string) => void) => void; }; /** Creative-specific metadata extracted from the VAST creative object. */ export type SimidCreativeInfo = { /** VAST content (required by spec, use '' when absent). */ adParameters?: string; /** VAST URL for the ad. */ clickThruUri?: string; }; export declare class SimidSession { private iframe; private adVideo; private callbacks; private creativeInfo?; private msgCounter; private pending; private messageListener; private sessionId; private initSent; private initPromise; private started; private destroyed; private mediaListeners; private visibilityHandler; /** * Detected outgoing message format. * 'plain' — post plain JS objects (spec default, works with most creatives) * 'json-string' — post JSON.stringify(payload) as the message value; used when the * creative calls JSON.parse(event.data) to deserialise incoming messages * (e.g. Google's compiled SIMID sample creative) */ private outgoingFormat; private _targetOrigin; /** Authoritative window to postMessage to — pinned from event.source on first valid message. */ private creativeWindow; constructor(iframe: HTMLIFrameElement, adVideo: HTMLVideoElement, callbacks: SimidCallbacks, creativeInfo?: SimidCreativeInfo | undefined); private nextMsgId; /** * Returns the target origin for postMessage calls to the creative iframe. * Prefer the origin captured from the first incoming message (event.origin), * which reflects where the iframe actually landed after any redirects. * Falls back to deriving from iframe.src until the first message arrives. */ private getTargetOrigin; /** * Post a payload to the creative's iframe using the detected outgoing format. * - 'plain': postMessage(payload, origin) * - 'json-string': postMessage(JSON.stringify(payload), origin) */ private postMsg; /** * Send a player→creative message that expects a resolve/reject response. * Returns a promise that resolves/rejects when the creative responds. */ private send; /** * Send a resolve response to the creative for a message it sent us. * Per spec: type="resolve", args={ messageId: , value: } */ private sendResolve; /** * Send a reject response to the creative for a message it sent us. */ private sendReject; /** * Parse a raw postMessage payload into a SimidMessage. * Handles both plain objects and JSON-encoded strings. * Auto-detects the outgoing format from the first valid message received. */ private parseMessageData; private handleMessage; /** * SIMID 1.2: creative sends createSession first. * Player responds with resolve, then immediately sends init. */ private onCreateSession; /** * Creative signals it is ready for startCreative. * If no createSession was received (older creatives), init is sent here as a fallback. */ private onCreativeReady; private buildEnvironmentData; private buildCreativeData; /** Current media state snapshot, used to respond to SIMID:Creative:getMediaState. */ private getMediaState; /** Manually send SIMID:Player:init (e.g. when not using the automatic handshake). */ init(creativeData: Record, environmentData: Record): Promise; /** Manually send SIMID:Player:startCreative. */ start(): Promise; progress(currentTime: number, duration: number): void; pause(): void; resume(): void; stop(): Promise; skip(): void; volumeChange(volume: number, muted: boolean): void; adDurationChange(duration: number): void; resize(width: number, height: number): Promise; fatal(errorCode: number, reason: string): void; /** * Bridge ad video DOM events to SIMID:Media:* postMessages and * document visibility changes to SIMID:Player:appBackgrounded/Foregrounded. * Called once from the constructor; listeners are cleaned up in destroy(). */ private bindMediaEvents; destroy(): void; } //# sourceMappingURL=simid.d.ts.map