@traceten/sdk-node 1.0.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/CHANGELOG.md +23 -0
- package/LICENSE +21 -0
- package/README.md +312 -0
- package/dist/client.d.ts +107 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +320 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/queue.d.ts +72 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +232 -0
- package/dist/queue.js.map +1 -0
- package/dist/types.d.ts +212 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +99 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +323 -0
- package/dist/validate.js.map +1 -0
- package/dist/webhook.d.ts +203 -0
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +141 -0
- package/dist/webhook.js.map +1 -0
- package/package.json +72 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The buffered Traceten client.
|
|
3
|
+
*
|
|
4
|
+
* `page()` and `track()` split at the API surface (two endpoints, two payload
|
|
5
|
+
* shapes) but unify in one buffered client with a single flush that drains both
|
|
6
|
+
* internal queues. See DESIGN.md §3–§4.
|
|
7
|
+
*/
|
|
8
|
+
import { Transport, chunk } from "./queue.js";
|
|
9
|
+
import { normalizeCurrency, normalizeHost, toIsoTimestamp, validateConversionName, validateConversionSessionId, validateEventName, validateEventSessionId, validateGoalName, validateReferrer, validateAmount, validateApiKey, validateProvider, validateSiteId, validateTransactionId, normalizePaymentCurrency, validateUrl, validateUserAgent, validateValueCents, validateVisitorId, } from "./validate.js";
|
|
10
|
+
const DEFAULT_FLUSH_AT = 50;
|
|
11
|
+
const MAX_FLUSH_AT = 50;
|
|
12
|
+
const MIN_FLUSH_AT = 1;
|
|
13
|
+
const DEFAULT_FLUSH_INTERVAL_MS = 5000;
|
|
14
|
+
const DEFAULT_MAX_RETRIES = 3;
|
|
15
|
+
const DEFAULT_TIMEOUT_MS = 10000;
|
|
16
|
+
/** Node process signals we install best-effort flush handlers for. */
|
|
17
|
+
const EXIT_SIGNALS = ["SIGTERM", "SIGINT"];
|
|
18
|
+
function clamp(value, min, max) {
|
|
19
|
+
return Math.min(max, Math.max(min, value));
|
|
20
|
+
}
|
|
21
|
+
/** Validate an optional positive-number config field. */
|
|
22
|
+
function positiveOr(value, fallback, name) {
|
|
23
|
+
if (value === undefined)
|
|
24
|
+
return fallback;
|
|
25
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
26
|
+
throw new TypeError(`Traceten: ${name} must be a positive number`);
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
export class Client {
|
|
31
|
+
siteId;
|
|
32
|
+
host;
|
|
33
|
+
flushAt;
|
|
34
|
+
transport;
|
|
35
|
+
onError;
|
|
36
|
+
events = [];
|
|
37
|
+
conversions = [];
|
|
38
|
+
timer;
|
|
39
|
+
inflight = new Set();
|
|
40
|
+
exitHooks = [];
|
|
41
|
+
closed = false;
|
|
42
|
+
constructor(options) {
|
|
43
|
+
if (options === null || typeof options !== "object") {
|
|
44
|
+
throw new TypeError("Traceten: Client requires an options object");
|
|
45
|
+
}
|
|
46
|
+
this.siteId = validateSiteId(options.siteId);
|
|
47
|
+
this.host = normalizeHost(options.host);
|
|
48
|
+
// Validated BEFORE anything else is set up: an integration missing its key
|
|
49
|
+
// would otherwise start, buffer, flush, and 401 every batch forever while
|
|
50
|
+
// looking perfectly healthy from the outside.
|
|
51
|
+
const apiKey = validateApiKey(options.apiKey);
|
|
52
|
+
this.flushAt = clamp(options.flushAt ?? DEFAULT_FLUSH_AT, MIN_FLUSH_AT, MAX_FLUSH_AT);
|
|
53
|
+
this.onError = options.onError ?? (() => undefined);
|
|
54
|
+
const flushInterval = positiveOr(options.flushInterval, DEFAULT_FLUSH_INTERVAL_MS, "flushInterval");
|
|
55
|
+
const maxRetries = options.maxRetries === undefined
|
|
56
|
+
? DEFAULT_MAX_RETRIES
|
|
57
|
+
: (() => {
|
|
58
|
+
if (typeof options.maxRetries !== "number" ||
|
|
59
|
+
!Number.isInteger(options.maxRetries) ||
|
|
60
|
+
options.maxRetries < 0) {
|
|
61
|
+
throw new TypeError("Traceten: maxRetries must be a non-negative integer");
|
|
62
|
+
}
|
|
63
|
+
return options.maxRetries;
|
|
64
|
+
})();
|
|
65
|
+
const timeoutMs = positiveOr(options.timeoutMs, DEFAULT_TIMEOUT_MS, "timeoutMs");
|
|
66
|
+
this.transport = new Transport({
|
|
67
|
+
host: this.host,
|
|
68
|
+
apiKey,
|
|
69
|
+
maxRetries,
|
|
70
|
+
timeoutMs,
|
|
71
|
+
onError: this.onError,
|
|
72
|
+
});
|
|
73
|
+
// Background flush timer — unref'd so it never keeps the process alive.
|
|
74
|
+
this.timer = setInterval(() => {
|
|
75
|
+
void this.flush();
|
|
76
|
+
}, flushInterval);
|
|
77
|
+
this.timer.unref();
|
|
78
|
+
if (options.flushOnExit ?? true) {
|
|
79
|
+
this.registerExitHooks();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Enqueue a pageview (`/v1/server/events`). Returns immediately; never throws on
|
|
84
|
+
* network problems. Throws synchronously on programmer errors (bad url,
|
|
85
|
+
* bad eventName, bad visitorId).
|
|
86
|
+
*/
|
|
87
|
+
page(props) {
|
|
88
|
+
this.assertOpen();
|
|
89
|
+
if (props === null || typeof props !== "object") {
|
|
90
|
+
throw new TypeError("Traceten: page() requires a props object");
|
|
91
|
+
}
|
|
92
|
+
const url = validateUrl(props.url);
|
|
93
|
+
const eventName = validateEventName(props.eventName ?? "pageview");
|
|
94
|
+
const referrer = validateReferrer(props.referrer ?? "");
|
|
95
|
+
const ts = toIsoTimestamp(props.timestamp);
|
|
96
|
+
const event = { siteId: this.siteId, ts, url, referrer, eventName };
|
|
97
|
+
if (props.sessionId !== undefined) {
|
|
98
|
+
event.sessionId = validateEventSessionId(props.sessionId);
|
|
99
|
+
}
|
|
100
|
+
if (props.visitorId !== undefined) {
|
|
101
|
+
event.vid = validateVisitorId(props.visitorId);
|
|
102
|
+
}
|
|
103
|
+
if (props.userAgent !== undefined) {
|
|
104
|
+
event.ua = validateUserAgent(props.userAgent);
|
|
105
|
+
}
|
|
106
|
+
this.events.push(event);
|
|
107
|
+
this.maybeFlush();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Enqueue a conversion (`/v1/server/conversions`). `opts.visitorId` is REQUIRED —
|
|
111
|
+
* omitting it is a programmer error and throws synchronously (a conversion
|
|
112
|
+
* cannot be attributed without it). Returns immediately otherwise.
|
|
113
|
+
*/
|
|
114
|
+
track(name, opts) {
|
|
115
|
+
this.assertOpen();
|
|
116
|
+
const eventName = validateConversionName(name);
|
|
117
|
+
if (opts === null || typeof opts !== "object") {
|
|
118
|
+
throw new TypeError("Traceten: track() requires an options object with a visitorId");
|
|
119
|
+
}
|
|
120
|
+
if (opts.visitorId === undefined) {
|
|
121
|
+
throw new TypeError("Traceten: track() requires opts.visitorId — conversions cannot attribute without it");
|
|
122
|
+
}
|
|
123
|
+
const visitorId = validateVisitorId(opts.visitorId);
|
|
124
|
+
const timestamp = toIsoTimestamp(opts.timestamp);
|
|
125
|
+
const conversion = {
|
|
126
|
+
event_name: eventName,
|
|
127
|
+
site_id: this.siteId,
|
|
128
|
+
timestamp,
|
|
129
|
+
visitor_id: visitorId,
|
|
130
|
+
properties: opts.properties ?? {},
|
|
131
|
+
};
|
|
132
|
+
if (opts.sessionId !== undefined) {
|
|
133
|
+
conversion.session_id = validateConversionSessionId(opts.sessionId);
|
|
134
|
+
}
|
|
135
|
+
if (opts.valueCents !== undefined) {
|
|
136
|
+
conversion.value_cents = validateValueCents(opts.valueCents);
|
|
137
|
+
}
|
|
138
|
+
if (opts.currency !== undefined) {
|
|
139
|
+
conversion.currency = normalizeCurrency(opts.currency);
|
|
140
|
+
}
|
|
141
|
+
this.conversions.push(conversion);
|
|
142
|
+
this.maybeFlush();
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Enqueue a goal completion. Identical to {@link Client.track} in every
|
|
146
|
+
* respect except the name check: the reserved Stripe/Shopify names are
|
|
147
|
+
* refused, because a goal that collides with one silently corrupts the site's
|
|
148
|
+
* revenue funnel.
|
|
149
|
+
*
|
|
150
|
+
* A goal IS a custom event — this is the same `/v1/server/conversions` call
|
|
151
|
+
* under a name that matches what the dashboard calls it.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```ts
|
|
155
|
+
* traceten.goal("demo_booked", { visitorId, properties: { plan: "pro" } });
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
goal(name, opts) {
|
|
159
|
+
this.track(validateGoalName(name), opts);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Record a payment from ANY payment processor (`POST /v1/server/payments`).
|
|
163
|
+
*
|
|
164
|
+
* ⚠️ The only method here that is AWAITED and that can reject. `page()` and
|
|
165
|
+
* `track()` are buffered and fire-and-forget because a lost pageview is a lost
|
|
166
|
+
* pageview; a lost payment is missing revenue, and the endpoint's whole point
|
|
167
|
+
* is the idempotency answer it returns — which a queue could not give back.
|
|
168
|
+
*
|
|
169
|
+
* Safe to call again with the same `transactionId`: the server deduplicates
|
|
170
|
+
* durably on `(site, provider, transactionId)` and answers `"duplicate"`
|
|
171
|
+
* rather than recording a second payment.
|
|
172
|
+
*
|
|
173
|
+
* `settlementAmount`/`settlementCurrency` are an optional fallback: your
|
|
174
|
+
* processor's own conversion of the payment into a currency Traceten can
|
|
175
|
+
* price, used only when `currency` itself isn't one Traceten prices
|
|
176
|
+
* natively. Set both or neither — one without the other is dropped.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```ts
|
|
180
|
+
* const res = await traceten.payment({
|
|
181
|
+
* transactionId: charge.id,
|
|
182
|
+
* amount: 49.99,
|
|
183
|
+
* currency: "USD",
|
|
184
|
+
* provider: "dodo",
|
|
185
|
+
* email: customer.email,
|
|
186
|
+
* });
|
|
187
|
+
* // res.status === "recorded"
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
async payment(props) {
|
|
191
|
+
this.assertOpen();
|
|
192
|
+
if (props === null || typeof props !== "object") {
|
|
193
|
+
throw new TypeError("Traceten: payment() requires a props object");
|
|
194
|
+
}
|
|
195
|
+
const payment = {
|
|
196
|
+
site_id: this.siteId,
|
|
197
|
+
transaction_id: validateTransactionId(props.transactionId),
|
|
198
|
+
amount: validateAmount(props.amount),
|
|
199
|
+
currency: normalizePaymentCurrency(props.currency),
|
|
200
|
+
};
|
|
201
|
+
if (props.provider !== undefined)
|
|
202
|
+
payment.provider = validateProvider(props.provider);
|
|
203
|
+
if (props.visitorId !== undefined)
|
|
204
|
+
payment.visitor_id = validateVisitorId(props.visitorId);
|
|
205
|
+
if (props.email !== undefined)
|
|
206
|
+
payment.email = props.email;
|
|
207
|
+
if (props.customerId !== undefined)
|
|
208
|
+
payment.customer_id = props.customerId;
|
|
209
|
+
if (props.renewal !== undefined)
|
|
210
|
+
payment.renewal = props.renewal;
|
|
211
|
+
if (props.refunded !== undefined)
|
|
212
|
+
payment.refunded = props.refunded;
|
|
213
|
+
if (props.isFreeTrial !== undefined)
|
|
214
|
+
payment.is_free_trial = props.isFreeTrial;
|
|
215
|
+
if (props.timestamp !== undefined)
|
|
216
|
+
payment.timestamp = toIsoTimestamp(props.timestamp);
|
|
217
|
+
// Fallback fields — never sent unless BOTH are present. One without the
|
|
218
|
+
// other is not a valid settlement figure and the server would reject it.
|
|
219
|
+
if (props.settlementAmount !== undefined && props.settlementCurrency !== undefined) {
|
|
220
|
+
payment.settlement_amount = validateAmount(props.settlementAmount);
|
|
221
|
+
payment.settlement_currency = normalizePaymentCurrency(props.settlementCurrency);
|
|
222
|
+
}
|
|
223
|
+
return this.transport.sendPayment(payment);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Drain both queues now. Resolves once every in-flight request settles.
|
|
227
|
+
* Never rejects — delivery failures surface via `onError`.
|
|
228
|
+
*/
|
|
229
|
+
async flush() {
|
|
230
|
+
// Snapshot + clear synchronously so concurrent enqueues aren't lost or
|
|
231
|
+
// double-sent. JS is single-threaded, so nothing runs between these lines.
|
|
232
|
+
const events = this.events;
|
|
233
|
+
this.events = [];
|
|
234
|
+
const conversions = this.conversions;
|
|
235
|
+
this.conversions = [];
|
|
236
|
+
// Send sequentially, not via Promise.all: firing one request per queued
|
|
237
|
+
// conversion concurrently would open N connections at once and, against the
|
|
238
|
+
// Worker's per-site / per-IP rate limits (100–200 req/min), trigger a 429
|
|
239
|
+
// storm that drops revenue events after retries. Matches the Go/Python SDKs.
|
|
240
|
+
for (const batch of chunk(events, this.flushAt)) {
|
|
241
|
+
await this.launch(this.transport.sendEvents(batch));
|
|
242
|
+
}
|
|
243
|
+
for (const conversion of conversions) {
|
|
244
|
+
await this.launch(this.transport.sendConversion(conversion));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Flush, stop the background timer, and remove exit hooks. Idempotent — safe
|
|
249
|
+
* to call more than once. After close, `page()`/`track()` throw.
|
|
250
|
+
*/
|
|
251
|
+
async close() {
|
|
252
|
+
if (this.closed)
|
|
253
|
+
return;
|
|
254
|
+
this.closed = true;
|
|
255
|
+
if (this.timer !== undefined) {
|
|
256
|
+
clearInterval(this.timer);
|
|
257
|
+
this.timer = undefined;
|
|
258
|
+
}
|
|
259
|
+
for (const { event, handler } of this.exitHooks) {
|
|
260
|
+
process.removeListener(event, handler);
|
|
261
|
+
}
|
|
262
|
+
this.exitHooks = [];
|
|
263
|
+
await this.flush();
|
|
264
|
+
// Await any batches launched by a prior auto-/timer-flush still in flight.
|
|
265
|
+
await Promise.all([...this.inflight]);
|
|
266
|
+
}
|
|
267
|
+
/** Alias for {@link Client.close} — matches the cross-language `shutdown()`. */
|
|
268
|
+
shutdown() {
|
|
269
|
+
return this.close();
|
|
270
|
+
}
|
|
271
|
+
// ── internals ──────────────────────────────────────────────────────────────
|
|
272
|
+
assertOpen() {
|
|
273
|
+
if (this.closed) {
|
|
274
|
+
throw new Error("Traceten: client is closed; construct a new Client to send more events");
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/** Trigger a flush when either queue has reached the flush threshold. */
|
|
278
|
+
maybeFlush() {
|
|
279
|
+
if (this.events.length >= this.flushAt || this.conversions.length >= this.flushAt) {
|
|
280
|
+
void this.flush();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/** Track an in-flight send so `close()` can await it, then self-remove. */
|
|
284
|
+
launch(promise) {
|
|
285
|
+
const tracked = promise.finally(() => {
|
|
286
|
+
this.inflight.delete(tracked);
|
|
287
|
+
});
|
|
288
|
+
this.inflight.add(tracked);
|
|
289
|
+
return tracked;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Register best-effort flush-on-exit hooks.
|
|
293
|
+
*
|
|
294
|
+
* `beforeExit` fires when the loop would otherwise empty — we flush and let
|
|
295
|
+
* the pending I/O keep the process alive until it settles. For `SIGTERM` /
|
|
296
|
+
* `SIGINT` we flush, then re-exit ONLY if we were the sole handler (otherwise
|
|
297
|
+
* the host app owns the shutdown decision and forcing `process.exit` would
|
|
298
|
+
* stomp its own handlers / exit code).
|
|
299
|
+
*/
|
|
300
|
+
registerExitHooks() {
|
|
301
|
+
const beforeExit = () => {
|
|
302
|
+
void this.flush();
|
|
303
|
+
};
|
|
304
|
+
process.once("beforeExit", beforeExit);
|
|
305
|
+
this.exitHooks.push({ event: "beforeExit", handler: beforeExit });
|
|
306
|
+
for (const signal of EXIT_SIGNALS) {
|
|
307
|
+
const soleHandler = process.listenerCount(signal) === 0;
|
|
308
|
+
const handler = () => {
|
|
309
|
+
void this.flush().finally(() => {
|
|
310
|
+
if (soleHandler) {
|
|
311
|
+
process.exit(0);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
};
|
|
315
|
+
process.once(signal, handler);
|
|
316
|
+
this.exitHooks.push({ event: signal, handler });
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAavB,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC5B,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,yBAAyB,GAAG,IAAI,CAAC;AACvC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAEjC,sEAAsE;AACtE,MAAM,YAAY,GAA8B,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEtE,SAAS,KAAK,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW;IACpD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,yDAAyD;AACzD,SAAS,UAAU,CAAC,KAAyB,EAAE,QAAgB,EAAE,IAAY;IAC3E,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,SAAS,CAAC,aAAa,IAAI,4BAA4B,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAOD,MAAM,OAAO,MAAM;IACA,MAAM,CAAS;IACf,IAAI,CAAS;IACb,OAAO,CAAS;IAChB,SAAS,CAAY;IACrB,OAAO,CAAU;IAE1B,MAAM,GAAgB,EAAE,CAAC;IACzB,WAAW,GAAqB,EAAE,CAAC;IAEnC,KAAK,CAA6B;IACzB,QAAQ,GAAG,IAAI,GAAG,EAAiB,CAAC;IAC7C,SAAS,GAAe,EAAE,CAAC;IAC3B,MAAM,GAAG,KAAK,CAAC;IAEvB,YAAY,OAAsB;QAChC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACpD,MAAM,IAAI,SAAS,CAAC,6CAA6C,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxC,2EAA2E;QAC3E,0EAA0E;QAC1E,8CAA8C;QAC9C,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,IAAI,gBAAgB,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;QACtF,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAEpD,MAAM,aAAa,GAAG,UAAU,CAC9B,OAAO,CAAC,aAAa,EACrB,yBAAyB,EACzB,eAAe,CAChB,CAAC;QACF,MAAM,UAAU,GACd,OAAO,CAAC,UAAU,KAAK,SAAS;YAC9B,CAAC,CAAC,mBAAmB;YACrB,CAAC,CAAC,CAAC,GAAW,EAAE;gBACZ,IACE,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ;oBACtC,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC;oBACrC,OAAO,CAAC,UAAU,GAAG,CAAC,EACtB,CAAC;oBACD,MAAM,IAAI,SAAS,CAAC,qDAAqD,CAAC,CAAC;gBAC7E,CAAC;gBACD,OAAO,OAAO,CAAC,UAAU,CAAC;YAC5B,CAAC,CAAC,EAAE,CAAC;QACX,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;QAEjF,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC;YAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM;YACN,UAAU;YACV,SAAS;YACT,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;QAEH,wEAAwE;QACxE,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC,EAAE,aAAa,CAAC,CAAC;QAClB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAEnB,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,KAAgB;QACnB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAChD,MAAM,IAAI,SAAS,CAAC,0CAA0C,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,SAAS,IAAI,UAAU,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAE3C,MAAM,KAAK,GAAc,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QAC/E,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAClC,KAAK,CAAC,SAAS,GAAG,sBAAsB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAClC,KAAK,CAAC,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YAClC,KAAK,CAAC,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAChD,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAY,EAAE,IAAkB;QACpC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9C,MAAM,IAAI,SAAS,CAAC,+DAA+D,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,SAAS,CACjB,qFAAqF,CACtF,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEjD,MAAM,UAAU,GAAmB;YACjC,UAAU,EAAE,SAAS;YACrB,OAAO,EAAE,IAAI,CAAC,MAAM;YACpB,SAAS;YACT,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;SAClC,CAAC;QACF,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACjC,UAAU,CAAC,UAAU,GAAG,2BAA2B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,UAAU,CAAC,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,UAAU,CAAC,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,IAAY,EAAE,IAAkB;QACnC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,KAAK,CAAC,OAAO,CAAC,KAAmB;QAC/B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAChD,MAAM,IAAI,SAAS,CAAC,6CAA6C,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,OAAO,GAAgB;YAC3B,OAAO,EAAE,IAAI,CAAC,MAAM;YACpB,cAAc,EAAE,qBAAqB,CAAC,KAAK,CAAC,aAAa,CAAC;YAC1D,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC;YACpC,QAAQ,EAAE,wBAAwB,CAAC,KAAK,CAAC,QAAQ,CAAC;SACnD,CAAC;QACF,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;YAAE,OAAO,CAAC,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACtF,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,CAAC,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3F,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAC3D,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;YAAE,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC;QAC3E,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;YAAE,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QACjE,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;YAAE,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QACpE,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS;YAAE,OAAO,CAAC,aAAa,GAAG,KAAK,CAAC,WAAW,CAAC;QAC/E,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO,CAAC,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvF,wEAAwE;QACxE,yEAAyE;QACzE,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,IAAI,KAAK,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACnF,OAAO,CAAC,iBAAiB,GAAG,cAAc,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACnE,OAAO,CAAC,mBAAmB,GAAG,wBAAwB,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACnF,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK;QACT,uEAAuE;QACvE,2EAA2E;QAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QAEtB,wEAAwE;QACxE,4EAA4E;QAC5E,0EAA0E;QAC1E,6EAA6E;QAC7E,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QACtD,CAAC;QACD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QAEnB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACzB,CAAC;QACD,KAAK,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAChD,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QAEpB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,2EAA2E;QAC3E,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,gFAAgF;IAChF,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,8EAA8E;IAEtE,UAAU;QAChB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAED,yEAAyE;IACjE,UAAU;QAChB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClF,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,2EAA2E;IACnE,MAAM,CAAC,OAAsB;QACnC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE;YACnC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;;;OAQG;IACK,iBAAiB;QACvB,MAAM,UAAU,GAAG,GAAS,EAAE;YAC5B,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAElE,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;YAClC,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxD,MAAM,OAAO,GAAG,GAAS,EAAE;gBACzB,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;oBAC7B,IAAI,WAAW,EAAE,CAAC;wBAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@traceten/sdk-node` — the Traceten server-side SDK for Node.js.
|
|
3
|
+
*
|
|
4
|
+
* Send AI-traffic pageviews (`page`) and revenue/conversion events (`track`)
|
|
5
|
+
* from your backend over authenticated, ad-blocker-resistant HTTP. See
|
|
6
|
+
* `API.md` for the quickstart and full reference.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { Client } from "@traceten/sdk-node";
|
|
11
|
+
*
|
|
12
|
+
* const traceten = new Client({ siteId: "ttid_7Rb4TrC1dTbnD8w3s1TS12", host: "https://ingest.traceten.com" });
|
|
13
|
+
* traceten.page({ url: "https://acme.com/pricing", visitorId });
|
|
14
|
+
* traceten.track("subscription_started", { visitorId, valueCents: 4900, currency: "usd" });
|
|
15
|
+
* await traceten.close(); // flush on shutdown
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export { Client } from "./client.js";
|
|
19
|
+
export type { ClientOptions, PageProps, PaymentProps, PaymentResult, PaymentStatus, TrackOptions, OnError, EventWire, ConversionWire, PaymentWire, } from "./types.js";
|
|
20
|
+
export { verifyWebhook, WebhookVerificationError, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, WEBHOOK_REPLAY_TOLERANCE_SECONDS, WEBHOOK_EVENT_TYPES, ATTRIBUTION_MODELS, } from "./webhook.js";
|
|
21
|
+
export type { WebhookEvent, WebhookEventType, VerifyWebhookOptions, AiSessionClassifiedData, ConversionAttributedData, WebhookPingData, AttributionModel, AttributionModelBreakdown, } from "./webhook.js";
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EACV,aAAa,EACb,SAAS,EACT,YAAY,EACZ,aAAa,EACb,aAAa,EACb,YAAY,EACZ,OAAO,EACP,SAAS,EACT,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,gCAAgC,EAChC,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,yBAAyB,GAC1B,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@traceten/sdk-node` — the Traceten server-side SDK for Node.js.
|
|
3
|
+
*
|
|
4
|
+
* Send AI-traffic pageviews (`page`) and revenue/conversion events (`track`)
|
|
5
|
+
* from your backend over authenticated, ad-blocker-resistant HTTP. See
|
|
6
|
+
* `API.md` for the quickstart and full reference.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { Client } from "@traceten/sdk-node";
|
|
11
|
+
*
|
|
12
|
+
* const traceten = new Client({ siteId: "ttid_7Rb4TrC1dTbnD8w3s1TS12", host: "https://ingest.traceten.com" });
|
|
13
|
+
* traceten.page({ url: "https://acme.com/pricing", visitorId });
|
|
14
|
+
* traceten.track("subscription_started", { visitorId, valueCents: 4900, currency: "usd" });
|
|
15
|
+
* await traceten.close(); // flush on shutdown
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export { Client } from "./client.js";
|
|
19
|
+
export { verifyWebhook, WebhookVerificationError, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, WEBHOOK_REPLAY_TOLERANCE_SECONDS, WEBHOOK_EVENT_TYPES, ATTRIBUTION_MODELS, } from "./webhook.js";
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAcrC,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,EACxB,gCAAgC,EAChC,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC"}
|
package/dist/queue.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport layer for the Traceten Node SDK.
|
|
3
|
+
*
|
|
4
|
+
* Owns the "one HTTP request, with retry" primitive that both queues share.
|
|
5
|
+
* Batching/chunking lives in the {@link Client}; this module only knows how to
|
|
6
|
+
* deliver a single already-shaped body to a single endpoint, retrying on
|
|
7
|
+
* transient failures per DESIGN.md §4.
|
|
8
|
+
*
|
|
9
|
+
* Retry policy:
|
|
10
|
+
* - 2xx → success.
|
|
11
|
+
* - 5xx or 429 or network/timeout → retryable; exponential backoff with full
|
|
12
|
+
* jitter (`base 200ms * 2^attempt`), up to
|
|
13
|
+
* `maxRetries` retries.
|
|
14
|
+
* - other 4xx → the payload is malformed; DROP it and call
|
|
15
|
+
* `onError`. Retrying a 400 forever is a
|
|
16
|
+
* self-DoS.
|
|
17
|
+
*/
|
|
18
|
+
import type { ConversionWire, EventWire, OnError, PaymentResult, PaymentWire } from "./types.js";
|
|
19
|
+
export interface TransportOptions {
|
|
20
|
+
host: string;
|
|
21
|
+
/** REQUIRED — `/v1/server/*` returns 401 without it. */
|
|
22
|
+
apiKey: string;
|
|
23
|
+
maxRetries: number;
|
|
24
|
+
timeoutMs: number;
|
|
25
|
+
onError: OnError;
|
|
26
|
+
}
|
|
27
|
+
/** Split `items` into contiguous chunks of at most `size`. */
|
|
28
|
+
export declare function chunk<T>(items: readonly T[], size: number): T[][];
|
|
29
|
+
export declare class Transport {
|
|
30
|
+
private readonly eventsUrl;
|
|
31
|
+
private readonly conversionsUrl;
|
|
32
|
+
private readonly paymentsUrl;
|
|
33
|
+
private readonly headers;
|
|
34
|
+
private readonly maxRetries;
|
|
35
|
+
private readonly timeoutMs;
|
|
36
|
+
private readonly onError;
|
|
37
|
+
constructor(opts: TransportOptions);
|
|
38
|
+
/** Send one `/v1/server/events` batch envelope. Never throws. */
|
|
39
|
+
sendEvents(events: EventWire[]): Promise<void>;
|
|
40
|
+
/** Send one `/v1/server/conversions` body (one event per request). Never throws. */
|
|
41
|
+
sendConversion(conversion: ConversionWire): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Send one `/v1/server/payments` body and RETURN the outcome (#794).
|
|
44
|
+
*
|
|
45
|
+
* Unlike the two above, this one is awaited and its result surfaced: the
|
|
46
|
+
* endpoint's whole contract is the idempotency answer, so swallowing it would
|
|
47
|
+
* discard the one thing the caller asked for.
|
|
48
|
+
*
|
|
49
|
+
* Retrying is safe for the same reason — the server deduplicates on
|
|
50
|
+
* `(site, provider, transaction_id)` durably, so a retried 5xx cannot become a
|
|
51
|
+
* second payment.
|
|
52
|
+
*
|
|
53
|
+
* @throws when the payment was NOT accepted after every retry. `payment()` is
|
|
54
|
+
* the only SDK call that rejects, because a silently dropped payment is
|
|
55
|
+
* missing revenue rather than a missing pageview.
|
|
56
|
+
*/
|
|
57
|
+
sendPayment(payment: PaymentWire): Promise<PaymentResult>;
|
|
58
|
+
/** One attempt that also reads the JSON body, for the payments endpoint. */
|
|
59
|
+
private attemptJson;
|
|
60
|
+
/**
|
|
61
|
+
* POST `body` to `url`, retrying transient failures. Resolves once the
|
|
62
|
+
* request either succeeds or is permanently given up on (after calling
|
|
63
|
+
* `onError`). Deliberately never rejects — `page()`/`track()`/`flush()` must
|
|
64
|
+
* not throw on network problems.
|
|
65
|
+
*/
|
|
66
|
+
private deliver;
|
|
67
|
+
/** A single HTTP attempt, classified into an {@link Outcome}. */
|
|
68
|
+
private attempt;
|
|
69
|
+
/** Invoke the user `onError` hook, swallowing any error it throws. */
|
|
70
|
+
private reportError;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKjG,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,8DAA8D;AAC9D,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAMjE;AAuBD,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEtB,IAAI,EAAE,gBAAgB;IAoBlC,iEAAiE;IAC3D,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpD,oFAAoF;IAC9E,cAAc,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D;;;;;;;;;;;;;;OAcG;IACG,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IAsB/D,4EAA4E;YAC9D,WAAW;IAgDzB;;;;;OAKG;YACW,OAAO;IAmBrB,iEAAiE;YACnD,OAAO;IAwCrB,sEAAsE;IACtE,OAAO,CAAC,WAAW;CAOpB"}
|