@trillboards/connect 1.0.0 → 1.1.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.js CHANGED
@@ -82,15 +82,26 @@ var require_device = __commonJS({
82
82
  ...metadata.custom
83
83
  }
84
84
  };
85
- const response = await fetch(`${API_BASE}/device`, {
86
- method: "POST",
87
- headers: {
88
- "Content-Type": "application/json",
89
- "Authorization": `Bearer ${apiKey}`,
90
- "X-SDK-Version": "1.0.0"
91
- },
92
- body: JSON.stringify(body)
93
- });
85
+ let response;
86
+ try {
87
+ response = await fetch(`${API_BASE}/device`, {
88
+ method: "POST",
89
+ headers: {
90
+ "Content-Type": "application/json",
91
+ "Authorization": `Bearer ${apiKey}`,
92
+ "X-SDK-Version": "1.0.0"
93
+ },
94
+ body: JSON.stringify(body)
95
+ });
96
+ } catch (fetchErr) {
97
+ const err = new Error(
98
+ `Network error during device registration: ${fetchErr.message}. If running from a browser, ensure your domain can reach api.trillboards.com. Test with: fetch("https://api.trillboards.com/v1/partner/ping").then(r => r.json()).then(console.log)`
99
+ );
100
+ err.statusCode = 0;
101
+ err.phase = "device_registration";
102
+ err.diagnosticUrl = `${API_BASE}/ping`;
103
+ throw err;
104
+ }
94
105
  if (!response.ok) {
95
106
  const errorData = await response.json().catch(() => ({}));
96
107
  const err = new Error(errorData.message || `Device registration failed: ${response.status}`);
@@ -1960,6 +1971,40 @@ var require_src = __commonJS({
1960
1971
  this.adRotation.start();
1961
1972
  }
1962
1973
  }
1974
+ /**
1975
+ * Request and display an ad in one call.
1976
+ * Returns a Promise that resolves with ad result or rejects on failure.
1977
+ *
1978
+ * @param {Object} [options]
1979
+ * @param {HTMLElement|string} [options.container] - DOM element or selector to render ad into (default: SDK's container)
1980
+ * @param {number} [options.timeout] - Max ms to wait for ad fill (default: 10000)
1981
+ * @param {boolean} [options.muted] - Start video muted (default: true)
1982
+ * @returns {Promise<{ad: Object|null, controller: Object|null, filled: boolean}>}
1983
+ */
1984
+ async requestAd(options = {}) {
1985
+ const container = options.container || resolveContainer(this.containerId);
1986
+ const timeout = options.timeout || 1e4;
1987
+ if (!this.initialized || !this.fingerprint) {
1988
+ throw new Error('Device not registered. Call init() first and wait for "ready" event.');
1989
+ }
1990
+ const adResponse = await Promise.race([
1991
+ fetchAds(this.fingerprint),
1992
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Ad request timed out")), timeout))
1993
+ ]);
1994
+ if (!adResponse || !adResponse.ads || adResponse.ads.length === 0) {
1995
+ return { ad: null, controller: null, filled: false };
1996
+ }
1997
+ const ad = adResponse.ads[0];
1998
+ const controller = renderAd(ad, container, {
1999
+ muted: options.muted !== false,
2000
+ onStart: (data) => this._emit("ad_started", { ad, ...data }),
2001
+ onComplete: (data) => this._emit("ad_complete", { ad, ...data }),
2002
+ onError: (err) => this._emit("ad_error", { ad, error: err })
2003
+ });
2004
+ trackImpression(ad, this.fingerprint).catch(() => {
2005
+ });
2006
+ return { ad, controller, filled: true };
2007
+ }
1963
2008
  /**
1964
2009
  * Get the current state of all subsystems.
1965
2010
  *