@trillboards/ads-sdk 2.1.1 → 2.2.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/CHANGELOG.md +10 -0
- package/README.md +9 -1
- package/dist/cli.js +2 -2
- package/dist/index.d.mts +45 -5
- package/dist/index.d.ts +45 -5
- package/dist/index.js +124 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +124 -11
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +2 -0
- package/dist/react-native.d.ts +2 -0
- package/dist/react-native.js +1 -0
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +1 -0
- package/dist/react-native.mjs.map +1 -1
- package/dist/react.d.mts +6 -0
- package/dist/react.d.ts +6 -0
- package/dist/react.js +124 -8
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +124 -8
- package/dist/react.mjs.map +1 -1
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +2 -2
- package/dist/server.mjs.map +1 -1
- package/dist/trillboards-lite.global.js +1 -1
- package/dist/trillboards-lite.global.js.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -2,6 +2,9 @@ import { createContext, useState, useEffect, useMemo, useContext, useCallback, u
|
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
// src/react/TrillboardsProvider.tsx
|
|
5
|
+
|
|
6
|
+
// src/core/config.ts
|
|
7
|
+
var SDK_VERSION = "2.2.0";
|
|
5
8
|
var DEFAULT_CONFIG = {
|
|
6
9
|
API_BASE: "https://api.trillboards.com/v1/partner",
|
|
7
10
|
CDN_BASE: "https://cdn.trillboards.com",
|
|
@@ -56,6 +59,7 @@ var DEFAULT_PUBLIC_STATE = {
|
|
|
56
59
|
programmaticPlaying: false,
|
|
57
60
|
prefetchedReady: false,
|
|
58
61
|
waterfallMode: "programmatic_only",
|
|
62
|
+
adDeliveryProfileMode: null,
|
|
59
63
|
screenId: null,
|
|
60
64
|
deviceId: null
|
|
61
65
|
};
|
|
@@ -83,6 +87,7 @@ function createInitialState() {
|
|
|
83
87
|
programmaticRetryActive: false,
|
|
84
88
|
programmaticRetryCount: 0,
|
|
85
89
|
programmaticLastError: null,
|
|
90
|
+
adDeliveryProfile: null,
|
|
86
91
|
initialized: false,
|
|
87
92
|
screenOrientation: null,
|
|
88
93
|
screenDimensions: null,
|
|
@@ -100,6 +105,7 @@ function getPublicState(internal) {
|
|
|
100
105
|
programmaticPlaying: internal.programmaticPlaying,
|
|
101
106
|
prefetchedReady: internal.prefetchedReady ?? false,
|
|
102
107
|
waterfallMode: internal.waterfallMode,
|
|
108
|
+
adDeliveryProfileMode: internal.adDeliveryProfile?.mode ?? null,
|
|
103
109
|
screenId: internal.screenId,
|
|
104
110
|
deviceId: internal.deviceId
|
|
105
111
|
};
|
|
@@ -360,10 +366,9 @@ var ApiClient = class {
|
|
|
360
366
|
}
|
|
361
367
|
}
|
|
362
368
|
/**
|
|
363
|
-
* Ping
|
|
364
|
-
* Returns `true` on 2xx, `false` on any error.
|
|
369
|
+
* Ping heartbeat endpoint and return delivery profile + queued commands.
|
|
365
370
|
*/
|
|
366
|
-
async sendHeartbeat(deviceId, screenId) {
|
|
371
|
+
async sendHeartbeat(deviceId, screenId, payload = {}) {
|
|
367
372
|
logger.debug("Sending heartbeat", { deviceId });
|
|
368
373
|
try {
|
|
369
374
|
const response = await fetch(`${this.apiBase}/device/${deviceId}/heartbeat`, {
|
|
@@ -373,13 +378,24 @@ var ApiClient = class {
|
|
|
373
378
|
device_id: deviceId,
|
|
374
379
|
screen_id: screenId,
|
|
375
380
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
376
|
-
status: "active"
|
|
381
|
+
status: "active",
|
|
382
|
+
...payload
|
|
377
383
|
}),
|
|
378
384
|
signal: AbortSignal.timeout(5e3)
|
|
379
385
|
});
|
|
380
|
-
|
|
386
|
+
if (!response.ok) {
|
|
387
|
+
return { ok: false, data: null };
|
|
388
|
+
}
|
|
389
|
+
let data = null;
|
|
390
|
+
try {
|
|
391
|
+
const json = await response.json();
|
|
392
|
+
data = json?.data ?? null;
|
|
393
|
+
} catch {
|
|
394
|
+
data = null;
|
|
395
|
+
}
|
|
396
|
+
return { ok: true, data };
|
|
381
397
|
} catch {
|
|
382
|
-
return false;
|
|
398
|
+
return { ok: false, data: null };
|
|
383
399
|
}
|
|
384
400
|
}
|
|
385
401
|
/**
|
|
@@ -1672,11 +1688,104 @@ var _TrillboardsAds = class _TrillboardsAds {
|
|
|
1672
1688
|
}
|
|
1673
1689
|
startHeartbeatTimer() {
|
|
1674
1690
|
if (this.state.heartbeatTimer) clearInterval(this.state.heartbeatTimer);
|
|
1691
|
+
const tick = () => {
|
|
1692
|
+
this.sendHeartbeatTick().catch(() => {
|
|
1693
|
+
});
|
|
1694
|
+
};
|
|
1695
|
+
tick();
|
|
1675
1696
|
this.state.heartbeatTimer = setInterval(() => {
|
|
1676
|
-
|
|
1697
|
+
tick();
|
|
1677
1698
|
}, this.config.heartbeatInterval);
|
|
1678
1699
|
}
|
|
1700
|
+
async sendHeartbeatTick() {
|
|
1701
|
+
const result = await this.api.sendHeartbeat(
|
|
1702
|
+
this.config.deviceId,
|
|
1703
|
+
this.state.screenId,
|
|
1704
|
+
this.buildHeartbeatPayload()
|
|
1705
|
+
);
|
|
1706
|
+
if (!result.ok || !result.data) return;
|
|
1707
|
+
if (result.data.ad_delivery_profile?.mode) {
|
|
1708
|
+
this.applyAdDeliveryProfile(result.data.ad_delivery_profile);
|
|
1709
|
+
}
|
|
1710
|
+
if (Array.isArray(result.data.commands) && result.data.commands.length > 0) {
|
|
1711
|
+
this.runHeartbeatCommands(result.data.commands);
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
buildHeartbeatPayload() {
|
|
1715
|
+
const userAgent = typeof navigator !== "undefined" ? navigator.userAgent : "";
|
|
1716
|
+
const platform = typeof navigator !== "undefined" ? navigator.platform : null;
|
|
1717
|
+
const connection = typeof navigator !== "undefined" ? navigator.connection : null;
|
|
1718
|
+
const chromiumMatch = userAgent.match(/(?:Chrome|Chromium)\/(\d+)/i);
|
|
1719
|
+
const chromiumMajor = chromiumMatch ? Number(chromiumMatch[1]) : void 0;
|
|
1720
|
+
const imaSupported = typeof window !== "undefined" ? Boolean(window?.google?.ima) : null;
|
|
1721
|
+
const telemetry = {
|
|
1722
|
+
powerState: typeof document !== "undefined" && document.hidden ? "standby" : "on",
|
|
1723
|
+
agentStatus: typeof document !== "undefined" && document.hidden ? "background" : "foreground",
|
|
1724
|
+
os: platform || void 0,
|
|
1725
|
+
agentVersion: SDK_VERSION,
|
|
1726
|
+
ima_integration: "html5_webview",
|
|
1727
|
+
ima_supported: imaSupported,
|
|
1728
|
+
webview_chromium_major: Number.isFinite(chromiumMajor) ? chromiumMajor : void 0
|
|
1729
|
+
};
|
|
1730
|
+
const payload = {
|
|
1731
|
+
telemetry,
|
|
1732
|
+
sdk: {
|
|
1733
|
+
version: SDK_VERSION,
|
|
1734
|
+
ima_supported: imaSupported,
|
|
1735
|
+
ima_integration: "html5_webview",
|
|
1736
|
+
webview_chromium_major: Number.isFinite(chromiumMajor) ? chromiumMajor : void 0
|
|
1737
|
+
},
|
|
1738
|
+
device: {
|
|
1739
|
+
os: platform || void 0,
|
|
1740
|
+
model: userAgent || void 0
|
|
1741
|
+
}
|
|
1742
|
+
};
|
|
1743
|
+
if (connection) {
|
|
1744
|
+
payload.network = {
|
|
1745
|
+
connectionType: connection.type || void 0,
|
|
1746
|
+
effectiveType: connection.effectiveType || void 0,
|
|
1747
|
+
downlinkMbps: typeof connection.downlink === "number" ? connection.downlink : void 0,
|
|
1748
|
+
bandwidthMbps: typeof connection.downlink === "number" ? connection.downlink : void 0,
|
|
1749
|
+
rtt: typeof connection.rtt === "number" ? connection.rtt : void 0,
|
|
1750
|
+
latencyRtt: typeof connection.rtt === "number" ? connection.rtt : void 0,
|
|
1751
|
+
saveData: typeof connection.saveData === "boolean" ? connection.saveData : void 0
|
|
1752
|
+
};
|
|
1753
|
+
}
|
|
1754
|
+
return payload;
|
|
1755
|
+
}
|
|
1756
|
+
applyAdDeliveryProfile(profile) {
|
|
1757
|
+
if (!profile?.mode) return;
|
|
1758
|
+
const previousMode = this.state.adDeliveryProfile?.mode ?? null;
|
|
1759
|
+
this.state.adDeliveryProfile = profile;
|
|
1760
|
+
if (profile.mode === "vast_fallback" && this.state.programmaticPlaying) {
|
|
1761
|
+
this.programmaticPlayer.stop({ silent: true });
|
|
1762
|
+
this.state.programmaticPlaying = false;
|
|
1763
|
+
}
|
|
1764
|
+
if (previousMode !== profile.mode) {
|
|
1765
|
+
this.emitStateChanged();
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
runHeartbeatCommands(commands) {
|
|
1769
|
+
for (const command of commands) {
|
|
1770
|
+
const name = String(command?.command || "").toLowerCase();
|
|
1771
|
+
if (name === "refresh_ads") {
|
|
1772
|
+
this.refresh().catch(() => {
|
|
1773
|
+
});
|
|
1774
|
+
} else if (name === "restart") {
|
|
1775
|
+
if (typeof window !== "undefined" && typeof window.location?.reload === "function") {
|
|
1776
|
+
window.location.reload();
|
|
1777
|
+
return;
|
|
1778
|
+
}
|
|
1779
|
+
this.refresh().catch(() => {
|
|
1780
|
+
});
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1679
1784
|
playNextAd() {
|
|
1785
|
+
if (this.state.adDeliveryProfile?.mode === "vast_fallback" && this.state.ads.length > 0) {
|
|
1786
|
+
this.playDirect();
|
|
1787
|
+
return;
|
|
1788
|
+
}
|
|
1680
1789
|
const mode = this.state.waterfallMode;
|
|
1681
1790
|
if (mode === "programmatic_only" || mode === "programmatic_then_direct") {
|
|
1682
1791
|
this.playProgrammatic();
|
|
@@ -1691,13 +1800,20 @@ var _TrillboardsAds = class _TrillboardsAds {
|
|
|
1691
1800
|
this.programmaticPlayer.play(
|
|
1692
1801
|
() => {
|
|
1693
1802
|
this.state.programmaticPlaying = false;
|
|
1803
|
+
this.resetProgrammaticBackoff();
|
|
1694
1804
|
this.emitStateChanged();
|
|
1695
1805
|
this.scheduleProgrammaticRetry();
|
|
1696
1806
|
},
|
|
1697
1807
|
(error) => {
|
|
1698
1808
|
this.state.programmaticPlaying = false;
|
|
1699
1809
|
this.state.programmaticLastError = error;
|
|
1700
|
-
|
|
1810
|
+
const normalizedError = String(error || "").toLowerCase();
|
|
1811
|
+
const isNoFillLike = normalizedError.includes("no fill") || normalizedError.includes("no ads vast response") || normalizedError.includes("waterfall_exhausted") || normalizedError === "throttled" || normalizedError === "busy";
|
|
1812
|
+
if (isNoFillLike) {
|
|
1813
|
+
this.state.programmaticRetryCount = 0;
|
|
1814
|
+
} else {
|
|
1815
|
+
this.state.programmaticRetryCount++;
|
|
1816
|
+
}
|
|
1701
1817
|
this.emitStateChanged();
|
|
1702
1818
|
if (this.state.waterfallMode === "programmatic_then_direct" && this.state.ads.length > 0) {
|
|
1703
1819
|
this.playDirect();
|