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