@trillboards/ads-sdk 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +158 -0
- package/dist/index.d.mts +602 -0
- package/dist/index.d.ts +602 -0
- package/dist/index.js +1752 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1739 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react-native.d.mts +154 -0
- package/dist/react-native.d.ts +154 -0
- package/dist/react-native.js +193 -0
- package/dist/react-native.js.map +1 -0
- package/dist/react-native.mjs +190 -0
- package/dist/react-native.mjs.map +1 -0
- package/dist/react.d.mts +239 -0
- package/dist/react.d.ts +239 -0
- package/dist/react.js +1891 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +1885 -0
- package/dist/react.mjs.map +1 -0
- package/dist/server.d.mts +238 -0
- package/dist/server.d.ts +238 -0
- package/dist/server.js +209 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +200 -0
- package/dist/server.mjs.map +1 -0
- package/dist/trillboards-lite.global.js +2 -0
- package/dist/trillboards-lite.global.js.map +1 -0
- package/package.json +109 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
interface TrillboardsConfig {
|
|
2
|
+
deviceId: string;
|
|
3
|
+
apiBase?: string;
|
|
4
|
+
cdnBase?: string;
|
|
5
|
+
waterfall?: WaterfallMode;
|
|
6
|
+
autoStart?: boolean;
|
|
7
|
+
refreshInterval?: number;
|
|
8
|
+
heartbeatInterval?: number;
|
|
9
|
+
defaultImageDuration?: number;
|
|
10
|
+
defaultAdInterval?: number;
|
|
11
|
+
programmaticTimeout?: number;
|
|
12
|
+
programmaticMinInterval?: number;
|
|
13
|
+
programmaticRetry?: number;
|
|
14
|
+
programmaticBackoffMax?: number;
|
|
15
|
+
cacheSize?: number;
|
|
16
|
+
}
|
|
17
|
+
type WaterfallMode = 'programmatic_only' | 'programmatic_then_direct' | 'direct_only';
|
|
18
|
+
interface AdItem {
|
|
19
|
+
id: string;
|
|
20
|
+
allocation_id?: string;
|
|
21
|
+
type: 'image' | 'video';
|
|
22
|
+
media_url: string;
|
|
23
|
+
/** Duration in seconds */
|
|
24
|
+
duration: number;
|
|
25
|
+
title?: string;
|
|
26
|
+
impression_id: string;
|
|
27
|
+
tracking?: {
|
|
28
|
+
impression_url: string;
|
|
29
|
+
complete_url: string;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
interface ProgrammaticSettings {
|
|
33
|
+
vast_tag_url: string | null;
|
|
34
|
+
variant_name: string | null;
|
|
35
|
+
min_interval_seconds?: number;
|
|
36
|
+
sources?: VastSource[];
|
|
37
|
+
auction_winner?: AuctionWinner | null;
|
|
38
|
+
}
|
|
39
|
+
interface VastSource {
|
|
40
|
+
name: string;
|
|
41
|
+
vast_url: string;
|
|
42
|
+
priority: number;
|
|
43
|
+
timeout_ms: number;
|
|
44
|
+
enabled: boolean;
|
|
45
|
+
}
|
|
46
|
+
interface AuctionWinner {
|
|
47
|
+
source: string;
|
|
48
|
+
bid_price_cpm?: number;
|
|
49
|
+
vast_url: string;
|
|
50
|
+
}
|
|
51
|
+
interface TrillboardsState {
|
|
52
|
+
initialized: boolean;
|
|
53
|
+
isPlaying: boolean;
|
|
54
|
+
isPaused: boolean;
|
|
55
|
+
isOffline: boolean;
|
|
56
|
+
currentAd: AdItem | null;
|
|
57
|
+
adCount: number;
|
|
58
|
+
programmaticPlaying: boolean;
|
|
59
|
+
prefetchedReady: boolean;
|
|
60
|
+
waterfallMode: WaterfallMode;
|
|
61
|
+
screenId: string | null;
|
|
62
|
+
deviceId: string | null;
|
|
63
|
+
}
|
|
64
|
+
interface ScreenDimensions {
|
|
65
|
+
width: number;
|
|
66
|
+
height: number;
|
|
67
|
+
orientation?: 'portrait' | 'landscape';
|
|
68
|
+
}
|
|
69
|
+
interface PlayerTruth {
|
|
70
|
+
slotWidth: number | null;
|
|
71
|
+
slotHeight: number | null;
|
|
72
|
+
orientation: 'portrait' | 'landscape' | null;
|
|
73
|
+
muted: boolean;
|
|
74
|
+
autoplayAllowed: boolean;
|
|
75
|
+
userAgent: string | null;
|
|
76
|
+
}
|
|
77
|
+
interface ImpressionData {
|
|
78
|
+
adId: string;
|
|
79
|
+
impressionId: string;
|
|
80
|
+
deviceId: string;
|
|
81
|
+
screenId?: string;
|
|
82
|
+
allocationId?: string;
|
|
83
|
+
duration: number;
|
|
84
|
+
completed: boolean;
|
|
85
|
+
timestamp: string;
|
|
86
|
+
type?: 'direct' | 'programmatic';
|
|
87
|
+
}
|
|
88
|
+
interface BridgeConfig {
|
|
89
|
+
send: (event: string, data: unknown) => void;
|
|
90
|
+
receive?: (callback: (command: unknown) => void) => void;
|
|
91
|
+
events?: string[];
|
|
92
|
+
name?: string;
|
|
93
|
+
}
|
|
94
|
+
type BridgeType = 'android' | 'android-alt' | 'ios' | 'react-native' | 'flutter' | 'ctv' | 'electron' | 'tauri' | 'postMessage' | 'custom';
|
|
95
|
+
interface BridgePayload {
|
|
96
|
+
type: 'trillboards';
|
|
97
|
+
version: string;
|
|
98
|
+
event: string;
|
|
99
|
+
data: unknown;
|
|
100
|
+
timestamp: number;
|
|
101
|
+
deviceId: string | null;
|
|
102
|
+
screenId: string | null;
|
|
103
|
+
sessionId: string;
|
|
104
|
+
}
|
|
105
|
+
interface TelemetrySnapshot {
|
|
106
|
+
fill_rate: number;
|
|
107
|
+
no_fill_rate: number;
|
|
108
|
+
timeout_rate: number;
|
|
109
|
+
error_rate: number;
|
|
110
|
+
}
|
|
111
|
+
interface CircuitBreakerState {
|
|
112
|
+
consecutiveFailures: number;
|
|
113
|
+
openUntil: number;
|
|
114
|
+
}
|
|
115
|
+
interface FetchAdsResult {
|
|
116
|
+
ads: AdItem[];
|
|
117
|
+
settings: Record<string, unknown>;
|
|
118
|
+
programmatic: ProgrammaticSettings | null;
|
|
119
|
+
screenId: string | null;
|
|
120
|
+
screenOrientation: string | null;
|
|
121
|
+
screenDimensions: ScreenDimensions | null;
|
|
122
|
+
etag: string | null;
|
|
123
|
+
notModified: boolean;
|
|
124
|
+
}
|
|
125
|
+
interface EventMap {
|
|
126
|
+
initialized: {
|
|
127
|
+
deviceId: string;
|
|
128
|
+
};
|
|
129
|
+
ads_refreshed: {
|
|
130
|
+
count: number;
|
|
131
|
+
};
|
|
132
|
+
ads_loaded_from_cache: {
|
|
133
|
+
count: number;
|
|
134
|
+
};
|
|
135
|
+
ad_started: {
|
|
136
|
+
id: string;
|
|
137
|
+
type: string;
|
|
138
|
+
index: number;
|
|
139
|
+
};
|
|
140
|
+
ad_ended: {
|
|
141
|
+
id: string;
|
|
142
|
+
type: string;
|
|
143
|
+
duration: number;
|
|
144
|
+
};
|
|
145
|
+
ad_ready: {
|
|
146
|
+
type: 'programmatic' | 'direct';
|
|
147
|
+
source?: string;
|
|
148
|
+
};
|
|
149
|
+
ad_error: {
|
|
150
|
+
error: string;
|
|
151
|
+
source?: string;
|
|
152
|
+
};
|
|
153
|
+
programmatic_started: {
|
|
154
|
+
source: string;
|
|
155
|
+
variant: string | null;
|
|
156
|
+
};
|
|
157
|
+
programmatic_ended: {
|
|
158
|
+
source: string;
|
|
159
|
+
variant: string | null;
|
|
160
|
+
duration: number;
|
|
161
|
+
};
|
|
162
|
+
programmatic_error: {
|
|
163
|
+
error: string;
|
|
164
|
+
code?: number;
|
|
165
|
+
};
|
|
166
|
+
programmatic_no_fill: {
|
|
167
|
+
source: string;
|
|
168
|
+
};
|
|
169
|
+
programmatic_timeout: {
|
|
170
|
+
source: string;
|
|
171
|
+
};
|
|
172
|
+
impression_tracked: {
|
|
173
|
+
adId: string;
|
|
174
|
+
impressionId: string;
|
|
175
|
+
};
|
|
176
|
+
state_changed: TrillboardsState;
|
|
177
|
+
bridge_event: {
|
|
178
|
+
event: string;
|
|
179
|
+
data: unknown;
|
|
180
|
+
};
|
|
181
|
+
visibility_changed: {
|
|
182
|
+
visible: boolean;
|
|
183
|
+
};
|
|
184
|
+
offline: Record<string, never>;
|
|
185
|
+
online: Record<string, never>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
declare class TrillboardsAds {
|
|
189
|
+
/** Singleton reference — `create()` destroys any previous instance. */
|
|
190
|
+
private static _instance;
|
|
191
|
+
private config;
|
|
192
|
+
private state;
|
|
193
|
+
private events;
|
|
194
|
+
private api;
|
|
195
|
+
private cache;
|
|
196
|
+
private bridge;
|
|
197
|
+
private programmaticPlayer;
|
|
198
|
+
private directPlayer;
|
|
199
|
+
/** Stored references for window event listeners (cleanup in destroy). */
|
|
200
|
+
private onlineHandler;
|
|
201
|
+
private offlineHandler;
|
|
202
|
+
private visibilityHandler;
|
|
203
|
+
private constructor();
|
|
204
|
+
/**
|
|
205
|
+
* Create and initialize a new TrillboardsAds instance.
|
|
206
|
+
* If a previous instance exists, it is destroyed first
|
|
207
|
+
* (singleton guard).
|
|
208
|
+
*/
|
|
209
|
+
static create(config: TrillboardsConfig): Promise<TrillboardsAds>;
|
|
210
|
+
/**
|
|
211
|
+
* Initialize the SDK (private — called by `create()` only).
|
|
212
|
+
*/
|
|
213
|
+
private init;
|
|
214
|
+
/**
|
|
215
|
+
* Destroy the SDK instance and clean up all resources.
|
|
216
|
+
*/
|
|
217
|
+
destroy(): void;
|
|
218
|
+
/**
|
|
219
|
+
* Show the ad container and start playback.
|
|
220
|
+
*/
|
|
221
|
+
show(): void;
|
|
222
|
+
/**
|
|
223
|
+
* Hide the ad container and pause playback.
|
|
224
|
+
*/
|
|
225
|
+
hide(): void;
|
|
226
|
+
/**
|
|
227
|
+
* Skip the current ad.
|
|
228
|
+
*/
|
|
229
|
+
skipAd(): void;
|
|
230
|
+
/**
|
|
231
|
+
* Force refresh — re-fetches VAST URLs from server with null etag.
|
|
232
|
+
*/
|
|
233
|
+
refresh(): Promise<void>;
|
|
234
|
+
/**
|
|
235
|
+
* Prefetch the next ad for instant playback.
|
|
236
|
+
*/
|
|
237
|
+
prefetchNextAd(): Promise<void>;
|
|
238
|
+
/**
|
|
239
|
+
* Get current public state.
|
|
240
|
+
*/
|
|
241
|
+
getState(): TrillboardsState;
|
|
242
|
+
/**
|
|
243
|
+
* Get current ad list.
|
|
244
|
+
*/
|
|
245
|
+
getAds(): AdItem[];
|
|
246
|
+
/**
|
|
247
|
+
* Subscribe to an event.
|
|
248
|
+
*/
|
|
249
|
+
on<K extends keyof EventMap>(event: K, handler: (data: EventMap[K]) => void): void;
|
|
250
|
+
/**
|
|
251
|
+
* Unsubscribe from an event.
|
|
252
|
+
*/
|
|
253
|
+
off<K extends keyof EventMap>(event: K, handler: (data: EventMap[K]) => void): void;
|
|
254
|
+
/**
|
|
255
|
+
* Register a custom native bridge.
|
|
256
|
+
*/
|
|
257
|
+
registerBridge(config: BridgeConfig): boolean;
|
|
258
|
+
private createContainer;
|
|
259
|
+
private refreshAds;
|
|
260
|
+
private startRefreshTimer;
|
|
261
|
+
private startHeartbeatTimer;
|
|
262
|
+
private playNextAd;
|
|
263
|
+
private playProgrammatic;
|
|
264
|
+
private playDirect;
|
|
265
|
+
private scheduleNextDirect;
|
|
266
|
+
private scheduleProgrammaticRetry;
|
|
267
|
+
private resetProgrammaticBackoff;
|
|
268
|
+
private emitStateChanged;
|
|
269
|
+
private handleBridgeCommand;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
type Handler<T> = (data: T) => void;
|
|
273
|
+
/**
|
|
274
|
+
* A lightweight, fully-typed event emitter.
|
|
275
|
+
*
|
|
276
|
+
* Usage:
|
|
277
|
+
* ```ts
|
|
278
|
+
* const emitter = new EventEmitter();
|
|
279
|
+
* emitter.on('ad_started', ({ id, type, index }) => { ... });
|
|
280
|
+
* emitter.emit('ad_started', { id: '123', type: 'video', index: 0 });
|
|
281
|
+
* ```
|
|
282
|
+
*
|
|
283
|
+
* Handler errors are caught and logged so a single bad listener
|
|
284
|
+
* can never crash the SDK or block other listeners.
|
|
285
|
+
*/
|
|
286
|
+
declare class EventEmitter {
|
|
287
|
+
private handlers;
|
|
288
|
+
/**
|
|
289
|
+
* Register a handler for the given event.
|
|
290
|
+
* The same handler reference can only be registered once per
|
|
291
|
+
* event (Set semantics).
|
|
292
|
+
*/
|
|
293
|
+
on<K extends keyof EventMap>(event: K, handler: Handler<EventMap[K]>): void;
|
|
294
|
+
/**
|
|
295
|
+
* Remove a previously registered handler.
|
|
296
|
+
* No-op if the handler was never registered.
|
|
297
|
+
*/
|
|
298
|
+
off<K extends keyof EventMap>(event: K, handler: Handler<EventMap[K]>): void;
|
|
299
|
+
/**
|
|
300
|
+
* Emit an event, invoking every registered handler with the
|
|
301
|
+
* supplied data payload. Handlers are called synchronously in
|
|
302
|
+
* registration order. Exceptions inside handlers are caught
|
|
303
|
+
* and logged to the console so they never propagate.
|
|
304
|
+
*/
|
|
305
|
+
emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void;
|
|
306
|
+
/**
|
|
307
|
+
* Register a one-shot handler that automatically removes itself
|
|
308
|
+
* after the first invocation.
|
|
309
|
+
*/
|
|
310
|
+
once<K extends keyof EventMap>(event: K, handler: Handler<EventMap[K]>): void;
|
|
311
|
+
/**
|
|
312
|
+
* Remove all handlers for all events.
|
|
313
|
+
* Typically called during SDK teardown / destroy.
|
|
314
|
+
*/
|
|
315
|
+
removeAllListeners(): void;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/** Single source of truth for the SDK version string. */
|
|
319
|
+
declare const SDK_VERSION = "2.0.0";
|
|
320
|
+
/**
|
|
321
|
+
* Compile-time constants that mirror the original IIFE CONFIG
|
|
322
|
+
* object. Every value here acts as a sensible production default
|
|
323
|
+
* that can be overridden per-device via TrillboardsConfig.
|
|
324
|
+
*/
|
|
325
|
+
declare const DEFAULT_CONFIG: {
|
|
326
|
+
readonly API_BASE: "https://api.trillboards.com/v1/partner";
|
|
327
|
+
readonly CDN_BASE: "https://cdn.trillboards.com";
|
|
328
|
+
readonly CACHE_NAME: "trillboards-lite-ads";
|
|
329
|
+
readonly CACHE_SIZE: 10;
|
|
330
|
+
readonly REFRESH_INTERVAL: number;
|
|
331
|
+
readonly HEARTBEAT_INTERVAL: number;
|
|
332
|
+
readonly DEFAULT_IMAGE_DURATION: 8000;
|
|
333
|
+
readonly DEFAULT_AD_INTERVAL: 60000;
|
|
334
|
+
readonly PROGRAMMATIC_TIMEOUT_MS: 12000;
|
|
335
|
+
readonly PROGRAMMATIC_MIN_INTERVAL_MS: 5000;
|
|
336
|
+
readonly PROGRAMMATIC_RETRY_MS: 5000;
|
|
337
|
+
readonly PROGRAMMATIC_BACKOFF_MAX_MS: number;
|
|
338
|
+
readonly VERSION: "2.0.0";
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* Merge a caller-supplied TrillboardsConfig with the defaults,
|
|
342
|
+
* returning a fully-resolved configuration object with no
|
|
343
|
+
* optional gaps.
|
|
344
|
+
*
|
|
345
|
+
* Throws if `deviceId` is empty or whitespace-only.
|
|
346
|
+
* Numeric fields are clamped to sensible minimums.
|
|
347
|
+
*/
|
|
348
|
+
declare function resolveConfig(userConfig: TrillboardsConfig): {
|
|
349
|
+
readonly deviceId: string;
|
|
350
|
+
readonly apiBase: string;
|
|
351
|
+
readonly cdnBase: string;
|
|
352
|
+
readonly waterfall: WaterfallMode;
|
|
353
|
+
readonly autoStart: boolean;
|
|
354
|
+
readonly refreshInterval: number;
|
|
355
|
+
readonly heartbeatInterval: number;
|
|
356
|
+
readonly defaultImageDuration: number;
|
|
357
|
+
readonly defaultAdInterval: number;
|
|
358
|
+
readonly programmaticTimeout: number;
|
|
359
|
+
readonly programmaticMinInterval: number;
|
|
360
|
+
readonly programmaticRetry: number;
|
|
361
|
+
readonly programmaticBackoffMax: number;
|
|
362
|
+
readonly cacheSize: number;
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* The full internal state held by the SDK engine.
|
|
367
|
+
* This is NOT exposed to consumers — they receive the
|
|
368
|
+
* trimmed-down `TrillboardsState` via `getPublicState()`.
|
|
369
|
+
*/
|
|
370
|
+
interface InternalState {
|
|
371
|
+
deviceId: string | null;
|
|
372
|
+
partnerId: string | null;
|
|
373
|
+
screenId: string | null;
|
|
374
|
+
ads: AdItem[];
|
|
375
|
+
currentAdIndex: number;
|
|
376
|
+
isPlaying: boolean;
|
|
377
|
+
isPaused: boolean;
|
|
378
|
+
isOffline: boolean;
|
|
379
|
+
settings: Record<string, unknown>;
|
|
380
|
+
programmatic: ProgrammaticSettings | null;
|
|
381
|
+
programmaticPlaying: boolean;
|
|
382
|
+
prefetchedReady: boolean;
|
|
383
|
+
waterfallMode: WaterfallMode;
|
|
384
|
+
autoStart: boolean;
|
|
385
|
+
container: HTMLElement | null;
|
|
386
|
+
adTimer: ReturnType<typeof setTimeout> | null;
|
|
387
|
+
refreshTimer: ReturnType<typeof setInterval> | null;
|
|
388
|
+
heartbeatTimer: ReturnType<typeof setInterval> | null;
|
|
389
|
+
programmaticRetryTimer: ReturnType<typeof setTimeout> | null;
|
|
390
|
+
programmaticRetryActive: boolean;
|
|
391
|
+
programmaticRetryCount: number;
|
|
392
|
+
programmaticLastError: string | null;
|
|
393
|
+
initialized: boolean;
|
|
394
|
+
screenOrientation: string | null;
|
|
395
|
+
screenDimensions: ScreenDimensions | null;
|
|
396
|
+
etag: string | null;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Default public state used by React components and the IIFE
|
|
400
|
+
* entry point before the SDK is initialized.
|
|
401
|
+
*/
|
|
402
|
+
declare const DEFAULT_PUBLIC_STATE: TrillboardsState;
|
|
403
|
+
/**
|
|
404
|
+
* Create a fresh internal state object with safe defaults.
|
|
405
|
+
* Called once during SDK initialisation.
|
|
406
|
+
*/
|
|
407
|
+
declare function createInitialState(): InternalState;
|
|
408
|
+
/**
|
|
409
|
+
* Project the internal state into a safe, read-only snapshot
|
|
410
|
+
* that can be handed to consumers and event listeners.
|
|
411
|
+
*/
|
|
412
|
+
declare function getPublicState(internal: InternalState): TrillboardsState;
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Per-source failure tracking to avoid hammering broken demand
|
|
416
|
+
* sources. Each source independently transitions through three
|
|
417
|
+
* states:
|
|
418
|
+
*
|
|
419
|
+
* CLOSED → failures < maxFailures → requests pass through
|
|
420
|
+
* OPEN → failures >= maxFailures → requests blocked until openDurationMs elapses
|
|
421
|
+
* HALF-OPEN → openDurationMs elapsed → one request allowed; success resets, failure re-opens
|
|
422
|
+
*/
|
|
423
|
+
declare class CircuitBreaker {
|
|
424
|
+
private sources;
|
|
425
|
+
readonly maxFailures: number;
|
|
426
|
+
readonly openDurationMs: number;
|
|
427
|
+
constructor(maxFailures?: number, openDurationMs?: number);
|
|
428
|
+
/**
|
|
429
|
+
* Record a successful request for a source, resetting its
|
|
430
|
+
* failure counter and clearing any open-circuit timer.
|
|
431
|
+
*/
|
|
432
|
+
recordSuccess(sourceName: string): void;
|
|
433
|
+
/**
|
|
434
|
+
* Record a failed request for a source. When consecutive
|
|
435
|
+
* failures reach `maxFailures`, the circuit opens for
|
|
436
|
+
* `openDurationMs` milliseconds.
|
|
437
|
+
*/
|
|
438
|
+
recordFailure(sourceName: string): void;
|
|
439
|
+
/**
|
|
440
|
+
* Check whether a source is available for requests.
|
|
441
|
+
*
|
|
442
|
+
* Returns `true` when:
|
|
443
|
+
* - The source has never been tracked (unknown = available)
|
|
444
|
+
* - Consecutive failures are below the threshold (CLOSED)
|
|
445
|
+
* - The open-circuit timer has elapsed (HALF-OPEN — allow a probe)
|
|
446
|
+
*/
|
|
447
|
+
isAvailable(sourceName: string): boolean;
|
|
448
|
+
/**
|
|
449
|
+
* Return the raw circuit breaker state for a source.
|
|
450
|
+
* Returns a zeroed-out state for unknown sources.
|
|
451
|
+
*/
|
|
452
|
+
getState(sourceName: string): CircuitBreakerState;
|
|
453
|
+
/**
|
|
454
|
+
* Clear all tracked source state.
|
|
455
|
+
*/
|
|
456
|
+
reset(): void;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Lightweight counters for ad-request outcomes.
|
|
461
|
+
*
|
|
462
|
+
* Every call to `play()` on the programmatic player should call
|
|
463
|
+
* `recordRequest()`. Depending on the outcome, one of
|
|
464
|
+
* `recordFill()`, `recordNoFill()`, `recordTimeout()`, or
|
|
465
|
+
* `recordError()` is then called. The snapshot exposes rates
|
|
466
|
+
* (0-1, rounded to 4 decimal places) that can be sent to the
|
|
467
|
+
* server for monitoring.
|
|
468
|
+
*/
|
|
469
|
+
declare class Telemetry {
|
|
470
|
+
private totalRequests;
|
|
471
|
+
private fills;
|
|
472
|
+
private noFills;
|
|
473
|
+
private timeouts;
|
|
474
|
+
private errors;
|
|
475
|
+
/** Count a new ad request. */
|
|
476
|
+
recordRequest(): void;
|
|
477
|
+
/** Count a successful fill (ad loaded and ready to play). */
|
|
478
|
+
recordFill(): void;
|
|
479
|
+
/** Count a request that returned no ad (no fill). */
|
|
480
|
+
recordNoFill(): void;
|
|
481
|
+
/** Count a request that timed out before a response arrived. */
|
|
482
|
+
recordTimeout(): void;
|
|
483
|
+
/** Count a request that failed with an error (not a timeout). */
|
|
484
|
+
recordError(): void;
|
|
485
|
+
/** Ratio of fills to total requests (0-1). */
|
|
486
|
+
getFillRate(): number;
|
|
487
|
+
/** Ratio of no-fills to total requests (0-1). */
|
|
488
|
+
getNoFillRate(): number;
|
|
489
|
+
/** Ratio of timeouts to total requests (0-1). */
|
|
490
|
+
getTimeoutRate(): number;
|
|
491
|
+
/** Ratio of errors to total requests (0-1). */
|
|
492
|
+
getErrorRate(): number;
|
|
493
|
+
/**
|
|
494
|
+
* Return a snapshot object suitable for serialization.
|
|
495
|
+
* Rates are rounded to four decimal places.
|
|
496
|
+
*/
|
|
497
|
+
getSnapshot(): TelemetrySnapshot;
|
|
498
|
+
/** Reset all counters to zero. */
|
|
499
|
+
reset(): void;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
interface WaterfallResult {
|
|
503
|
+
source: VastSource;
|
|
504
|
+
vastUrl: string;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Manages iterating through waterfall demand sources in priority
|
|
508
|
+
* order, skipping circuit-broken sources. Lower priority numbers
|
|
509
|
+
* are tried first. Equal-priority sources are randomized to
|
|
510
|
+
* distribute load evenly.
|
|
511
|
+
*/
|
|
512
|
+
declare class WaterfallEngine {
|
|
513
|
+
private circuitBreaker;
|
|
514
|
+
constructor(circuitBreaker: CircuitBreaker);
|
|
515
|
+
/**
|
|
516
|
+
* Get the next available VAST source from the waterfall.
|
|
517
|
+
* Sources are sorted by priority (lower = higher priority),
|
|
518
|
+
* with a random tiebreaker for equal priorities.
|
|
519
|
+
* Circuit-broken sources are skipped.
|
|
520
|
+
*
|
|
521
|
+
* If all sources are circuit-broken, returns `null` to let
|
|
522
|
+
* the caller handle retry scheduling rather than bypassing
|
|
523
|
+
* the circuit breaker.
|
|
524
|
+
*/
|
|
525
|
+
getNextSource(sources: VastSource[]): WaterfallResult | null;
|
|
526
|
+
/**
|
|
527
|
+
* Get all available sources in priority order (for parallel bidding).
|
|
528
|
+
* Only returns sources that are not circuit-broken.
|
|
529
|
+
* Equal-priority sources are randomized for load distribution.
|
|
530
|
+
*/
|
|
531
|
+
getAvailableSources(sources: VastSource[]): WaterfallResult[];
|
|
532
|
+
/** Record a successful ad fill for a source. */
|
|
533
|
+
recordSuccess(sourceName: string): void;
|
|
534
|
+
/** Record a failed request for a source. */
|
|
535
|
+
recordFailure(sourceName: string): void;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Low-level HTTP client for the Trillboards Partner API.
|
|
540
|
+
*
|
|
541
|
+
* Each method maps 1-to-1 to an endpoint:
|
|
542
|
+
* - `fetchAds` — `GET /device/:id/ads`
|
|
543
|
+
* - `reportImpression` — `GET /impression`
|
|
544
|
+
* - `sendHeartbeat` — `POST /device/:id/heartbeat`
|
|
545
|
+
* - `reportProgrammaticEvent` — `POST /programmatic-event`
|
|
546
|
+
*/
|
|
547
|
+
declare class ApiClient {
|
|
548
|
+
private apiBase;
|
|
549
|
+
private container;
|
|
550
|
+
constructor(apiBase?: string);
|
|
551
|
+
/** Bind an optional container element for slot-size measurement. */
|
|
552
|
+
setContainer(container: HTMLElement | null): void;
|
|
553
|
+
/**
|
|
554
|
+
* Fetch the current ad roster for a device.
|
|
555
|
+
*
|
|
556
|
+
* Supports conditional requests via `ETag` / `If-None-Match` —
|
|
557
|
+
* when the server returns 304 the caller receives the previous
|
|
558
|
+
* ad list untouched (indicated by `notModified: true`).
|
|
559
|
+
*
|
|
560
|
+
* The request is aborted after 10 seconds.
|
|
561
|
+
*/
|
|
562
|
+
fetchAds(deviceId: string, etag?: string | null): Promise<FetchAdsResult>;
|
|
563
|
+
/**
|
|
564
|
+
* Fire an impression pixel.
|
|
565
|
+
*
|
|
566
|
+
* Uses a GET request with query-string parameters so the call
|
|
567
|
+
* survives `navigator.sendBeacon`-like fallback patterns and
|
|
568
|
+
* can be retried transparently on network failure.
|
|
569
|
+
*
|
|
570
|
+
* Returns `true` if the server acknowledged the impression.
|
|
571
|
+
*/
|
|
572
|
+
reportImpression(impression: {
|
|
573
|
+
adid: string;
|
|
574
|
+
impid: string;
|
|
575
|
+
did: string;
|
|
576
|
+
aid: string;
|
|
577
|
+
duration: number;
|
|
578
|
+
completed: boolean;
|
|
579
|
+
}): Promise<boolean>;
|
|
580
|
+
/**
|
|
581
|
+
* Ping the heartbeat endpoint to signal this device is alive.
|
|
582
|
+
* Returns `true` on 2xx, `false` on any error.
|
|
583
|
+
*/
|
|
584
|
+
sendHeartbeat(deviceId: string, screenId: string | null): Promise<boolean>;
|
|
585
|
+
/**
|
|
586
|
+
* Report a programmatic lifecycle event (VAST fill, timeout,
|
|
587
|
+
* error, etc.) to the analytics backend.
|
|
588
|
+
*/
|
|
589
|
+
reportProgrammaticEvent(event: {
|
|
590
|
+
screenId: string;
|
|
591
|
+
deviceId: string;
|
|
592
|
+
eventType: string;
|
|
593
|
+
vastSource?: string;
|
|
594
|
+
variantName?: string;
|
|
595
|
+
errorCode?: number;
|
|
596
|
+
errorMessage?: string;
|
|
597
|
+
duration?: number;
|
|
598
|
+
telemetry?: Record<string, number>;
|
|
599
|
+
}): Promise<boolean>;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
export { type AdItem, ApiClient, type AuctionWinner, type BridgeConfig, type BridgePayload, type BridgeType, CircuitBreaker, type CircuitBreakerState, DEFAULT_CONFIG, DEFAULT_PUBLIC_STATE, EventEmitter, type EventMap, type FetchAdsResult, type ImpressionData, type PlayerTruth, type ProgrammaticSettings, SDK_VERSION, type ScreenDimensions, Telemetry, type TelemetrySnapshot, TrillboardsAds, type TrillboardsConfig, type TrillboardsState, type VastSource, WaterfallEngine, type WaterfallMode, createInitialState, getPublicState, resolveConfig };
|