@trillboards/ads-sdk 2.2.1 → 2.3.1

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/dist/index.mjs CHANGED
@@ -318,10 +318,17 @@ var ApiClient = class {
318
318
  }
319
319
  const data = await response.json();
320
320
  const newEtag = response.headers.get("ETag");
321
+ const hbs = data.data?.header_bidding_settings;
321
322
  const result = {
322
323
  ads: data.data?.ads ?? [],
323
324
  settings: data.data?.settings ?? {},
324
- programmatic: data.data?.header_bidding_settings ?? null,
325
+ programmatic: hbs ? {
326
+ ...hbs,
327
+ sources: (hbs.vast_waterfall?.sources ?? []).map((s) => ({
328
+ ...s,
329
+ enabled: s.enabled !== false
330
+ }))
331
+ } : null,
325
332
  screenId: data.data?.screen_id ?? null,
326
333
  screenOrientation: data.data?.screen_orientation ?? null,
327
334
  screenDimensions: data.data?.screen_dimensions ?? null,
@@ -919,7 +926,7 @@ var WaterfallEngine = class {
919
926
  */
920
927
  getNextSource(sources) {
921
928
  if (!sources || sources.length === 0) return null;
922
- const sorted = [...sources].filter((s) => s.enabled).sort((a, b) => a.priority - b.priority || Math.random() - 0.5);
929
+ const sorted = [...sources].filter((s) => s.enabled !== false).sort((a, b) => a.priority - b.priority || Math.random() - 0.5);
923
930
  for (const source of sorted) {
924
931
  if (this.circuitBreaker.isAvailable(source.name)) {
925
932
  return { source, vastUrl: source.vast_url };
@@ -934,7 +941,7 @@ var WaterfallEngine = class {
934
941
  */
935
942
  getAvailableSources(sources) {
936
943
  if (!sources || sources.length === 0) return [];
937
- return sources.filter((s) => s.enabled && this.circuitBreaker.isAvailable(s.name)).sort((a, b) => a.priority - b.priority || Math.random() - 0.5).map((source) => ({ source, vastUrl: source.vast_url }));
944
+ return sources.filter((s) => s.enabled !== false && this.circuitBreaker.isAvailable(s.name)).sort((a, b) => a.priority - b.priority || Math.random() - 0.5).map((source) => ({ source, vastUrl: source.vast_url }));
938
945
  }
939
946
  /** Record a successful ad fill for a source. */
940
947
  recordSuccess(sourceName) {
@@ -947,7 +954,7 @@ var WaterfallEngine = class {
947
954
  };
948
955
 
949
956
  // src/player/ProgrammaticPlayer.ts
950
- var ProgrammaticPlayer = class {
957
+ var _ProgrammaticPlayer = class _ProgrammaticPlayer {
951
958
  constructor(events, timeoutMs = 12e3) {
952
959
  // ── Public state ──────────────────────────────────────────
953
960
  this.vastTagUrl = null;
@@ -1034,8 +1041,11 @@ var ProgrammaticPlayer = class {
1034
1041
  this.telemetry.recordRequest();
1035
1042
  const correlator = Date.now();
1036
1043
  const finalUrl = vastUrl.includes("correlator=") ? vastUrl.replace(/correlator=[^&]*/, `correlator=${correlator}`) : `${vastUrl}${vastUrl.includes("?") ? "&" : "?"}correlator=${correlator}`;
1037
- if (typeof google === "undefined" || !google?.ima) {
1038
- onError("Google IMA SDK not loaded");
1044
+ const imaReady = await this.ensureImaSdk();
1045
+ if (!imaReady) {
1046
+ const msg = "Google IMA SDK not loaded";
1047
+ this.events.emit("programmatic_error", { error: msg, code: void 0 });
1048
+ onError(msg);
1039
1049
  this.telemetry.recordError();
1040
1050
  this.waterfallEngine.recordFailure(sourceName);
1041
1051
  return;
@@ -1052,6 +1062,50 @@ var ProgrammaticPlayer = class {
1052
1062
  onError(err instanceof Error ? err.message : String(err));
1053
1063
  }
1054
1064
  }
1065
+ /**
1066
+ * Ensure Google IMA SDK is available. If already loaded, resolves
1067
+ * immediately. Otherwise injects the `<script>` tag and waits.
1068
+ * Matches the Lite SDK's `loadImaScript()` pattern.
1069
+ */
1070
+ async ensureImaSdk() {
1071
+ if (typeof google !== "undefined" && google?.ima) return true;
1072
+ if (typeof document === "undefined") return false;
1073
+ const existing = document.querySelector(
1074
+ `script[src="${_ProgrammaticPlayer.IMA_SDK_URL}"]`
1075
+ );
1076
+ if (existing) {
1077
+ return new Promise((resolve) => {
1078
+ const start = Date.now();
1079
+ const check = () => {
1080
+ if (typeof google !== "undefined" && google?.ima) {
1081
+ resolve(true);
1082
+ } else if (Date.now() - start > 5e3) {
1083
+ resolve(false);
1084
+ } else {
1085
+ setTimeout(check, 100);
1086
+ }
1087
+ };
1088
+ check();
1089
+ });
1090
+ }
1091
+ if (!_ProgrammaticPlayer.imaLoadPromise) {
1092
+ _ProgrammaticPlayer.imaLoadPromise = new Promise((resolve) => {
1093
+ const script = document.createElement("script");
1094
+ script.src = _ProgrammaticPlayer.IMA_SDK_URL;
1095
+ script.async = true;
1096
+ script.onload = () => {
1097
+ _ProgrammaticPlayer.imaLoadPromise = null;
1098
+ resolve(true);
1099
+ };
1100
+ script.onerror = () => {
1101
+ _ProgrammaticPlayer.imaLoadPromise = null;
1102
+ resolve(false);
1103
+ };
1104
+ document.head.appendChild(script);
1105
+ });
1106
+ }
1107
+ return _ProgrammaticPlayer.imaLoadPromise;
1108
+ }
1055
1109
  // ── IMA request / playback lifecycle ──────────────────────
1056
1110
  async requestAdsViaIMA(vastUrl, onComplete, onError) {
1057
1111
  return new Promise((resolve) => {
@@ -1253,6 +1307,12 @@ var ProgrammaticPlayer = class {
1253
1307
  this.telemetry.reset();
1254
1308
  }
1255
1309
  };
1310
+ // ── IMA SDK loader ──────────────────────────────────────────
1311
+ /** IMA script URL */
1312
+ _ProgrammaticPlayer.IMA_SDK_URL = "https://imasdk.googleapis.com/js/sdkloader/ima3.js";
1313
+ /** Singleton load promise so concurrent calls don't insert multiple scripts. */
1314
+ _ProgrammaticPlayer.imaLoadPromise = null;
1315
+ var ProgrammaticPlayer = _ProgrammaticPlayer;
1256
1316
 
1257
1317
  // src/player/Player.ts
1258
1318
  var MAX_AD_DURATION_SECONDS = 300;