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