@trillboards/ads-sdk 2.0.0 → 2.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/CHANGELOG.md +23 -0
- package/README.md +65 -0
- package/dist/cli.js +158 -0
- package/dist/index.d.mts +56 -3
- package/dist/index.d.ts +56 -3
- package/dist/index.js +151 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +145 -4
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +1 -0
- package/dist/react-native.d.ts +1 -0
- package/dist/react.d.mts +1 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +73 -2
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +73 -2
- package/dist/react.mjs.map +1 -1
- package/dist/server.d.mts +106 -4
- package/dist/server.d.ts +106 -4
- package/dist/server.js +254 -4
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +248 -5
- 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 +22 -19
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@trillboards/ads-sdk` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.1.1] - 2026-02-15
|
|
6
|
+
|
|
7
|
+
### Fixes
|
|
8
|
+
- **Exports map**: Fixed `package.json` exports — `import` now correctly resolves to `.mjs`/`.d.mts` and `require` to `.js`/`.d.ts` (matches actual tsup output)
|
|
9
|
+
- **204 handling**: `fetchWithAuth` no longer throws `SyntaxError` on HTTP 204 No Content responses (affects `CreativeClient.block()` and `unblock()`)
|
|
10
|
+
- **Browser debug mode**: `debug: true` in `TrillboardsConfig` now correctly activates the logger (was a no-op in v2.1.0)
|
|
11
|
+
- **Error `instanceof`**: Added `Object.setPrototypeOf` to `TrillboardsError` base class for correct `instanceof` checks in transpiled environments
|
|
12
|
+
|
|
13
|
+
## [2.1.0] - 2026-02-15
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
- **CLI setup wizard**: `npx @trillboards/ads-sdk init` — registers account, creates first device, saves API key to `.env` in 30 seconds
|
|
17
|
+
- **Structured errors**: `TrillboardsError`, `TrillboardsAuthenticationError`, `TrillboardsRateLimitError`, `TrillboardsNotFoundError`, `TrillboardsValidationError` — all errors include `code`, `statusCode`, `type`, and `help` fields
|
|
18
|
+
- **Debug mode**: Set `debug: true` in config or `TRILLBOARDS_DEBUG=true` env var to log all API requests with timing
|
|
19
|
+
- **Environment variable auto-detection**: `PartnerClient` reads `TRILLBOARDS_API_KEY` from env — no need to pass in code
|
|
20
|
+
- **`PartnerClient.quickStart()`**: Static method for one-call registration + device creation + pre-authenticated client
|
|
21
|
+
- **Test mode detection**: `client.isTestMode` returns `true` when using a test API key (`trb_test_*`)
|
|
22
|
+
|
|
23
|
+
### Improvements
|
|
24
|
+
- Error messages now include actionable help text and links to docs
|
|
25
|
+
- All API errors parsed from JSON response body with `type`, `code`, `message`, `param` fields
|
|
26
|
+
- Debug logger prefixed with `[Trillboards]` for easy filtering
|
|
27
|
+
|
|
5
28
|
## [2.0.0] - 2026-02-14
|
|
6
29
|
|
|
7
30
|
### Breaking Changes
|
package/README.md
CHANGED
|
@@ -14,6 +14,24 @@ npm install @trillboards/ads-sdk
|
|
|
14
14
|
|
|
15
15
|
## Quick Start
|
|
16
16
|
|
|
17
|
+
### Fastest: One-command setup
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx @trillboards/ads-sdk init
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This registers your account, creates your first device, and saves your API key to `.env`. Zero configuration.
|
|
24
|
+
|
|
25
|
+
### Server (Node.js with env var)
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { PartnerClient } from '@trillboards/ads-sdk/server';
|
|
29
|
+
|
|
30
|
+
// Reads TRILLBOARDS_API_KEY from environment automatically
|
|
31
|
+
const client = new PartnerClient();
|
|
32
|
+
const audience = await client.audience.getLive('screen-id');
|
|
33
|
+
```
|
|
34
|
+
|
|
17
35
|
### Browser (core)
|
|
18
36
|
|
|
19
37
|
```typescript
|
|
@@ -75,6 +93,53 @@ The `TrillboardsConfig` interface accepts the following options:
|
|
|
75
93
|
| `refreshInterval` | `number` | `120000` | Ad refresh interval (ms) |
|
|
76
94
|
| `cacheSize` | `number` | `10` | Max cached ads |
|
|
77
95
|
|
|
96
|
+
## Debug Mode
|
|
97
|
+
|
|
98
|
+
Enable debug logging to see all API requests, state transitions, and cache operations:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// Browser
|
|
102
|
+
const sdk = await TrillboardsAds.create({ deviceId: 'xxx', debug: true });
|
|
103
|
+
|
|
104
|
+
// Server
|
|
105
|
+
const client = new PartnerClient({ debug: true });
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Or set the environment variable:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
TRILLBOARDS_DEBUG=true
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Environment Variables
|
|
115
|
+
|
|
116
|
+
| Variable | Description |
|
|
117
|
+
|----------|-------------|
|
|
118
|
+
| `TRILLBOARDS_API_KEY` | API key for `PartnerClient` (avoids passing in code) |
|
|
119
|
+
| `TRILLBOARDS_DEBUG` | Set to `true` to enable debug logging |
|
|
120
|
+
|
|
121
|
+
## Error Handling
|
|
122
|
+
|
|
123
|
+
The SDK throws typed errors that match the API error format:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import {
|
|
127
|
+
TrillboardsAuthenticationError,
|
|
128
|
+
TrillboardsRateLimitError,
|
|
129
|
+
} from '@trillboards/ads-sdk/server';
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
const audience = await client.audience.getLive('screen-id');
|
|
133
|
+
} catch (error) {
|
|
134
|
+
if (error instanceof TrillboardsAuthenticationError) {
|
|
135
|
+
console.log('Bad API key:', error.message);
|
|
136
|
+
console.log('Help:', error.help);
|
|
137
|
+
} else if (error instanceof TrillboardsRateLimitError) {
|
|
138
|
+
console.log(`Rate limited. Retry after ${error.retryAfter}s`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
78
143
|
## Events
|
|
79
144
|
|
|
80
145
|
The SDK emits typed events via the `EventMap` interface. Subscribe with `sdk.on(event, listener)` or `sdk.once(event, listener)`.
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var readline = require('readline');
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
|
|
8
|
+
function _interopNamespace(e) {
|
|
9
|
+
if (e && e.__esModule) return e;
|
|
10
|
+
var n = Object.create(null);
|
|
11
|
+
if (e) {
|
|
12
|
+
Object.keys(e).forEach(function (k) {
|
|
13
|
+
if (k !== 'default') {
|
|
14
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
15
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return e[k]; }
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
n.default = e;
|
|
23
|
+
return Object.freeze(n);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
27
|
+
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
28
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
29
|
+
|
|
30
|
+
// src/core/config.ts
|
|
31
|
+
var SDK_VERSION = "2.1.1";
|
|
32
|
+
|
|
33
|
+
// src/cli.ts
|
|
34
|
+
var BANNER = `
|
|
35
|
+
_____ ___ ___ _ _ ___ ___ _ ___ ___ ___
|
|
36
|
+
|_ _| _ \\_ _| | | | | _ )/ _ \\ /_\\ | _ \\ \\/ __|
|
|
37
|
+
| | | /| || |__| |__| _ \\ (_) / _ \\| / |) \\__ \\
|
|
38
|
+
|_| |_|_\\___|____|____|___/\\___/_/ \\_\\_|_\\___/|___/
|
|
39
|
+
|
|
40
|
+
Turn any screen into ad revenue in 30 seconds
|
|
41
|
+
`;
|
|
42
|
+
var API_BASE = "https://api.trillboards.com/v1";
|
|
43
|
+
function prompt(rl, question) {
|
|
44
|
+
return new Promise((resolve2) => {
|
|
45
|
+
rl.question(question, (answer) => resolve2(answer.trim()));
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async function callQuickStart(companyName, email) {
|
|
49
|
+
const response = await fetch(`${API_BASE}/partner/quick-start`, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: { "Content-Type": "application/json" },
|
|
52
|
+
body: JSON.stringify({
|
|
53
|
+
company_name: companyName,
|
|
54
|
+
email
|
|
55
|
+
}),
|
|
56
|
+
signal: AbortSignal.timeout(3e4)
|
|
57
|
+
});
|
|
58
|
+
const json = await response.json();
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
const msg = json?.error?.message ?? json?.message ?? `HTTP ${response.status}`;
|
|
61
|
+
throw new Error(msg);
|
|
62
|
+
}
|
|
63
|
+
return json.data;
|
|
64
|
+
}
|
|
65
|
+
function appendToEnvFile(apiKey) {
|
|
66
|
+
const envPath = path__namespace.resolve(process.cwd(), ".env");
|
|
67
|
+
const line = `TRILLBOARDS_API_KEY=${apiKey}
|
|
68
|
+
`;
|
|
69
|
+
if (fs__namespace.existsSync(envPath)) {
|
|
70
|
+
const content = fs__namespace.readFileSync(envPath, "utf-8");
|
|
71
|
+
if (content.includes("TRILLBOARDS_API_KEY=")) {
|
|
72
|
+
const updated = content.replace(/^TRILLBOARDS_API_KEY=.*$/m, `TRILLBOARDS_API_KEY=${apiKey}`);
|
|
73
|
+
fs__namespace.writeFileSync(envPath, updated);
|
|
74
|
+
} else {
|
|
75
|
+
const separator = content.endsWith("\n") ? "" : "\n";
|
|
76
|
+
fs__namespace.appendFileSync(envPath, `${separator}${line}`);
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
fs__namespace.writeFileSync(envPath, line);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function runInit() {
|
|
83
|
+
console.log(BANNER);
|
|
84
|
+
let completed = false;
|
|
85
|
+
const rl = readline__namespace.createInterface({
|
|
86
|
+
input: process.stdin,
|
|
87
|
+
output: process.stdout
|
|
88
|
+
});
|
|
89
|
+
rl.on("close", () => {
|
|
90
|
+
if (!completed) {
|
|
91
|
+
console.log("\nAborted.");
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
try {
|
|
96
|
+
const companyName = await prompt(rl, " Company name: ");
|
|
97
|
+
if (!companyName) {
|
|
98
|
+
console.error("\n Error: Company name is required.");
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
const email = await prompt(rl, " Email: ");
|
|
102
|
+
if (!email || !email.includes("@")) {
|
|
103
|
+
console.error("\n Error: A valid email is required.");
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
console.log("\n Registering...\n");
|
|
107
|
+
const data = await callQuickStart(companyName, email);
|
|
108
|
+
appendToEnvFile(data.credentials.api_key);
|
|
109
|
+
const keyPreview = data.credentials.api_key_prefix;
|
|
110
|
+
const fingerprint = data.device.fingerprint;
|
|
111
|
+
const embedUrl = data.device.embed_url;
|
|
112
|
+
console.log(` Your API Key: ${keyPreview}`);
|
|
113
|
+
console.log(` Device ID: ${fingerprint}`);
|
|
114
|
+
console.log(` Embed URL: ${embedUrl}`);
|
|
115
|
+
console.log("");
|
|
116
|
+
console.log(" API key saved to .env");
|
|
117
|
+
console.log("");
|
|
118
|
+
console.log(" Quick integration:");
|
|
119
|
+
console.log("");
|
|
120
|
+
console.log(" // Node.js / server");
|
|
121
|
+
console.log(" import { PartnerClient } from '@trillboards/ads-sdk/server';");
|
|
122
|
+
console.log(" const client = new PartnerClient(); // reads from TRILLBOARDS_API_KEY");
|
|
123
|
+
console.log("");
|
|
124
|
+
console.log(" // Browser \u2014 paste in your HTML");
|
|
125
|
+
console.log(` <iframe src="${embedUrl}" style="width:100%;height:100%;border:none;" allow="autoplay; fullscreen" allowfullscreen></iframe>`);
|
|
126
|
+
console.log("");
|
|
127
|
+
console.log(" Next steps:");
|
|
128
|
+
console.log(" 1. Register more devices: POST /v1/partner/device");
|
|
129
|
+
console.log(" 2. Connect Stripe for payouts: POST /v1/partner/stripe/connect");
|
|
130
|
+
console.log(" 3. Read the docs: https://trillboards.com/developers");
|
|
131
|
+
console.log("");
|
|
132
|
+
completed = true;
|
|
133
|
+
} catch (err) {
|
|
134
|
+
console.error(`
|
|
135
|
+
Error: ${err.message}
|
|
136
|
+
`);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
} finally {
|
|
139
|
+
rl.close();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
var args = process.argv.slice(2);
|
|
143
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
144
|
+
console.log(SDK_VERSION);
|
|
145
|
+
process.exit(0);
|
|
146
|
+
}
|
|
147
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
148
|
+
console.log(`
|
|
149
|
+
@trillboards/ads-sdk v${SDK_VERSION}
|
|
150
|
+
|
|
151
|
+
Usage:
|
|
152
|
+
npx @trillboards/ads-sdk init Register and set up your first device
|
|
153
|
+
npx @trillboards/ads-sdk --version
|
|
154
|
+
npx @trillboards/ads-sdk --help
|
|
155
|
+
`);
|
|
156
|
+
process.exit(0);
|
|
157
|
+
}
|
|
158
|
+
runInit();
|
package/dist/index.d.mts
CHANGED
|
@@ -13,6 +13,7 @@ interface TrillboardsConfig {
|
|
|
13
13
|
programmaticRetry?: number;
|
|
14
14
|
programmaticBackoffMax?: number;
|
|
15
15
|
cacheSize?: number;
|
|
16
|
+
debug?: boolean;
|
|
16
17
|
}
|
|
17
18
|
type WaterfallMode = 'programmatic_only' | 'programmatic_then_direct' | 'direct_only';
|
|
18
19
|
interface AdItem {
|
|
@@ -316,7 +317,7 @@ declare class EventEmitter {
|
|
|
316
317
|
}
|
|
317
318
|
|
|
318
319
|
/** Single source of truth for the SDK version string. */
|
|
319
|
-
declare const SDK_VERSION = "2.
|
|
320
|
+
declare const SDK_VERSION = "2.1.1";
|
|
320
321
|
/**
|
|
321
322
|
* Compile-time constants that mirror the original IIFE CONFIG
|
|
322
323
|
* object. Every value here acts as a sensible production default
|
|
@@ -335,7 +336,7 @@ declare const DEFAULT_CONFIG: {
|
|
|
335
336
|
readonly PROGRAMMATIC_MIN_INTERVAL_MS: 5000;
|
|
336
337
|
readonly PROGRAMMATIC_RETRY_MS: 5000;
|
|
337
338
|
readonly PROGRAMMATIC_BACKOFF_MAX_MS: number;
|
|
338
|
-
readonly VERSION: "2.
|
|
339
|
+
readonly VERSION: "2.1.1";
|
|
339
340
|
};
|
|
340
341
|
/**
|
|
341
342
|
* Merge a caller-supplied TrillboardsConfig with the defaults,
|
|
@@ -360,6 +361,7 @@ declare function resolveConfig(userConfig: TrillboardsConfig): {
|
|
|
360
361
|
readonly programmaticRetry: number;
|
|
361
362
|
readonly programmaticBackoffMax: number;
|
|
362
363
|
readonly cacheSize: number;
|
|
364
|
+
readonly debug: boolean;
|
|
363
365
|
};
|
|
364
366
|
|
|
365
367
|
/**
|
|
@@ -599,4 +601,55 @@ declare class ApiClient {
|
|
|
599
601
|
}): Promise<boolean>;
|
|
600
602
|
}
|
|
601
603
|
|
|
602
|
-
|
|
604
|
+
/**
|
|
605
|
+
* Base error class for all Trillboards SDK errors.
|
|
606
|
+
* Mirrors the API error response shape: `{ type, code, message, param, help }`.
|
|
607
|
+
*/
|
|
608
|
+
declare class TrillboardsError extends Error {
|
|
609
|
+
readonly type: string;
|
|
610
|
+
readonly code: string;
|
|
611
|
+
readonly statusCode: number;
|
|
612
|
+
readonly help?: string;
|
|
613
|
+
readonly param?: string;
|
|
614
|
+
constructor(message: string, options?: {
|
|
615
|
+
type?: string;
|
|
616
|
+
code?: string;
|
|
617
|
+
statusCode?: number;
|
|
618
|
+
help?: string;
|
|
619
|
+
param?: string;
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
/** Thrown on HTTP 401 — invalid or missing API key. */
|
|
623
|
+
declare class TrillboardsAuthenticationError extends TrillboardsError {
|
|
624
|
+
constructor(message?: string);
|
|
625
|
+
}
|
|
626
|
+
/** Thrown on HTTP 429 — rate limit exceeded. */
|
|
627
|
+
declare class TrillboardsRateLimitError extends TrillboardsError {
|
|
628
|
+
readonly retryAfter: number;
|
|
629
|
+
constructor(retryAfter: number, message?: string);
|
|
630
|
+
}
|
|
631
|
+
/** Thrown on HTTP 404 — resource not found. */
|
|
632
|
+
declare class TrillboardsNotFoundError extends TrillboardsError {
|
|
633
|
+
constructor(message?: string);
|
|
634
|
+
}
|
|
635
|
+
/** Thrown on HTTP 400 — validation / bad request. */
|
|
636
|
+
declare class TrillboardsValidationError extends TrillboardsError {
|
|
637
|
+
constructor(message?: string, param?: string);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
641
|
+
declare class Logger {
|
|
642
|
+
private level;
|
|
643
|
+
setLevel(level: LogLevel): void;
|
|
644
|
+
getLevel(): LogLevel;
|
|
645
|
+
debug(message: string, data?: unknown): void;
|
|
646
|
+
info(message: string, data?: unknown): void;
|
|
647
|
+
warn(message: string, data?: unknown): void;
|
|
648
|
+
error(message: string, data?: unknown): void;
|
|
649
|
+
}
|
|
650
|
+
/** Singleton logger instance shared across the SDK. */
|
|
651
|
+
declare const logger: Logger;
|
|
652
|
+
/** Set the global log level for the SDK. */
|
|
653
|
+
declare function setLogLevel(level: LogLevel): void;
|
|
654
|
+
|
|
655
|
+
export { type AdItem, ApiClient, type AuctionWinner, type BridgeConfig, type BridgePayload, type BridgeType, CircuitBreaker, type CircuitBreakerState, DEFAULT_CONFIG, DEFAULT_PUBLIC_STATE, EventEmitter, type EventMap, type FetchAdsResult, type ImpressionData, type LogLevel, type PlayerTruth, type ProgrammaticSettings, SDK_VERSION, type ScreenDimensions, Telemetry, type TelemetrySnapshot, TrillboardsAds, TrillboardsAuthenticationError, type TrillboardsConfig, TrillboardsError, TrillboardsNotFoundError, TrillboardsRateLimitError, type TrillboardsState, TrillboardsValidationError, type VastSource, WaterfallEngine, type WaterfallMode, createInitialState, getPublicState, logger, resolveConfig, setLogLevel };
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ interface TrillboardsConfig {
|
|
|
13
13
|
programmaticRetry?: number;
|
|
14
14
|
programmaticBackoffMax?: number;
|
|
15
15
|
cacheSize?: number;
|
|
16
|
+
debug?: boolean;
|
|
16
17
|
}
|
|
17
18
|
type WaterfallMode = 'programmatic_only' | 'programmatic_then_direct' | 'direct_only';
|
|
18
19
|
interface AdItem {
|
|
@@ -316,7 +317,7 @@ declare class EventEmitter {
|
|
|
316
317
|
}
|
|
317
318
|
|
|
318
319
|
/** Single source of truth for the SDK version string. */
|
|
319
|
-
declare const SDK_VERSION = "2.
|
|
320
|
+
declare const SDK_VERSION = "2.1.1";
|
|
320
321
|
/**
|
|
321
322
|
* Compile-time constants that mirror the original IIFE CONFIG
|
|
322
323
|
* object. Every value here acts as a sensible production default
|
|
@@ -335,7 +336,7 @@ declare const DEFAULT_CONFIG: {
|
|
|
335
336
|
readonly PROGRAMMATIC_MIN_INTERVAL_MS: 5000;
|
|
336
337
|
readonly PROGRAMMATIC_RETRY_MS: 5000;
|
|
337
338
|
readonly PROGRAMMATIC_BACKOFF_MAX_MS: number;
|
|
338
|
-
readonly VERSION: "2.
|
|
339
|
+
readonly VERSION: "2.1.1";
|
|
339
340
|
};
|
|
340
341
|
/**
|
|
341
342
|
* Merge a caller-supplied TrillboardsConfig with the defaults,
|
|
@@ -360,6 +361,7 @@ declare function resolveConfig(userConfig: TrillboardsConfig): {
|
|
|
360
361
|
readonly programmaticRetry: number;
|
|
361
362
|
readonly programmaticBackoffMax: number;
|
|
362
363
|
readonly cacheSize: number;
|
|
364
|
+
readonly debug: boolean;
|
|
363
365
|
};
|
|
364
366
|
|
|
365
367
|
/**
|
|
@@ -599,4 +601,55 @@ declare class ApiClient {
|
|
|
599
601
|
}): Promise<boolean>;
|
|
600
602
|
}
|
|
601
603
|
|
|
602
|
-
|
|
604
|
+
/**
|
|
605
|
+
* Base error class for all Trillboards SDK errors.
|
|
606
|
+
* Mirrors the API error response shape: `{ type, code, message, param, help }`.
|
|
607
|
+
*/
|
|
608
|
+
declare class TrillboardsError extends Error {
|
|
609
|
+
readonly type: string;
|
|
610
|
+
readonly code: string;
|
|
611
|
+
readonly statusCode: number;
|
|
612
|
+
readonly help?: string;
|
|
613
|
+
readonly param?: string;
|
|
614
|
+
constructor(message: string, options?: {
|
|
615
|
+
type?: string;
|
|
616
|
+
code?: string;
|
|
617
|
+
statusCode?: number;
|
|
618
|
+
help?: string;
|
|
619
|
+
param?: string;
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
/** Thrown on HTTP 401 — invalid or missing API key. */
|
|
623
|
+
declare class TrillboardsAuthenticationError extends TrillboardsError {
|
|
624
|
+
constructor(message?: string);
|
|
625
|
+
}
|
|
626
|
+
/** Thrown on HTTP 429 — rate limit exceeded. */
|
|
627
|
+
declare class TrillboardsRateLimitError extends TrillboardsError {
|
|
628
|
+
readonly retryAfter: number;
|
|
629
|
+
constructor(retryAfter: number, message?: string);
|
|
630
|
+
}
|
|
631
|
+
/** Thrown on HTTP 404 — resource not found. */
|
|
632
|
+
declare class TrillboardsNotFoundError extends TrillboardsError {
|
|
633
|
+
constructor(message?: string);
|
|
634
|
+
}
|
|
635
|
+
/** Thrown on HTTP 400 — validation / bad request. */
|
|
636
|
+
declare class TrillboardsValidationError extends TrillboardsError {
|
|
637
|
+
constructor(message?: string, param?: string);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
641
|
+
declare class Logger {
|
|
642
|
+
private level;
|
|
643
|
+
setLevel(level: LogLevel): void;
|
|
644
|
+
getLevel(): LogLevel;
|
|
645
|
+
debug(message: string, data?: unknown): void;
|
|
646
|
+
info(message: string, data?: unknown): void;
|
|
647
|
+
warn(message: string, data?: unknown): void;
|
|
648
|
+
error(message: string, data?: unknown): void;
|
|
649
|
+
}
|
|
650
|
+
/** Singleton logger instance shared across the SDK. */
|
|
651
|
+
declare const logger: Logger;
|
|
652
|
+
/** Set the global log level for the SDK. */
|
|
653
|
+
declare function setLogLevel(level: LogLevel): void;
|
|
654
|
+
|
|
655
|
+
export { type AdItem, ApiClient, type AuctionWinner, type BridgeConfig, type BridgePayload, type BridgeType, CircuitBreaker, type CircuitBreakerState, DEFAULT_CONFIG, DEFAULT_PUBLIC_STATE, EventEmitter, type EventMap, type FetchAdsResult, type ImpressionData, type LogLevel, type PlayerTruth, type ProgrammaticSettings, SDK_VERSION, type ScreenDimensions, Telemetry, type TelemetrySnapshot, TrillboardsAds, TrillboardsAuthenticationError, type TrillboardsConfig, TrillboardsError, TrillboardsNotFoundError, TrillboardsRateLimitError, type TrillboardsState, TrillboardsValidationError, type VastSource, WaterfallEngine, type WaterfallMode, createInitialState, getPublicState, logger, resolveConfig, setLogLevel };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/core/config.ts
|
|
4
|
-
var SDK_VERSION = "2.
|
|
4
|
+
var SDK_VERSION = "2.1.1";
|
|
5
5
|
var DEFAULT_CONFIG = {
|
|
6
6
|
API_BASE: "https://api.trillboards.com/v1/partner",
|
|
7
7
|
CDN_BASE: "https://cdn.trillboards.com",
|
|
@@ -44,7 +44,8 @@ function resolveConfig(userConfig) {
|
|
|
44
44
|
programmaticMinInterval: Math.max(userConfig.programmaticMinInterval ?? DEFAULT_CONFIG.PROGRAMMATIC_MIN_INTERVAL_MS, 1e3),
|
|
45
45
|
programmaticRetry: Math.max(userConfig.programmaticRetry ?? DEFAULT_CONFIG.PROGRAMMATIC_RETRY_MS, 1e3),
|
|
46
46
|
programmaticBackoffMax: Math.max(userConfig.programmaticBackoffMax ?? DEFAULT_CONFIG.PROGRAMMATIC_BACKOFF_MAX_MS, 5e3),
|
|
47
|
-
cacheSize: Math.max(userConfig.cacheSize ?? DEFAULT_CONFIG.CACHE_SIZE, 1)
|
|
47
|
+
cacheSize: Math.max(userConfig.cacheSize ?? DEFAULT_CONFIG.CACHE_SIZE, 1),
|
|
48
|
+
debug: userConfig.debug ?? false
|
|
48
49
|
};
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -171,6 +172,67 @@ var EventEmitter = class {
|
|
|
171
172
|
}
|
|
172
173
|
};
|
|
173
174
|
|
|
175
|
+
// src/logger.ts
|
|
176
|
+
var LEVEL_PRIORITY = {
|
|
177
|
+
debug: 0,
|
|
178
|
+
info: 1,
|
|
179
|
+
warn: 2,
|
|
180
|
+
error: 3,
|
|
181
|
+
none: 4
|
|
182
|
+
};
|
|
183
|
+
var PREFIX = "[Trillboards]";
|
|
184
|
+
var Logger = class {
|
|
185
|
+
constructor() {
|
|
186
|
+
this.level = "none";
|
|
187
|
+
}
|
|
188
|
+
setLevel(level) {
|
|
189
|
+
this.level = level;
|
|
190
|
+
}
|
|
191
|
+
getLevel() {
|
|
192
|
+
return this.level;
|
|
193
|
+
}
|
|
194
|
+
debug(message, data) {
|
|
195
|
+
if (LEVEL_PRIORITY[this.level] <= LEVEL_PRIORITY.debug) {
|
|
196
|
+
if (data !== void 0) {
|
|
197
|
+
console.debug(PREFIX, message, data);
|
|
198
|
+
} else {
|
|
199
|
+
console.debug(PREFIX, message);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
info(message, data) {
|
|
204
|
+
if (LEVEL_PRIORITY[this.level] <= LEVEL_PRIORITY.info) {
|
|
205
|
+
if (data !== void 0) {
|
|
206
|
+
console.info(PREFIX, message, data);
|
|
207
|
+
} else {
|
|
208
|
+
console.info(PREFIX, message);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
warn(message, data) {
|
|
213
|
+
if (LEVEL_PRIORITY[this.level] <= LEVEL_PRIORITY.warn) {
|
|
214
|
+
if (data !== void 0) {
|
|
215
|
+
console.warn(PREFIX, message, data);
|
|
216
|
+
} else {
|
|
217
|
+
console.warn(PREFIX, message);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
error(message, data) {
|
|
222
|
+
if (LEVEL_PRIORITY[this.level] <= LEVEL_PRIORITY.error) {
|
|
223
|
+
if (data !== void 0) {
|
|
224
|
+
console.error(PREFIX, message, data);
|
|
225
|
+
} else {
|
|
226
|
+
console.error(PREFIX, message);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
var logger = new Logger();
|
|
232
|
+
function setLogLevel(level) {
|
|
233
|
+
logger.setLevel(level);
|
|
234
|
+
}
|
|
235
|
+
|
|
174
236
|
// src/api/client.ts
|
|
175
237
|
function getPlayerTruth(container) {
|
|
176
238
|
if (typeof window === "undefined") {
|
|
@@ -220,6 +282,7 @@ var ApiClient = class {
|
|
|
220
282
|
* The request is aborted after 10 seconds.
|
|
221
283
|
*/
|
|
222
284
|
async fetchAds(deviceId, etag = null) {
|
|
285
|
+
logger.debug("Fetching ads", { deviceId });
|
|
223
286
|
const headers = { Accept: "application/json" };
|
|
224
287
|
if (etag) headers["If-None-Match"] = etag;
|
|
225
288
|
const controller = new AbortController();
|
|
@@ -254,7 +317,7 @@ var ApiClient = class {
|
|
|
254
317
|
}
|
|
255
318
|
const data = await response.json();
|
|
256
319
|
const newEtag = response.headers.get("ETag");
|
|
257
|
-
|
|
320
|
+
const result = {
|
|
258
321
|
ads: data.data?.ads ?? [],
|
|
259
322
|
settings: data.data?.settings ?? {},
|
|
260
323
|
programmatic: data.data?.header_bidding_settings ?? null,
|
|
@@ -264,6 +327,8 @@ var ApiClient = class {
|
|
|
264
327
|
etag: newEtag,
|
|
265
328
|
notModified: false
|
|
266
329
|
};
|
|
330
|
+
logger.debug("Ads fetched", { deviceId, count: result.ads.length, notModified: false });
|
|
331
|
+
return result;
|
|
267
332
|
} catch (error) {
|
|
268
333
|
clearTimeout(timeoutId);
|
|
269
334
|
throw error;
|
|
@@ -279,6 +344,7 @@ var ApiClient = class {
|
|
|
279
344
|
* Returns `true` if the server acknowledged the impression.
|
|
280
345
|
*/
|
|
281
346
|
async reportImpression(impression) {
|
|
347
|
+
logger.debug("Reporting impression", { adId: impression.adid, impressionId: impression.impid });
|
|
282
348
|
try {
|
|
283
349
|
const params = new URLSearchParams({
|
|
284
350
|
adid: impression.adid,
|
|
@@ -302,6 +368,7 @@ var ApiClient = class {
|
|
|
302
368
|
* Returns `true` on 2xx, `false` on any error.
|
|
303
369
|
*/
|
|
304
370
|
async sendHeartbeat(deviceId, screenId) {
|
|
371
|
+
logger.debug("Sending heartbeat", { deviceId });
|
|
305
372
|
try {
|
|
306
373
|
const response = await fetch(`${this.apiBase}/device/${deviceId}/heartbeat`, {
|
|
307
374
|
method: "POST",
|
|
@@ -324,6 +391,7 @@ var ApiClient = class {
|
|
|
324
391
|
* error, etc.) to the analytics backend.
|
|
325
392
|
*/
|
|
326
393
|
async reportProgrammaticEvent(event) {
|
|
394
|
+
logger.debug("Reporting programmatic event", { eventType: event.eventType });
|
|
327
395
|
try {
|
|
328
396
|
const response = await fetch(`${this.apiBase}/programmatic-event`, {
|
|
329
397
|
method: "POST",
|
|
@@ -1332,6 +1400,9 @@ var _TrillboardsAds = class _TrillboardsAds {
|
|
|
1332
1400
|
this.offlineHandler = null;
|
|
1333
1401
|
this.visibilityHandler = null;
|
|
1334
1402
|
this.config = resolveConfig(config);
|
|
1403
|
+
if (this.config.debug) {
|
|
1404
|
+
setLogLevel("debug");
|
|
1405
|
+
}
|
|
1335
1406
|
this.state = createInitialState();
|
|
1336
1407
|
this.events = new EventEmitter();
|
|
1337
1408
|
this.api = new ApiClient(this.config.apiBase);
|
|
@@ -1736,6 +1807,76 @@ var _TrillboardsAds = class _TrillboardsAds {
|
|
|
1736
1807
|
_TrillboardsAds._instance = null;
|
|
1737
1808
|
var TrillboardsAds = _TrillboardsAds;
|
|
1738
1809
|
|
|
1810
|
+
// src/errors.ts
|
|
1811
|
+
var TrillboardsError = class extends Error {
|
|
1812
|
+
constructor(message, options = {}) {
|
|
1813
|
+
super(message);
|
|
1814
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
1815
|
+
this.name = "TrillboardsError";
|
|
1816
|
+
this.type = options.type ?? "api_error";
|
|
1817
|
+
this.code = options.code ?? "unknown_error";
|
|
1818
|
+
this.statusCode = options.statusCode ?? 500;
|
|
1819
|
+
this.help = options.help;
|
|
1820
|
+
this.param = options.param;
|
|
1821
|
+
}
|
|
1822
|
+
};
|
|
1823
|
+
var TrillboardsAuthenticationError = class extends TrillboardsError {
|
|
1824
|
+
constructor(message) {
|
|
1825
|
+
super(
|
|
1826
|
+
message ?? "Invalid API key. Check your key at https://trillboards.com/developers",
|
|
1827
|
+
{
|
|
1828
|
+
type: "authentication_error",
|
|
1829
|
+
code: "invalid_api_key",
|
|
1830
|
+
statusCode: 401,
|
|
1831
|
+
help: "https://trillboards.com/developers"
|
|
1832
|
+
}
|
|
1833
|
+
);
|
|
1834
|
+
this.name = "TrillboardsAuthenticationError";
|
|
1835
|
+
}
|
|
1836
|
+
};
|
|
1837
|
+
var TrillboardsRateLimitError = class extends TrillboardsError {
|
|
1838
|
+
constructor(retryAfter, message) {
|
|
1839
|
+
super(
|
|
1840
|
+
message ?? `Rate limit exceeded. Retry after ${retryAfter} seconds.`,
|
|
1841
|
+
{
|
|
1842
|
+
type: "rate_limit_error",
|
|
1843
|
+
code: "rate_limited",
|
|
1844
|
+
statusCode: 429
|
|
1845
|
+
}
|
|
1846
|
+
);
|
|
1847
|
+
this.name = "TrillboardsRateLimitError";
|
|
1848
|
+
this.retryAfter = retryAfter;
|
|
1849
|
+
}
|
|
1850
|
+
};
|
|
1851
|
+
var TrillboardsNotFoundError = class extends TrillboardsError {
|
|
1852
|
+
constructor(message) {
|
|
1853
|
+
super(
|
|
1854
|
+
message ?? "The requested resource was not found.",
|
|
1855
|
+
{
|
|
1856
|
+
type: "not_found_error",
|
|
1857
|
+
code: "resource_not_found",
|
|
1858
|
+
statusCode: 404,
|
|
1859
|
+
help: "Verify the ID is correct and belongs to your account."
|
|
1860
|
+
}
|
|
1861
|
+
);
|
|
1862
|
+
this.name = "TrillboardsNotFoundError";
|
|
1863
|
+
}
|
|
1864
|
+
};
|
|
1865
|
+
var TrillboardsValidationError = class extends TrillboardsError {
|
|
1866
|
+
constructor(message, param) {
|
|
1867
|
+
super(
|
|
1868
|
+
message ?? "The request was invalid.",
|
|
1869
|
+
{
|
|
1870
|
+
type: "validation_error",
|
|
1871
|
+
code: "invalid_request",
|
|
1872
|
+
statusCode: 400,
|
|
1873
|
+
param
|
|
1874
|
+
}
|
|
1875
|
+
);
|
|
1876
|
+
this.name = "TrillboardsValidationError";
|
|
1877
|
+
}
|
|
1878
|
+
};
|
|
1879
|
+
|
|
1739
1880
|
exports.ApiClient = ApiClient;
|
|
1740
1881
|
exports.CircuitBreaker = CircuitBreaker;
|
|
1741
1882
|
exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
|
|
@@ -1744,9 +1885,16 @@ exports.EventEmitter = EventEmitter;
|
|
|
1744
1885
|
exports.SDK_VERSION = SDK_VERSION;
|
|
1745
1886
|
exports.Telemetry = Telemetry;
|
|
1746
1887
|
exports.TrillboardsAds = TrillboardsAds;
|
|
1888
|
+
exports.TrillboardsAuthenticationError = TrillboardsAuthenticationError;
|
|
1889
|
+
exports.TrillboardsError = TrillboardsError;
|
|
1890
|
+
exports.TrillboardsNotFoundError = TrillboardsNotFoundError;
|
|
1891
|
+
exports.TrillboardsRateLimitError = TrillboardsRateLimitError;
|
|
1892
|
+
exports.TrillboardsValidationError = TrillboardsValidationError;
|
|
1747
1893
|
exports.WaterfallEngine = WaterfallEngine;
|
|
1748
1894
|
exports.createInitialState = createInitialState;
|
|
1749
1895
|
exports.getPublicState = getPublicState;
|
|
1896
|
+
exports.logger = logger;
|
|
1750
1897
|
exports.resolveConfig = resolveConfig;
|
|
1898
|
+
exports.setLogLevel = setLogLevel;
|
|
1751
1899
|
//# sourceMappingURL=index.js.map
|
|
1752
1900
|
//# sourceMappingURL=index.js.map
|