@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/server.mjs
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
// src/server/fetchWithAuth.ts
|
|
2
|
+
function createAuthenticatedFetch(apiKey, apiBase) {
|
|
3
|
+
const base = apiBase.replace(/\/+$/, "");
|
|
4
|
+
return async (path, options) => {
|
|
5
|
+
const response = await globalThis.fetch(`${base}${path}`, {
|
|
6
|
+
...options,
|
|
7
|
+
signal: options?.signal ?? AbortSignal.timeout(1e4),
|
|
8
|
+
headers: {
|
|
9
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
10
|
+
"Content-Type": "application/json",
|
|
11
|
+
...options?.headers ?? {}
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
if (!response.ok) {
|
|
15
|
+
throw new Error(`API error: HTTP ${response.status}`);
|
|
16
|
+
}
|
|
17
|
+
return response.json();
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/server/VastTagBuilder.ts
|
|
22
|
+
var VastTagBuilder = class {
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.authFetch = createAuthenticatedFetch(config.apiKey, config.apiBase ?? "https://api.trillboards.com/v1");
|
|
25
|
+
}
|
|
26
|
+
async buildTag(options) {
|
|
27
|
+
const params = new URLSearchParams();
|
|
28
|
+
if (options.width) params.set("slot_w", String(options.width));
|
|
29
|
+
if (options.height) params.set("slot_h", String(options.height));
|
|
30
|
+
if (options.orientation) params.set("orientation", options.orientation);
|
|
31
|
+
if (options.muted !== void 0) params.set("muted", options.muted ? "1" : "0");
|
|
32
|
+
if (options.autoplay !== void 0) params.set("autoplay", options.autoplay ? "1" : "0");
|
|
33
|
+
if (options.userAgent) params.set("ua", options.userAgent);
|
|
34
|
+
const query = params.toString();
|
|
35
|
+
const path = `/partner/device/${options.deviceId}/ads${query ? `?${query}` : ""}`;
|
|
36
|
+
const data = await this.authFetch(path);
|
|
37
|
+
const hbs = data.data?.header_bidding_settings;
|
|
38
|
+
return {
|
|
39
|
+
url: hbs?.vast_tag_url ?? "",
|
|
40
|
+
sources: (hbs?.vast_waterfall?.sources ?? []).map((s) => ({
|
|
41
|
+
name: s.name,
|
|
42
|
+
vast_url: s.vast_url,
|
|
43
|
+
priority: s.priority,
|
|
44
|
+
timeout_ms: s.timeout_ms
|
|
45
|
+
})),
|
|
46
|
+
auctionWinner: hbs?.auction_winner ?? null
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// src/server/TrackingBatch.ts
|
|
52
|
+
var TrackingBatch = class {
|
|
53
|
+
constructor(config) {
|
|
54
|
+
this.apiBase = (config.apiBase ?? "https://api.trillboards.com/v1").replace(/\/+$/, "");
|
|
55
|
+
this.authFetch = createAuthenticatedFetch(config.apiKey, config.apiBase ?? "https://api.trillboards.com/v1");
|
|
56
|
+
}
|
|
57
|
+
async report(impressions) {
|
|
58
|
+
const data = await this.authFetch("/partner/tracking/batch", {
|
|
59
|
+
method: "POST",
|
|
60
|
+
body: JSON.stringify({ impressions })
|
|
61
|
+
});
|
|
62
|
+
return {
|
|
63
|
+
success: data.success ?? true,
|
|
64
|
+
tracked: data.data?.tracked ?? impressions.length,
|
|
65
|
+
proofs: (data.data?.proofs ?? []).map((p) => ({
|
|
66
|
+
impressionId: p.impression_id,
|
|
67
|
+
proof: p.proof,
|
|
68
|
+
publicKeyUrl: p.public_key_url ?? `${this.apiBase}/.well-known/public-key`
|
|
69
|
+
}))
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// src/server/AudienceClient.ts
|
|
75
|
+
var AudienceClient = class {
|
|
76
|
+
constructor(apiKey, apiBase) {
|
|
77
|
+
this.authFetch = createAuthenticatedFetch(apiKey, apiBase);
|
|
78
|
+
}
|
|
79
|
+
async getLive(screenId) {
|
|
80
|
+
const data = await this.authFetch(`/partner/audience/live/${screenId}`);
|
|
81
|
+
return data.data ?? data;
|
|
82
|
+
}
|
|
83
|
+
async predict(screenId, options) {
|
|
84
|
+
const params = new URLSearchParams({
|
|
85
|
+
hour: String(options.hour),
|
|
86
|
+
day_of_week: String(options.dayOfWeek)
|
|
87
|
+
});
|
|
88
|
+
const data = await this.authFetch(`/partner/audience/predict/${screenId}?${params}`);
|
|
89
|
+
return data.data ?? data;
|
|
90
|
+
}
|
|
91
|
+
async findLookalikes(screenId, options) {
|
|
92
|
+
const params = new URLSearchParams();
|
|
93
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
94
|
+
if (options?.minSimilarity) params.set("min_similarity", String(options.minSimilarity));
|
|
95
|
+
const query = params.toString();
|
|
96
|
+
const data = await this.authFetch(`/partner/audience/lookalikes/${screenId}${query ? `?${query}` : ""}`);
|
|
97
|
+
return data.data ?? [];
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// src/server/AnalyticsClient.ts
|
|
102
|
+
var AnalyticsClient = class {
|
|
103
|
+
constructor(apiKey, apiBase) {
|
|
104
|
+
this.authFetch = createAuthenticatedFetch(apiKey, apiBase);
|
|
105
|
+
}
|
|
106
|
+
async getScreenDaily(screenId, options) {
|
|
107
|
+
const params = new URLSearchParams({
|
|
108
|
+
start_date: options.startDate,
|
|
109
|
+
end_date: options.endDate
|
|
110
|
+
});
|
|
111
|
+
const data = await this.authFetch(`/partner/screens/${screenId}/analytics?${params}`);
|
|
112
|
+
return data.data ?? [];
|
|
113
|
+
}
|
|
114
|
+
async getEarnings(options) {
|
|
115
|
+
const params = new URLSearchParams();
|
|
116
|
+
if (options?.screenId) params.set("screen_id", options.screenId);
|
|
117
|
+
if (options?.startDate) params.set("start_date", options.startDate);
|
|
118
|
+
if (options?.endDate) params.set("end_date", options.endDate);
|
|
119
|
+
const query = params.toString();
|
|
120
|
+
const data = await this.authFetch(`/partner/earnings${query ? `?${query}` : ""}`);
|
|
121
|
+
return data.data ?? [];
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// src/server/AuctionClient.ts
|
|
126
|
+
var AuctionClient = class {
|
|
127
|
+
constructor(apiKey, apiBase) {
|
|
128
|
+
this.authFetch = createAuthenticatedFetch(apiKey, apiBase);
|
|
129
|
+
}
|
|
130
|
+
async list(options) {
|
|
131
|
+
const params = new URLSearchParams();
|
|
132
|
+
if (options?.screenId) params.set("screen_id", options.screenId);
|
|
133
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
134
|
+
if (options?.offset) params.set("offset", String(options.offset));
|
|
135
|
+
const query = params.toString();
|
|
136
|
+
const data = await this.authFetch(`/partner/auctions${query ? `?${query}` : ""}`);
|
|
137
|
+
return data.data ?? [];
|
|
138
|
+
}
|
|
139
|
+
async get(auctionId) {
|
|
140
|
+
const data = await this.authFetch(`/partner/auctions/${auctionId}`);
|
|
141
|
+
return data.data ?? data;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// src/server/CreativeClient.ts
|
|
146
|
+
var CreativeClient = class {
|
|
147
|
+
constructor(apiKey, apiBase) {
|
|
148
|
+
this.authFetch = createAuthenticatedFetch(apiKey, apiBase);
|
|
149
|
+
}
|
|
150
|
+
async list(options) {
|
|
151
|
+
const params = new URLSearchParams();
|
|
152
|
+
if (options?.status) params.set("status", options.status);
|
|
153
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
154
|
+
if (options?.offset) params.set("offset", String(options.offset));
|
|
155
|
+
const query = params.toString();
|
|
156
|
+
const data = await this.authFetch(`/openrtb/v1/creative-review${query ? `?${query}` : ""}`);
|
|
157
|
+
return data.data ?? [];
|
|
158
|
+
}
|
|
159
|
+
async getStats() {
|
|
160
|
+
const data = await this.authFetch("/openrtb/v1/creative-review/stats");
|
|
161
|
+
return data.data ?? data;
|
|
162
|
+
}
|
|
163
|
+
async block(creativeId, reason) {
|
|
164
|
+
await this.authFetch(`/openrtb/v1/creative-review/${creativeId}/block`, {
|
|
165
|
+
method: "POST",
|
|
166
|
+
body: JSON.stringify({ reason })
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
async unblock(creativeId) {
|
|
170
|
+
await this.authFetch(`/openrtb/v1/creative-review/${creativeId}/unblock`, {
|
|
171
|
+
method: "POST"
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// src/server/PartnerClient.ts
|
|
177
|
+
var PartnerClient = class {
|
|
178
|
+
constructor(config) {
|
|
179
|
+
this.apiKey = config.apiKey;
|
|
180
|
+
this.apiBase = config.apiBase ?? "https://api.trillboards.com/v1";
|
|
181
|
+
this.authFetch = createAuthenticatedFetch(this.apiKey, this.apiBase);
|
|
182
|
+
this.audience = new AudienceClient(this.apiKey, this.apiBase);
|
|
183
|
+
this.analytics = new AnalyticsClient(this.apiKey, this.apiBase);
|
|
184
|
+
this.auctions = new AuctionClient(this.apiKey, this.apiBase);
|
|
185
|
+
this.creatives = new CreativeClient(this.apiKey, this.apiBase);
|
|
186
|
+
}
|
|
187
|
+
createVastTagBuilder() {
|
|
188
|
+
return new VastTagBuilder({ apiKey: this.apiKey, apiBase: this.apiBase });
|
|
189
|
+
}
|
|
190
|
+
createTrackingBatch() {
|
|
191
|
+
return new TrackingBatch({ apiKey: this.apiKey, apiBase: this.apiBase });
|
|
192
|
+
}
|
|
193
|
+
async fetch(path, options = {}) {
|
|
194
|
+
return this.authFetch(path, options);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
export { AnalyticsClient, AuctionClient, AudienceClient, CreativeClient, PartnerClient, TrackingBatch, VastTagBuilder, createAuthenticatedFetch };
|
|
199
|
+
//# sourceMappingURL=server.mjs.map
|
|
200
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/fetchWithAuth.ts","../src/server/VastTagBuilder.ts","../src/server/TrackingBatch.ts","../src/server/AudienceClient.ts","../src/server/AnalyticsClient.ts","../src/server/AuctionClient.ts","../src/server/CreativeClient.ts","../src/server/PartnerClient.ts"],"names":[],"mappings":"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","file":"server.mjs","sourcesContent":["// ─────────────────────────────────────────────────────────────\n// @trillboards/ads-sdk — Shared authenticated fetch utility\n// ─────────────────────────────────────────────────────────────\n\n/**\n * Create a reusable authenticated fetch function bound to a\n * specific API key and base URL.\n *\n * - Strips trailing slashes from `apiBase` to avoid double-slash paths.\n * - Applies a 10-second timeout via `AbortSignal.timeout` unless\n * the caller provides their own `signal`.\n * - Always sends `Authorization: Bearer <key>` and\n * `Content-Type: application/json`.\n * - Throws on non-2xx responses.\n */\nexport function createAuthenticatedFetch(apiKey: string, apiBase: string) {\n const base = apiBase.replace(/\\/+$/, '');\n\n return async (path: string, options?: RequestInit): Promise<any> => {\n const response = await globalThis.fetch(`${base}${path}`, {\n ...options,\n signal: options?.signal ?? AbortSignal.timeout(10000),\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n ...((options?.headers as Record<string, string>) ?? {}),\n },\n });\n\n if (!response.ok) {\n throw new Error(`API error: HTTP ${response.status}`);\n }\n\n return response.json();\n };\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface VastTagBuilderConfig {\n apiKey: string;\n apiBase?: string;\n}\n\nexport interface BuildTagOptions {\n deviceId: string;\n width?: number;\n height?: number;\n orientation?: 'portrait' | 'landscape';\n muted?: boolean;\n autoplay?: boolean;\n userAgent?: string;\n}\n\nexport interface VastTagResult {\n url: string;\n sources: Array<{\n name: string;\n vast_url: string;\n priority: number;\n timeout_ms: number;\n }>;\n auctionWinner?: {\n source: string;\n bid_price_cpm: number;\n vast_url: string;\n } | null;\n}\n\nexport class VastTagBuilder {\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(config: VastTagBuilderConfig) {\n this.authFetch = createAuthenticatedFetch(config.apiKey, config.apiBase ?? 'https://api.trillboards.com/v1');\n }\n\n async buildTag(options: BuildTagOptions): Promise<VastTagResult> {\n const params = new URLSearchParams();\n if (options.width) params.set('slot_w', String(options.width));\n if (options.height) params.set('slot_h', String(options.height));\n if (options.orientation) params.set('orientation', options.orientation);\n if (options.muted !== undefined) params.set('muted', options.muted ? '1' : '0');\n if (options.autoplay !== undefined) params.set('autoplay', options.autoplay ? '1' : '0');\n if (options.userAgent) params.set('ua', options.userAgent);\n\n const query = params.toString();\n const path = `/partner/device/${options.deviceId}/ads${query ? `?${query}` : ''}`;\n\n const data = await this.authFetch(path);\n const hbs = data.data?.header_bidding_settings;\n\n return {\n url: hbs?.vast_tag_url ?? '',\n sources: (hbs?.vast_waterfall?.sources ?? []).map((s: any) => ({\n name: s.name,\n vast_url: s.vast_url,\n priority: s.priority,\n timeout_ms: s.timeout_ms,\n })),\n auctionWinner: hbs?.auction_winner ?? null,\n };\n }\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface TrackingBatchConfig {\n apiKey: string;\n apiBase?: string;\n}\n\nexport interface ImpressionReport {\n adId: string;\n impressionId: string;\n deviceId: string;\n screenId?: string;\n duration: number;\n completed: boolean;\n timestamp: string;\n}\n\nexport interface TrackingResult {\n success: boolean;\n tracked: number;\n proofs: Array<{\n impressionId: string;\n proof: string;\n publicKeyUrl: string;\n }>;\n}\n\nexport class TrackingBatch {\n private apiBase: string;\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(config: TrackingBatchConfig) {\n this.apiBase = (config.apiBase ?? 'https://api.trillboards.com/v1').replace(/\\/+$/, '');\n this.authFetch = createAuthenticatedFetch(config.apiKey, config.apiBase ?? 'https://api.trillboards.com/v1');\n }\n\n async report(impressions: ImpressionReport[]): Promise<TrackingResult> {\n const data = await this.authFetch('/partner/tracking/batch', {\n method: 'POST',\n body: JSON.stringify({ impressions }),\n });\n\n return {\n success: data.success ?? true,\n tracked: data.data?.tracked ?? impressions.length,\n proofs: (data.data?.proofs ?? []).map((p: any) => ({\n impressionId: p.impression_id,\n proof: p.proof,\n publicKeyUrl: p.public_key_url ?? `${this.apiBase}/.well-known/public-key`,\n })),\n };\n }\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface LiveAudience {\n face_count: number;\n attention_score: number;\n mood: string | null;\n income_level: string | null;\n purchase_intent: number | null;\n dwell_time_ms: number | null;\n timestamp: string;\n}\n\nexport interface AudiencePrediction {\n predicted_face_count: number;\n predicted_attention_score: number;\n predicted_mood: string | null;\n confidence: number;\n hour: number;\n dayOfWeek: number;\n}\n\nexport interface LookalikeScreen {\n screenId: string;\n similarity: number;\n audience_profile: Record<string, unknown>;\n}\n\nexport class AudienceClient {\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(apiKey: string, apiBase: string) {\n this.authFetch = createAuthenticatedFetch(apiKey, apiBase);\n }\n\n async getLive(screenId: string): Promise<LiveAudience> {\n const data = await this.authFetch(`/partner/audience/live/${screenId}`);\n return data.data ?? data;\n }\n\n async predict(screenId: string, options: { hour: number; dayOfWeek: number }): Promise<AudiencePrediction> {\n const params = new URLSearchParams({\n hour: String(options.hour),\n day_of_week: String(options.dayOfWeek),\n });\n const data = await this.authFetch(`/partner/audience/predict/${screenId}?${params}`);\n return data.data ?? data;\n }\n\n async findLookalikes(screenId: string, options?: { limit?: number; minSimilarity?: number }): Promise<LookalikeScreen[]> {\n const params = new URLSearchParams();\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.minSimilarity) params.set('min_similarity', String(options.minSimilarity));\n const query = params.toString();\n const data = await this.authFetch(`/partner/audience/lookalikes/${screenId}${query ? `?${query}` : ''}`);\n return data.data ?? [];\n }\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface ScreenDailyAnalytics {\n date: string;\n ads: {\n plays_started: number;\n plays_completed: number;\n completion_rate: number;\n programmatic_plays: number;\n direct_plays: number;\n };\n audience: {\n avg_face_count: number;\n avg_attention_score: number;\n peak_viewers: number;\n };\n earnings: {\n programmatic_cents: number;\n direct_cents: number;\n total_cents: number;\n };\n streaming: {\n seconds: number;\n uptime_percentage: number;\n };\n}\n\nexport interface EarningsData {\n screenId: string;\n period: string;\n impressions_count: number;\n cpm_rate: number;\n gross_revenue: number;\n earner_revenue: number;\n earner_share_rate: number;\n}\n\nexport class AnalyticsClient {\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(apiKey: string, apiBase: string) {\n this.authFetch = createAuthenticatedFetch(apiKey, apiBase);\n }\n\n async getScreenDaily(screenId: string, options: { startDate: string; endDate: string }): Promise<ScreenDailyAnalytics[]> {\n const params = new URLSearchParams({\n start_date: options.startDate,\n end_date: options.endDate,\n });\n const data = await this.authFetch(`/partner/screens/${screenId}/analytics?${params}`);\n return data.data ?? [];\n }\n\n async getEarnings(options?: { screenId?: string; startDate?: string; endDate?: string }): Promise<EarningsData[]> {\n const params = new URLSearchParams();\n if (options?.screenId) params.set('screen_id', options.screenId);\n if (options?.startDate) params.set('start_date', options.startDate);\n if (options?.endDate) params.set('end_date', options.endDate);\n const query = params.toString();\n const data = await this.authFetch(`/partner/earnings${query ? `?${query}` : ''}`);\n return data.data ?? [];\n }\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface AuctionResult {\n auction_id: string;\n screen_id: string;\n timestamp: string;\n winning_bid: {\n bid_price_cpm: number;\n dsp_name: string;\n creative_id: string;\n vast_url: string;\n } | null;\n all_bids: Array<{\n dsp_name: string;\n bid_price_cpm: number;\n latency_ms: number;\n }>;\n latency_ms: number;\n floor_price_cpm: number;\n}\n\nexport class AuctionClient {\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(apiKey: string, apiBase: string) {\n this.authFetch = createAuthenticatedFetch(apiKey, apiBase);\n }\n\n async list(options?: { screenId?: string; limit?: number; offset?: number }): Promise<AuctionResult[]> {\n const params = new URLSearchParams();\n if (options?.screenId) params.set('screen_id', options.screenId);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.offset) params.set('offset', String(options.offset));\n const query = params.toString();\n const data = await this.authFetch(`/partner/auctions${query ? `?${query}` : ''}`);\n return data.data ?? [];\n }\n\n async get(auctionId: string): Promise<AuctionResult> {\n const data = await this.authFetch(`/partner/auctions/${auctionId}`);\n return data.data ?? data;\n }\n}\n","import { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface CreativeReview {\n creative_id: string;\n advertiser_name: string;\n creative_url: string;\n status: 'pending' | 'approved' | 'flagged' | 'blocked';\n iab_categories: string[];\n age_rating: string | null;\n brand_detected: string | null;\n content_flags: string[];\n reviewed_at: string | null;\n created_at: string;\n}\n\nexport interface CreativeStats {\n total: number;\n pending: number;\n approved: number;\n flagged: number;\n blocked: number;\n}\n\nexport class CreativeClient {\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n constructor(apiKey: string, apiBase: string) {\n this.authFetch = createAuthenticatedFetch(apiKey, apiBase);\n }\n\n async list(options?: { status?: string; limit?: number; offset?: number }): Promise<CreativeReview[]> {\n const params = new URLSearchParams();\n if (options?.status) params.set('status', options.status);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.offset) params.set('offset', String(options.offset));\n const query = params.toString();\n const data = await this.authFetch(`/openrtb/v1/creative-review${query ? `?${query}` : ''}`);\n return data.data ?? [];\n }\n\n async getStats(): Promise<CreativeStats> {\n const data = await this.authFetch('/openrtb/v1/creative-review/stats');\n return data.data ?? data;\n }\n\n async block(creativeId: string, reason?: string): Promise<void> {\n await this.authFetch(`/openrtb/v1/creative-review/${creativeId}/block`, {\n method: 'POST',\n body: JSON.stringify({ reason }),\n });\n }\n\n async unblock(creativeId: string): Promise<void> {\n await this.authFetch(`/openrtb/v1/creative-review/${creativeId}/unblock`, {\n method: 'POST',\n });\n }\n}\n","import { VastTagBuilder } from './VastTagBuilder';\nimport { TrackingBatch } from './TrackingBatch';\nimport { AudienceClient } from './AudienceClient';\nimport { AnalyticsClient } from './AnalyticsClient';\nimport { AuctionClient } from './AuctionClient';\nimport { CreativeClient } from './CreativeClient';\nimport { createAuthenticatedFetch } from './fetchWithAuth';\n\nexport interface PartnerClientConfig {\n apiKey: string;\n apiBase?: string;\n}\n\nexport class PartnerClient {\n private apiKey: string;\n private apiBase: string;\n private authFetch: ReturnType<typeof createAuthenticatedFetch>;\n\n readonly audience: AudienceClient;\n readonly analytics: AnalyticsClient;\n readonly auctions: AuctionClient;\n readonly creatives: CreativeClient;\n\n constructor(config: PartnerClientConfig) {\n this.apiKey = config.apiKey;\n this.apiBase = config.apiBase ?? 'https://api.trillboards.com/v1';\n this.authFetch = createAuthenticatedFetch(this.apiKey, this.apiBase);\n this.audience = new AudienceClient(this.apiKey, this.apiBase);\n this.analytics = new AnalyticsClient(this.apiKey, this.apiBase);\n this.auctions = new AuctionClient(this.apiKey, this.apiBase);\n this.creatives = new CreativeClient(this.apiKey, this.apiBase);\n }\n\n createVastTagBuilder(): VastTagBuilder {\n return new VastTagBuilder({ apiKey: this.apiKey, apiBase: this.apiBase });\n }\n\n createTrackingBatch(): TrackingBatch {\n return new TrackingBatch({ apiKey: this.apiKey, apiBase: this.apiBase });\n }\n\n protected async fetch(path: string, options: RequestInit = {}): Promise<any> {\n return this.authFetch(path, options);\n }\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var TrillboardsLiteBundle=(()=>{var _=Object.defineProperty,X=Object.defineProperties,Y=Object.getOwnPropertyDescriptor,Z=Object.getOwnPropertyDescriptors,Q=Object.getOwnPropertyNames,V=Object.getOwnPropertySymbols;var q=Object.prototype.hasOwnProperty,ee=Object.prototype.propertyIsEnumerable;var U=(r,e,t)=>e in r?_(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,I=(r,e)=>{for(var t in e||(e={}))q.call(e,t)&&U(r,t,e[t]);if(V)for(var t of V(e))ee.call(e,t)&&U(r,t,e[t]);return r},K=(r,e)=>X(r,Z(e));var te=(r,e)=>{for(var t in e)_(r,t,{get:e[t],enumerable:!0})},ie=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Q(e))!q.call(r,s)&&s!==t&&_(r,s,{get:()=>e[s],enumerable:!(i=Y(e,s))||i.enumerable});return r};var re=r=>ie(_({},"__esModule",{value:!0}),r);var ne={};te(ne,{TrillboardsLite:()=>j});var B="2.0.0",g={API_BASE:"https://api.trillboards.com/v1/partner",CDN_BASE:"https://cdn.trillboards.com",CACHE_NAME:"trillboards-lite-ads",CACHE_SIZE:10,REFRESH_INTERVAL:12e4,HEARTBEAT_INTERVAL:6e4,DEFAULT_IMAGE_DURATION:8e3,DEFAULT_AD_INTERVAL:6e4,PROGRAMMATIC_TIMEOUT_MS:12e3,PROGRAMMATIC_MIN_INTERVAL_MS:5e3,PROGRAMMATIC_RETRY_MS:5e3,PROGRAMMATIC_BACKOFF_MAX_MS:3e5,VERSION:B};function H(r){var t,i,s,a,n,o,h,l,p,f,v,c,m,d;let e=(t=r.deviceId)==null?void 0:t.trim();if(!e)throw new Error("TrillboardsConfig: deviceId must be a non-empty string");return{deviceId:e,apiBase:(i=r.apiBase)!=null?i:g.API_BASE,cdnBase:(s=r.cdnBase)!=null?s:g.CDN_BASE,waterfall:(a=r.waterfall)!=null?a:"programmatic_only",autoStart:(n=r.autoStart)!=null?n:!0,refreshInterval:Math.max((o=r.refreshInterval)!=null?o:g.REFRESH_INTERVAL,1e4),heartbeatInterval:Math.max((h=r.heartbeatInterval)!=null?h:g.HEARTBEAT_INTERVAL,5e3),defaultImageDuration:Math.max((l=r.defaultImageDuration)!=null?l:g.DEFAULT_IMAGE_DURATION,1e3),defaultAdInterval:Math.max((p=r.defaultAdInterval)!=null?p:g.DEFAULT_AD_INTERVAL,1e3),programmaticTimeout:Math.max((f=r.programmaticTimeout)!=null?f:g.PROGRAMMATIC_TIMEOUT_MS,1e3),programmaticMinInterval:Math.max((v=r.programmaticMinInterval)!=null?v:g.PROGRAMMATIC_MIN_INTERVAL_MS,1e3),programmaticRetry:Math.max((c=r.programmaticRetry)!=null?c:g.PROGRAMMATIC_RETRY_MS,1e3),programmaticBackoffMax:Math.max((m=r.programmaticBackoffMax)!=null?m:g.PROGRAMMATIC_BACKOFF_MAX_MS,5e3),cacheSize:Math.max((d=r.cacheSize)!=null?d:g.CACHE_SIZE,1)}}var W={initialized:!1,isPlaying:!1,isPaused:!1,isOffline:!1,currentAd:null,adCount:0,programmaticPlaying:!1,prefetchedReady:!1,waterfallMode:"programmatic_only",screenId:null,deviceId:null};function k(){return{deviceId:null,partnerId:null,screenId:null,ads:[],currentAdIndex:0,isPlaying:!1,isPaused:!1,isOffline:!1,settings:{},programmatic:null,programmaticPlaying:!1,prefetchedReady:!1,waterfallMode:"programmatic_only",autoStart:!0,container:null,adTimer:null,refreshTimer:null,heartbeatTimer:null,programmaticRetryTimer:null,programmaticRetryActive:!1,programmaticRetryCount:0,programmaticLastError:null,initialized:!1,screenOrientation:null,screenDimensions:null,etag:null}}function z(r){var e,t;return{initialized:r.initialized,isPlaying:r.isPlaying,isPaused:r.isPaused,isOffline:r.isOffline,currentAd:(e=r.ads[r.currentAdIndex])!=null?e:null,adCount:r.ads.length,programmaticPlaying:r.programmaticPlaying,prefetchedReady:(t=r.prefetchedReady)!=null?t:!1,waterfallMode:r.waterfallMode,screenId:r.screenId,deviceId:r.deviceId}}var b=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){var i;(i=this.handlers.get(e))==null||i.delete(t)}emit(e,t){let i=this.handlers.get(e);if(i)for(let s of[...i])try{s(t)}catch(a){console.error(`[TrillboardsAds] Event handler error for "${String(e)}":`,a)}}once(e,t){let i=s=>{this.off(e,i),t(s)};this.on(e,i)}removeAllListeners(){this.handlers.clear()}};function se(r){if(typeof window=="undefined")return{slotWidth:null,slotHeight:null,orientation:null,muted:!0,autoplayAllowed:!0,userAgent:null};let e=window.innerWidth,t=window.innerHeight;if(r){let i=r.getBoundingClientRect();i.width>0&&i.height>0&&(e=Math.round(i.width),t=Math.round(i.height))}return{slotWidth:e,slotHeight:t,orientation:t>e?"portrait":"landscape",muted:!0,autoplayAllowed:!0,userAgent:typeof navigator!="undefined"?navigator.userAgent:null}}var R=class{constructor(e){this.container=null;this.apiBase=e!=null?e:g.API_BASE}setContainer(e){this.container=e}async fetchAds(e,t=null){var n,o,h,l,p,f,v,c,m,d,E,T;let i={Accept:"application/json"};t&&(i["If-None-Match"]=t);let s=new AbortController,a=setTimeout(()=>s.abort(),1e4);try{let u=se(this.container),A=new URLSearchParams;u.slotWidth&&A.set("slot_w",String(u.slotWidth)),u.slotHeight&&A.set("slot_h",String(u.slotHeight)),u.orientation&&A.set("orientation",u.orientation),A.set("muted",u.muted?"1":"0"),A.set("autoplay",u.autoplayAllowed?"1":"0"),u.userAgent&&A.set("ua",u.userAgent);let F=A.toString(),$=F?`${this.apiBase}/device/${e}/ads?${F}`:`${this.apiBase}/device/${e}/ads`,S=await fetch($,{headers:i,signal:s.signal});if(clearTimeout(a),S.status===304)return{ads:[],settings:{},programmatic:null,screenId:null,screenOrientation:null,screenDimensions:null,etag:t,notModified:!0};if(!S.ok)throw new Error(`HTTP ${S.status}`);let w=await S.json(),J=S.headers.get("ETag");return{ads:(o=(n=w.data)==null?void 0:n.ads)!=null?o:[],settings:(l=(h=w.data)==null?void 0:h.settings)!=null?l:{},programmatic:(f=(p=w.data)==null?void 0:p.header_bidding_settings)!=null?f:null,screenId:(c=(v=w.data)==null?void 0:v.screen_id)!=null?c:null,screenOrientation:(d=(m=w.data)==null?void 0:m.screen_orientation)!=null?d:null,screenDimensions:(T=(E=w.data)==null?void 0:E.screen_dimensions)!=null?T:null,etag:J,notModified:!1}}catch(u){throw clearTimeout(a),u}}async reportImpression(e){try{let t=new URLSearchParams({adid:e.adid,impid:e.impid,did:e.did,aid:e.aid,duration:String(e.duration||0),completed:e.completed?"true":"false"});return(await fetch(`${this.apiBase}/impression?${t}`,{method:"GET",signal:AbortSignal.timeout(5e3)})).ok}catch(t){return!1}}async sendHeartbeat(e,t){try{return(await fetch(`${this.apiBase}/device/${e}/heartbeat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({device_id:e,screen_id:t,timestamp:new Date().toISOString(),status:"active"}),signal:AbortSignal.timeout(5e3)})).ok}catch(i){return!1}}async reportProgrammaticEvent(e){try{return(await fetch(`${this.apiBase}/programmatic-event`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({screen_id:e.screenId,device_id:e.deviceId,event_type:e.eventType,vast_source:e.vastSource,variant_name:e.variantName,error_code:e.errorCode,error_message:e.errorMessage,duration:e.duration,telemetry:e.telemetry,timestamp:new Date().toISOString()}),signal:AbortSignal.timeout(5e3)})).ok}catch(t){return!1}}};var M=class{constructor(e=10){this.db=null;this.DB_NAME="TrillboardsAdsCache";this.DB_VERSION=1;this.STORE_ADS="ads";this.STORE_IMPRESSIONS="pendingImpressions";this.maxCacheSize=e}async init(){if(!this.db)return new Promise((e,t)=>{if(typeof indexedDB=="undefined"){e();return}let i=indexedDB.open(this.DB_NAME,this.DB_VERSION);i.onerror=()=>t(i.error),i.onsuccess=()=>{this.db=i.result,e()},i.onupgradeneeded=s=>{let a=s.target.result;a.objectStoreNames.contains(this.STORE_ADS)||a.createObjectStore(this.STORE_ADS,{keyPath:"id"}).createIndex("cached_at","cached_at",{unique:!1}),a.objectStoreNames.contains(this.STORE_IMPRESSIONS)||a.createObjectStore(this.STORE_IMPRESSIONS,{keyPath:"impid"})}})}async cacheAds(e){if(!this.db)return;let t=this.db.transaction(this.STORE_ADS,"readwrite"),i=t.objectStore(this.STORE_ADS),s=Date.now();for(let a of e)i.put(K(I({},a),{cached_at:s}));await new Promise((a,n)=>{t.oncomplete=()=>a(),t.onerror=()=>n(t.error)}),await this.evictOldAds()}async getCachedAds(){return this.db?new Promise(e=>{let s=this.db.transaction(this.STORE_ADS,"readonly").objectStore(this.STORE_ADS).getAll();s.onsuccess=()=>e(s.result||[]),s.onerror=()=>e([])}):[]}async evictOldAds(){if(!this.db)return;let e=await this.getCachedAds();if(e.length<=this.maxCacheSize)return;let i=[...e].sort((n,o)=>{var h,l;return((h=o.cached_at)!=null?h:0)-((l=n.cached_at)!=null?l:0)}).slice(this.maxCacheSize),a=this.db.transaction(this.STORE_ADS,"readwrite").objectStore(this.STORE_ADS);for(let n of i)a.delete(n.id)}async savePendingImpression(e){if(!this.db)return;this.db.transaction(this.STORE_IMPRESSIONS,"readwrite").objectStore(this.STORE_IMPRESSIONS).put(e)}async getPendingImpressions(){return this.db?new Promise(e=>{let s=this.db.transaction(this.STORE_IMPRESSIONS,"readonly").objectStore(this.STORE_IMPRESSIONS).getAll();s.onsuccess=()=>e(s.result||[]),s.onerror=()=>e([])}):[]}async clearPendingImpressions(){if(!this.db)return;this.db.transaction(this.STORE_IMPRESSIONS,"readwrite").objectStore(this.STORE_IMPRESSIONS).clear()}destroy(){this.db&&(this.db.close(),this.db=null)}};var P=class{constructor(){this.VERSION="1.0";this.registered=null;this.detected=null;this.sessionId=`sess_${Date.now()}_${Math.random().toString(36).slice(2,9)}`;this.eventFilter=null;this.commandHandler=null;this.deviceId=null;this.screenId=null;this.messageListener=null;this.targetOrigin="*"}setContext(e,t){this.deviceId=e,this.screenId=t}register(e){var t,i;return typeof e.send!="function"?(console.error("[TrillboardsAds] Bridge requires send function"),!1):(this.registered={send:e.send,receive:(t=e.receive)!=null?t:null,name:(i=e.name)!=null?i:"CustomBridge"},Array.isArray(e.events)&&(this.eventFilter=new Set(e.events)),this.registered.receive&&this.commandHandler&&this.registered.receive(this.commandHandler),!0)}setCommandHandler(e){this.commandHandler=e}setTargetOrigin(e){this.targetOrigin=e}detect(){var t,i,s,a;if(typeof window=="undefined")return null;let e=null;if(window.TrillboardsBridge&&typeof window.TrillboardsBridge.onEvent=="function")e={type:"android",send:n=>window.TrillboardsBridge.onEvent(n)};else if(window.Android&&typeof window.Android.onTrillboardsEvent=="function")e={type:"android-alt",send:n=>window.Android.onTrillboardsEvent(n)};else if((s=(i=(t=window.webkit)==null?void 0:t.messageHandlers)==null?void 0:i.trillboards)!=null&&s.postMessage)e={type:"ios",send:n=>window.webkit.messageHandlers.trillboards.postMessage(JSON.parse(n))};else if(window.ReactNativeWebView&&typeof window.ReactNativeWebView.postMessage=="function")e={type:"react-native",send:n=>window.ReactNativeWebView.postMessage(n)};else if(window.Flutter&&typeof window.Flutter.postMessage=="function")e={type:"flutter",send:n=>window.Flutter.postMessage(n)};else if(window.__TRILL_CTV_BRIDGE__&&typeof window.__TRILL_CTV_BRIDGE__.postEvent=="function")e={type:"ctv",send:n=>window.__TRILL_CTV_BRIDGE__.postEvent(n)};else if(window.electronAPI&&typeof window.electronAPI.trillboardsEvent=="function")e={type:"electron",send:n=>window.electronAPI.trillboardsEvent(JSON.parse(n))};else if((a=window.__TAURI__)!=null&&a.event)e={type:"tauri",send:n=>{try{window.__TAURI__.event.emit("trillboards-event",JSON.parse(n))}catch(o){}}};else if(typeof window!="undefined"&&window.parent!==window&&typeof window.parent.postMessage=="function"){let n=this.targetOrigin;e={type:"postMessage",send:o=>window.parent.postMessage(JSON.parse(o),n)}}return this.detected=e,this.detected}buildPayload(e,t){let i={type:"trillboards",version:this.VERSION,event:e,data:t!=null?t:{},timestamp:Date.now(),deviceId:this.deviceId,screenId:this.screenId,sessionId:this.sessionId};return JSON.stringify(i)}send(e,t){var a;if(this.eventFilter&&!this.eventFilter.has(e))return!1;let i=this.buildPayload(e,t);if((a=this.registered)!=null&&a.send)try{return this.registered.send(e,JSON.parse(i)),!0}catch(n){}let s=this.detect();if(s!=null&&s.send)try{return s.send(i),!0}catch(n){}return!1}initCommandListener(){typeof window!="undefined"&&(this.messageListener&&window.removeEventListener("message",this.messageListener),this.messageListener=e=>{var t;((t=e.data)==null?void 0:t.type)==="trillboards-command"&&this.commandHandler&&this.commandHandler(e.data)},window.addEventListener("message",this.messageListener))}destroy(){typeof window!="undefined"&&this.messageListener&&(window.removeEventListener("message",this.messageListener),this.messageListener=null),this.registered=null,this.detected=null,this.commandHandler=null,this.eventFilter=null}};var C=class{constructor(e=5,t=3e4){this.sources=new Map;this.maxFailures=e,this.openDurationMs=t}recordSuccess(e){e&&this.sources.set(e,{consecutiveFailures:0,openUntil:0})}recordFailure(e){var i;if(!e)return;let t=(i=this.sources.get(e))!=null?i:{consecutiveFailures:0,openUntil:0};t.consecutiveFailures+=1,t.consecutiveFailures>=this.maxFailures&&(t.openUntil=Date.now()+this.openDurationMs),this.sources.set(e,t)}isAvailable(e){if(!e)return!0;let t=this.sources.get(e);if(!t||t.consecutiveFailures<this.maxFailures)return!0;let i=Date.now();return i>=t.openUntil?(t.openUntil=i+this.openDurationMs,!0):!1}getState(e){var t;return(t=this.sources.get(e))!=null?t:{consecutiveFailures:0,openUntil:0}}reset(){this.sources.clear()}};var L=class{constructor(){this.totalRequests=0;this.fills=0;this.noFills=0;this.timeouts=0;this.errors=0}recordRequest(){this.totalRequests++}recordFill(){this.fills++}recordNoFill(){this.noFills++}recordTimeout(){this.timeouts++}recordError(){this.errors++}getFillRate(){return this.totalRequests>0?this.fills/this.totalRequests:0}getNoFillRate(){return this.totalRequests>0?this.noFills/this.totalRequests:0}getTimeoutRate(){return this.totalRequests>0?this.timeouts/this.totalRequests:0}getErrorRate(){return this.totalRequests>0?this.errors/this.totalRequests:0}getSnapshot(){return{fill_rate:Math.round(this.getFillRate()*1e4)/1e4,no_fill_rate:Math.round(this.getNoFillRate()*1e4)/1e4,timeout_rate:Math.round(this.getTimeoutRate()*1e4)/1e4,error_rate:Math.round(this.getErrorRate()*1e4)/1e4}}reset(){this.totalRequests=0,this.fills=0,this.noFills=0,this.timeouts=0,this.errors=0}};var O=class{constructor(e){this.circuitBreaker=e}getNextSource(e){if(!e||e.length===0)return null;let t=[...e].filter(i=>i.enabled).sort((i,s)=>i.priority-s.priority||Math.random()-.5);for(let i of t)if(this.circuitBreaker.isAvailable(i.name))return{source:i,vastUrl:i.vast_url};return null}getAvailableSources(e){return!e||e.length===0?[]:e.filter(t=>t.enabled&&this.circuitBreaker.isAvailable(t.name)).sort((t,i)=>t.priority-i.priority||Math.random()-.5).map(t=>({source:t,vastUrl:t.vast_url}))}recordSuccess(e){this.circuitBreaker.recordSuccess(e)}recordFailure(e){this.circuitBreaker.recordFailure(e)}};var D=class{constructor(e,t=12e3){this.vastTagUrl=null;this.variantName=null;this.screenId=null;this.adContainer=null;this.contentVideo=null;this.ima={};this.currentSourceName=null;this.isPlaying=!1;this.isPrefetching=!1;this.prefetchedReady=!1;this.prefetchTimer=null;this.adStartTime=0;this.sources=[];this.circuitBreaker=new C(5,3e4),this.telemetry=new L,this.waterfallEngine=new O(this.circuitBreaker),this.events=e,this.timeoutMs=t}setSources(e){this.sources=e}getTelemetrySnapshot(){return this.telemetry.getSnapshot()}getIsPlaying(){return this.isPlaying}hasPrefetchedAd(){return this.prefetchedReady}createAdContainer(e){this.adContainer||(this.adContainer=document.createElement("div"),this.adContainer.id="trillboards-ad-container",this.adContainer.style.cssText="position:absolute;top:0;left:0;width:100%;height:100%;z-index:10000;display:none;",this.contentVideo=document.createElement("video"),this.contentVideo.id="trillboards-content-video",this.contentVideo.style.cssText="width:100%;height:100%;",this.contentVideo.setAttribute("playsinline",""),this.contentVideo.muted=!0,this.adContainer.appendChild(this.contentVideo),e.appendChild(this.adContainer))}async play(e,t){if(this.isPlaying)return;if(!this.adContainer||!this.contentVideo){t("Ad container not initialized");return}let i=this.vastTagUrl,s="default";if(this.sources.length>0){let o=this.waterfallEngine.getNextSource(this.sources);o&&(i=o.vastUrl,s=o.source.name)}if(!i){t("No VAST URL available");return}this.currentSourceName=s,this.telemetry.recordRequest();let a=Date.now(),n=i.includes("correlator=")?i.replace(/correlator=[^&]*/,`correlator=${a}`):`${i}${i.includes("?")?"&":"?"}correlator=${a}`;if(typeof google=="undefined"||!(google!=null&&google.ima)){t("Google IMA SDK not loaded"),this.telemetry.recordError(),this.waterfallEngine.recordFailure(s);return}this.isPlaying=!0,this.adContainer.style.display="block";try{await this.requestAdsViaIMA(n,e,t)}catch(o){this.isPlaying=!1,this.adContainer.style.display="none",this.telemetry.recordError(),this.waterfallEngine.recordFailure(s),t(o instanceof Error?o.message:String(o))}}async requestAdsViaIMA(e,t,i){return new Promise(s=>{let a=!1,n=()=>{a||(a=!0,t(),s())},o=v=>{a||(a=!0,i(v),s())};this.destroyIMA();let h=new google.ima.AdDisplayContainer(this.adContainer,this.contentVideo);h.initialize();let l=new google.ima.AdsLoader(h);this.ima.adDisplayContainer=h,this.ima.adsLoader=l;let p=setTimeout(()=>{this.telemetry.recordTimeout(),this.waterfallEngine.recordFailure(this.currentSourceName),this.stop({silent:!0}),this.events.emit("programmatic_timeout",{source:this.currentSourceName||"unknown"}),o("VAST request timeout")},this.timeoutMs);l.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,v=>{clearTimeout(p),this.telemetry.recordFill(),this.waterfallEngine.recordSuccess(this.currentSourceName);let c=v.getAdsManager(this.contentVideo);this.ima.adsManager=c,this.adStartTime=Date.now(),c.addEventListener(google.ima.AdEvent.Type.COMPLETE,()=>{let m=Math.round((Date.now()-this.adStartTime)/1e3);this.events.emit("programmatic_ended",{source:this.currentSourceName||"unknown",variant:this.variantName,duration:m}),this.stop({silent:!0}),n()}),c.addEventListener(google.ima.AdEvent.Type.STARTED,()=>{this.events.emit("programmatic_started",{source:this.currentSourceName||"unknown",variant:this.variantName})}),c.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,m=>{var E,T,u;let d=m.getError();this.events.emit("programmatic_error",{error:((E=d==null?void 0:d.getMessage)==null?void 0:E.call(d))||"Ad playback error",code:(T=d==null?void 0:d.getErrorCode)==null?void 0:T.call(d)}),this.stop({silent:!0}),o(((u=d==null?void 0:d.getMessage)==null?void 0:u.call(d))||"Ad error")});try{let m=this.adContainer.offsetWidth||window.innerWidth,d=this.adContainer.offsetHeight||window.innerHeight;c.init(m,d,google.ima.ViewMode.NORMAL),c.start()}catch(m){this.stop({silent:!0}),o("Failed to start ad")}}),l.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,v=>{var E,T;clearTimeout(p);let c=v.getError(),m=(E=c==null?void 0:c.getErrorCode)==null?void 0:E.call(c),d=((T=c==null?void 0:c.getMessage)==null?void 0:T.call(c))||"Ad load error";m===303?(this.waterfallEngine.recordFailure(this.currentSourceName),this.events.emit("programmatic_no_fill",{source:this.currentSourceName||"unknown"})):(this.telemetry.recordError(),this.waterfallEngine.recordFailure(this.currentSourceName),this.events.emit("programmatic_error",{error:d,code:m})),this.stop({silent:!0}),o(d)});let f=new google.ima.AdsRequest;f.adTagUrl=e,f.linearAdSlotWidth=this.adContainer.offsetWidth||window.innerWidth,f.linearAdSlotHeight=this.adContainer.offsetHeight||window.innerHeight,this.ima.adsRequest=f,l.requestAds(f)})}async prefetch(){return this.isPrefetching||this.prefetchedReady||!this.vastTagUrl&&this.sources.length===0?!1:(this.isPrefetching=!0,this.prefetchedReady=!0,this.isPrefetching=!1,this.events.emit("ad_ready",{type:"programmatic",source:this.currentSourceName||void 0}),!0)}destroyPrefetched(){this.prefetchedReady=!1,this.isPrefetching=!1,this.prefetchTimer&&(clearTimeout(this.prefetchTimer),this.prefetchTimer=null)}stop(e){this.isPlaying=!1,this.destroyIMA(),this.adContainer&&(this.adContainer.style.display="none")}destroyIMA(){if(this.ima.adsManager){try{this.ima.adsManager.removeEventListener(google.ima.AdEvent.Type.COMPLETE),this.ima.adsManager.removeEventListener(google.ima.AdEvent.Type.STARTED),this.ima.adsManager.removeEventListener(google.ima.AdErrorEvent.Type.AD_ERROR)}catch(e){}try{this.ima.adsManager.destroy()}catch(e){}this.ima.adsManager=null}if(this.ima.adsLoader){try{this.ima.adsLoader.destroy()}catch(e){}this.ima.adsLoader=null}this.ima.adDisplayContainer=null,this.ima.adsRequest=null}destroy(){this.stop({silent:!0}),this.destroyPrefetched(),this.adContainer&&(this.adContainer.remove(),this.adContainer=null,this.contentVideo=null),this.circuitBreaker.reset(),this.telemetry.reset()}};var G=300,x=class{constructor(e,t=8e3){this.container=null;this.currentAd=null;this.adTimer=null;this.videoElement=null;this.imageElement=null;this.videoEndedHandler=null;this.videoErrorHandler=null;this.events=e,this.defaultImageDuration=t}setContainer(e){this.container=e}play(e,t,i=0){this.container&&(this.stop(),this.currentAd=e,this.events.emit("ad_started",{id:e.id,type:e.type,index:i}),e.type==="video"?this.playVideo(e,t):this.playImage(e,t))}playVideo(e,t){for(this.videoElement=document.createElement("video"),this.videoElement.src=e.media_url,this.videoElement.style.cssText="width:100%;height:100%;object-fit:contain;",this.videoElement.setAttribute("playsinline",""),this.videoElement.muted=!0,this.videoElement.autoplay=!0,this.videoEndedHandler=()=>{var s,a;let i=Math.min(Math.round((a=(s=this.videoElement)==null?void 0:s.duration)!=null?a:e.duration),G);this.events.emit("ad_ended",{id:e.id,type:e.type,duration:i}),this.stop(),t()},this.videoErrorHandler=()=>{this.events.emit("ad_error",{error:"Video playback error"}),this.stop(),t()},this.videoElement.addEventListener("ended",this.videoEndedHandler),this.videoElement.addEventListener("error",this.videoErrorHandler);this.container.firstChild;)this.container.removeChild(this.container.firstChild);this.container.appendChild(this.videoElement)}playImage(e,t){var a;for(this.imageElement=document.createElement("img"),this.imageElement.src=e.media_url,this.imageElement.style.cssText="width:100%;height:100%;object-fit:contain;",this.imageElement.alt=(a=e.title)!=null?a:"Advertisement";this.container.firstChild;)this.container.removeChild(this.container.firstChild);this.container.appendChild(this.imageElement);let i=Math.min(e.duration||this.defaultImageDuration/1e3,G),s=i*1e3;this.adTimer=setTimeout(()=>{this.events.emit("ad_ended",{id:e.id,type:e.type,duration:Math.round(i)}),this.stop(),t()},s)}stop(){this.adTimer&&(clearTimeout(this.adTimer),this.adTimer=null),this.videoElement&&(this.videoEndedHandler&&(this.videoElement.removeEventListener("ended",this.videoEndedHandler),this.videoEndedHandler=null),this.videoErrorHandler&&(this.videoElement.removeEventListener("error",this.videoErrorHandler),this.videoErrorHandler=null),this.videoElement.pause(),this.videoElement.removeAttribute("src"),this.videoElement.load(),this.videoElement.remove(),this.videoElement=null),this.imageElement&&(this.imageElement.remove(),this.imageElement=null),this.currentAd=null}destroy(){this.stop(),this.container=null}};function ae(r){if(!r)return null;let e=String(r).toLowerCase();return["programmatic_only","programmatic-only","programmatic"].includes(e)?"programmatic_only":["programmatic_then_direct","programmatic-direct","programmatic+direct","hybrid"].includes(e)?"programmatic_then_direct":["direct_only","direct-only","direct"].includes(e)?"direct_only":null}var y=class y{constructor(e){this.onlineHandler=null;this.offlineHandler=null;this.visibilityHandler=null;this.config=H(e),this.state=k(),this.events=new b,this.api=new R(this.config.apiBase),this.cache=new M(this.config.cacheSize),this.bridge=new P,this.programmaticPlayer=new D(this.events,this.config.programmaticTimeout),this.directPlayer=new x(this.events,this.config.defaultImageDuration)}static async create(e){y._instance&&(y._instance.destroy(),y._instance=null);let t=new y(e);return await t.init(e),y._instance=t,t}async init(e){if(this.state.initialized)return;this.config=H(e),this.state.deviceId=this.config.deviceId,this.state.waterfallMode=this.config.waterfall,this.state.autoStart=this.config.autoStart;try{await this.cache.init()}catch(i){}this.bridge.setContext(this.state.deviceId,this.state.screenId),this.bridge.setCommandHandler(i=>this.handleBridgeCommand(i)),this.bridge.initCommandListener(),this.bridge.detect();let t=["initialized","ad_started","ad_ended","ad_ready","ad_error","programmatic_started","programmatic_ended","programmatic_error","programmatic_no_fill","state_changed"];for(let i of t)this.events.on(i,s=>{this.bridge.send(i,s)});this.createContainer(),typeof window!="undefined"&&(this.onlineHandler=()=>{this.state.isOffline&&(this.state.isOffline=!1,this.events.emit("online",{})),this.refreshAds().catch(()=>{})},this.offlineHandler=()=>{this.state.isOffline=!0,this.events.emit("offline",{}),this.emitStateChanged()},window.addEventListener("online",this.onlineHandler),window.addEventListener("offline",this.offlineHandler),this.visibilityHandler=()=>{let i=!document.hidden;this.events.emit("visibility_changed",{visible:i}),i&&this.refreshAds().catch(()=>{})},document.addEventListener("visibilitychange",this.visibilityHandler)),await this.refreshAds(),this.startRefreshTimer(),this.startHeartbeatTimer(),this.state.initialized=!0,this.events.emit("initialized",{deviceId:this.config.deviceId}),this.emitStateChanged(),this.state.autoStart&&this.prefetchNextAd().catch(()=>{})}destroy(){this.state.refreshTimer&&clearInterval(this.state.refreshTimer),this.state.heartbeatTimer&&clearInterval(this.state.heartbeatTimer),this.state.adTimer&&clearTimeout(this.state.adTimer),this.state.programmaticRetryTimer&&clearTimeout(this.state.programmaticRetryTimer),this.programmaticPlayer.destroy(),this.directPlayer.destroy(),this.bridge.destroy(),this.cache.destroy(),typeof window!="undefined"&&(this.onlineHandler&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null),this.offlineHandler&&(window.removeEventListener("offline",this.offlineHandler),this.offlineHandler=null),this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null)),this.state.container&&this.state.container.remove(),this.events.removeAllListeners(),this.state=k(),y._instance===this&&(y._instance=null)}show(){this.state.container&&(this.state.container.style.display="block"),this.state.isPlaying=!0,this.state.isPaused=!1,this.playNextAd(),this.emitStateChanged()}hide(){this.state.container&&(this.state.container.style.display="none"),this.state.isPlaying=!1,this.state.isPaused=!0,this.programmaticPlayer.stop(),this.directPlayer.stop(),this.emitStateChanged()}skipAd(){this.programmaticPlayer.stop(),this.directPlayer.stop(),this.playNextAd()}async refresh(){this.programmaticPlayer.destroyPrefetched(),this.resetProgrammaticBackoff(),this.state.etag=null,await this.refreshAds(),this.prefetchNextAd()}async prefetchNextAd(){let e=this.state.waterfallMode;if(e==="programmatic_only"||e==="programmatic_then_direct"){let t=this.state.programmatic;(t!=null&&t.vast_tag_url||t!=null&&t.sources&&t.sources.length>0)&&await this.programmaticPlayer.prefetch()}}getState(){return z(this.state)}getAds(){return[...this.state.ads]}on(e,t){this.events.on(e,t)}off(e,t){this.events.off(e,t)}registerBridge(e){return this.bridge.register(e)}createContainer(){if(typeof document=="undefined")return;let e=document.createElement("div");e.id="trillboards-ads-container",e.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;z-index:99999;display:none;background:#000;",document.body.appendChild(e),this.state.container=e,this.api.setContainer(e),this.directPlayer.setContainer(e),this.programmaticPlayer.createAdContainer(e)}async refreshAds(){var e,t,i,s,a,n,o,h;try{let l=await this.api.fetchAds(this.config.deviceId,this.state.etag);if(l.notModified)return;this.state.isOffline&&(this.state.isOffline=!1,this.events.emit("online",{})),this.state.ads=l.ads,this.state.settings=l.settings,this.state.etag=l.etag,this.state.screenId=(e=l.screenId)!=null?e:this.state.screenId,this.state.programmatic=l.programmatic,this.state.screenOrientation=(t=l.screenOrientation)!=null?t:this.state.screenOrientation,this.state.screenDimensions=(i=l.screenDimensions)!=null?i:this.state.screenDimensions,this.bridge.setContext(this.state.deviceId,this.state.screenId),this.programmaticPlayer.screenId=this.state.screenId,this.programmaticPlayer.vastTagUrl=(a=(s=this.state.programmatic)==null?void 0:s.vast_tag_url)!=null?a:null,this.programmaticPlayer.variantName=(o=(n=this.state.programmatic)==null?void 0:n.variant_name)!=null?o:null,(h=this.state.programmatic)!=null&&h.sources&&this.programmaticPlayer.setSources(this.state.programmatic.sources),this.state.ads.length>0&&await this.cache.cacheAds(this.state.ads),this.events.emit("ads_refreshed",{count:this.state.ads.length})}catch(l){this.state.isOffline=!0;let p=await this.cache.getCachedAds();p.length>0&&(this.state.ads=p,this.events.emit("ads_loaded_from_cache",{count:p.length}))}}startRefreshTimer(){this.state.refreshTimer&&clearInterval(this.state.refreshTimer),this.state.refreshTimer=setInterval(()=>{this.refreshAds().catch(()=>{})},this.config.refreshInterval)}startHeartbeatTimer(){this.state.heartbeatTimer&&clearInterval(this.state.heartbeatTimer),this.state.heartbeatTimer=setInterval(()=>{this.api.sendHeartbeat(this.config.deviceId,this.state.screenId)},this.config.heartbeatInterval)}playNextAd(){let e=this.state.waterfallMode;e==="programmatic_only"||e==="programmatic_then_direct"?this.playProgrammatic():e==="direct_only"&&this.playDirect()}playProgrammatic(){this.programmaticPlayer.getIsPlaying()||(this.state.programmaticPlaying=!0,this.emitStateChanged(),this.programmaticPlayer.play(()=>{this.state.programmaticPlaying=!1,this.emitStateChanged(),this.scheduleProgrammaticRetry()},e=>{this.state.programmaticPlaying=!1,this.state.programmaticLastError=e,this.state.programmaticRetryCount++,this.emitStateChanged(),this.state.waterfallMode==="programmatic_then_direct"&&this.state.ads.length>0?this.playDirect():this.scheduleProgrammaticRetry()}))}playDirect(){if(this.state.ads.length===0)return;let e=this.state.currentAdIndex%this.state.ads.length,t=this.state.ads[e];t&&this.directPlayer.play(t,()=>{var i;this.state.currentAdIndex=(e+1)%this.state.ads.length,this.api.reportImpression({adid:t.id,impid:t.impression_id,did:this.config.deviceId,aid:(i=t.allocation_id)!=null?i:"",duration:t.duration,completed:!0}),this.emitStateChanged(),this.scheduleNextDirect()},e)}scheduleNextDirect(){this.state.adTimer&&clearTimeout(this.state.adTimer),this.state.adTimer=setTimeout(()=>{this.playNextAd()},this.config.defaultAdInterval)}scheduleProgrammaticRetry(){this.state.programmaticRetryTimer&&clearTimeout(this.state.programmaticRetryTimer);let e=this.state.programmaticRetryCount,t=this.config.programmaticRetry,i=this.config.programmaticBackoffMax,s=Math.min(t*Math.pow(2,e),i),a=s*.2*Math.random();this.state.programmaticRetryTimer=setTimeout(()=>{this.prefetchNextAd().catch(()=>{}).then(()=>{this.playNextAd()})},s+a)}resetProgrammaticBackoff(){this.state.programmaticRetryCount=0,this.state.programmaticLastError=null,this.state.programmaticRetryTimer&&(clearTimeout(this.state.programmaticRetryTimer),this.state.programmaticRetryTimer=null)}emitStateChanged(){this.events.emit("state_changed",this.getState())}handleBridgeCommand(e){let t;try{t=typeof e=="string"?JSON.parse(e):e}catch(a){console.warn("[TrillboardsAds] Failed to parse bridge command:",e);return}let i=t.action||t.command,s=t.params||t.data||{};switch(i){case"show":this.show();break;case"hide":this.hide();break;case"skip":this.skipAd();break;case"refresh":this.refresh();break;case"getState":this.bridge.send("state_changed",this.getState());break;case"configure":if(s.waterfall){let a=ae(s.waterfall);a&&(this.state.waterfallMode=a)}typeof s.volume=="number"&&(this.state.settings.sound_enabled=s.volume>0);break}}};y._instance=null;var N=y;var j={VERSION:B,_instance:null,async init(r){var t,i;let e={deviceId:r.deviceId,waterfall:(t=r.waterfall)!=null?t:"programmatic_only",autoStart:(i=r.autoStart)!=null?i:!0,apiBase:r.apiBase};this._instance=await N.create(e)},show(){var r;(r=this._instance)==null||r.show()},hide(){var r;(r=this._instance)==null||r.hide()},skipAd(){var r;(r=this._instance)==null||r.skipAd()},async refresh(){var r;await((r=this._instance)==null?void 0:r.refresh())},async prefetchNextAd(){var r;await((r=this._instance)==null?void 0:r.prefetchNextAd())},getState(){var r,e;return(e=(r=this._instance)==null?void 0:r.getState())!=null?e:I({},W)},getAds(){var r,e;return(e=(r=this._instance)==null?void 0:r.getAds())!=null?e:[]},on(r,e){var t;(t=this._instance)==null||t.on(r,e)},off(r,e){var t;(t=this._instance)==null||t.off(r,e)},registerBridge(r){var e,t;return(t=(e=this._instance)==null?void 0:e.registerBridge(r))!=null?t:!1},destroy(){var r;(r=this._instance)==null||r.destroy(),this._instance=null}};typeof window!="undefined"&&(window.TrillboardsLite=j);return re(ne);})();
|
|
2
|
+
//# sourceMappingURL=trillboards-lite.global.js.map
|