@runbandit/sdk 3.1.3 → 3.4.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.
@@ -0,0 +1,503 @@
1
+ declare const STOREFRONT_KINDS: readonly ["text", "image", "ordering", "offer"];
2
+ type StorefrontKind = (typeof STOREFRONT_KINDS)[number];
3
+ declare const PLACEMENTS_BY_KIND: {
4
+ readonly text: readonly ["hero_headline", "hero_subhead", "cta_primary", "banner_text", "badge_text"];
5
+ readonly image: readonly ["hero_image", "banner_image", "feature_image"];
6
+ readonly ordering: readonly ["product_list_primary", "product_list_secondary"];
7
+ readonly offer: readonly ["offer_banner"];
8
+ };
9
+ type Placement = (typeof PLACEMENTS_BY_KIND)[StorefrontKind][number];
10
+ declare const PLACEMENTS: readonly Placement[];
11
+ declare function isPlacement(value: unknown): value is Placement;
12
+ declare function kindOfPlacement(placement: Placement): StorefrontKind;
13
+ declare const CONTENT_TYPE_BY_KIND: {
14
+ readonly text: {
15
+ readonly contentType: "TEXT";
16
+ readonly contentSubtype: "plain_text";
17
+ };
18
+ readonly image: {
19
+ readonly contentType: "FILE";
20
+ readonly contentSubtype: "image";
21
+ };
22
+ readonly ordering: {
23
+ readonly contentType: "CODE";
24
+ readonly contentSubtype: "json";
25
+ };
26
+ readonly offer: {
27
+ readonly contentType: "CODE";
28
+ readonly contentSubtype: "json";
29
+ };
30
+ };
31
+ declare const MIN_ORDERING_ITEMS = 2;
32
+ declare const MAX_ORDERING_ITEMS = 12;
33
+ interface ImageContent {
34
+ url: string;
35
+ alt: string;
36
+ width: number;
37
+ height: number;
38
+ sourceId: string;
39
+ }
40
+ interface OfferContent {
41
+ discountId: string;
42
+ code: string;
43
+ headline: string;
44
+ subtext: string;
45
+ }
46
+ type TreatmentContent = {
47
+ kind: 'text';
48
+ text: string;
49
+ } | {
50
+ kind: 'image';
51
+ image: ImageContent;
52
+ } | {
53
+ kind: 'ordering';
54
+ productIds: string[];
55
+ } | {
56
+ kind: 'offer';
57
+ offer: OfferContent | null;
58
+ };
59
+ declare function isShopifyCdnUrl(value: string): boolean;
60
+ declare function parseTreatmentContent(kind: StorefrontKind, config: unknown): TreatmentContent | null;
61
+ declare function serializeTreatmentConfig(content: TreatmentContent): {
62
+ content: unknown;
63
+ };
64
+
65
+ declare const SITE_TARGET_KINDS: readonly ["text", "image"];
66
+ type SiteTargetKind = (typeof SITE_TARGET_KINDS)[number];
67
+ interface SiteTarget {
68
+ page: string;
69
+ selector: string;
70
+ tag: string;
71
+ kind: SiteTargetKind;
72
+ original: string;
73
+ }
74
+ type FunnelGoal = {
75
+ kind: 'page';
76
+ page: string;
77
+ } | {
78
+ kind: 'click';
79
+ page: string;
80
+ selector: string;
81
+ tag: string;
82
+ label: string;
83
+ };
84
+ declare function parseSiteContent(config: unknown): string | null;
85
+ declare function normalizeSiteTarget(target: SiteTarget): SiteTarget;
86
+ declare function normalizeFunnelGoal(goal: FunnelGoal): FunnelGoal;
87
+ declare function targetMatchesPage(target: Pick<SiteTarget, 'page'>, pathname: string): boolean;
88
+ declare function goalMatchesPage(goal: Pick<FunnelGoal, 'page'>, pathname: string): boolean;
89
+ declare const MAX_ALTERNATIVES = 5;
90
+ declare const MAX_TEXT_ALTERNATIVE_LENGTH = 300;
91
+ declare const MAX_IMAGE_URL_LENGTH = 2048;
92
+ interface PickDraft {
93
+ target?: SiteTarget;
94
+ alternatives: string[];
95
+ goal?: FunnelGoal;
96
+ }
97
+ interface PickState {
98
+ funnelId: string;
99
+ siteHost: string;
100
+ expiresAt: number;
101
+ draft: PickDraft;
102
+ funnelGoal: FunnelGoal | null;
103
+ experimentId: string | null;
104
+ runningExperiments: number;
105
+ }
106
+ declare const SUGGESTED_SITE_EXPERIMENTS = 3;
107
+ declare function moreExperimentsSentence(running: number, suggested: number): string;
108
+ type PickStep = 'pick' | 'alternatives' | 'goal' | 'ready' | 'live';
109
+ declare function pickStep(state: Pick<PickState, 'draft' | 'funnelGoal' | 'experimentId'>): PickStep;
110
+ declare function parseAlternative(kind: SiteTargetKind, raw: string): string;
111
+ declare const PICK_CHANNEL = "bandit-pick";
112
+ declare const PICK_PROTOCOL_VERSION = 1;
113
+ declare const PICK_MODES: readonly ["idle", "target", "goal-click"];
114
+ type PickMode = (typeof PICK_MODES)[number];
115
+ declare const PICK_REJECTIONS: readonly ["not-text-or-image", "has-markup", "not-clickable", "no-selector"];
116
+ type PickRejection = (typeof PICK_REJECTIONS)[number];
117
+ type ClickFunnelGoal = Extract<FunnelGoal, {
118
+ kind: 'click';
119
+ }>;
120
+ type PickerToPanel = {
121
+ type: 'navigated';
122
+ page: string;
123
+ } | {
124
+ type: 'target-picked';
125
+ target: SiteTarget;
126
+ } | {
127
+ type: 'goal-picked';
128
+ goal: ClickFunnelGoal;
129
+ } | {
130
+ type: 'rejected';
131
+ reason: PickRejection;
132
+ } | {
133
+ type: 'cancelled';
134
+ };
135
+ type PanelToPicker = {
136
+ type: 'hello';
137
+ } | {
138
+ type: 'mode';
139
+ mode: PickMode;
140
+ } | {
141
+ type: 'preview';
142
+ target: SiteTarget;
143
+ content: string;
144
+ } | {
145
+ type: 'clear-preview';
146
+ } | {
147
+ type: 'finish';
148
+ } | {
149
+ type: 'renew';
150
+ token: string;
151
+ };
152
+ declare const PICK_TOKEN_PREFIX = "bpick_";
153
+ interface PickEnvelope<M> {
154
+ channel: typeof PICK_CHANNEL;
155
+ v: typeof PICK_PROTOCOL_VERSION;
156
+ msg: M;
157
+ }
158
+ declare function pickEnvelope<M extends PickerToPanel | PanelToPicker>(msg: M): PickEnvelope<M>;
159
+ declare function parsePickerMessage(data: unknown): PickerToPanel | null;
160
+ declare function parsePanelMessage(data: unknown): PanelToPicker | null;
161
+
162
+ interface OrderLineItem {
163
+ id?: string;
164
+ quantity?: number;
165
+ price: number;
166
+ discount?: number;
167
+ unitCost?: number;
168
+ }
169
+ type OrderAmounts = {
170
+ lines: OrderLineItem[];
171
+ shipping?: number;
172
+ shippingCost?: number;
173
+ } | {
174
+ revenue: number;
175
+ cost?: number;
176
+ shipping?: number;
177
+ shippingCost?: number;
178
+ };
179
+
180
+ interface Company {
181
+ id: string;
182
+ name: string;
183
+ subdomain?: string;
184
+ domain?: string;
185
+ plan: string;
186
+ apiKey: string;
187
+ status: string;
188
+ createdAt: Date;
189
+ updatedAt: Date;
190
+ }
191
+ interface User {
192
+ id: string;
193
+ email: string;
194
+ name: string;
195
+ image?: string;
196
+ role: string;
197
+ companyId: string | null;
198
+ emailVerified?: boolean;
199
+ createdAt: Date;
200
+ updatedAt: Date;
201
+ }
202
+ interface Session {
203
+ id: string;
204
+ userId: string;
205
+ token: string;
206
+ expiresAt: Date;
207
+ ipAddress?: string | null;
208
+ userAgent?: string | null;
209
+ createdAt: Date;
210
+ updatedAt: Date;
211
+ }
212
+ interface Account {
213
+ id: string;
214
+ userId: string;
215
+ provider: string;
216
+ providerAccountId: string;
217
+ accessToken?: string;
218
+ refreshToken?: string;
219
+ accessTokenExpiresAt?: Date;
220
+ refreshTokenExpiresAt?: Date;
221
+ scope?: string;
222
+ idToken?: string;
223
+ sessionState?: string;
224
+ createdAt: Date;
225
+ updatedAt: Date;
226
+ }
227
+ interface Experiment {
228
+ id: string;
229
+ name: string;
230
+ description?: string;
231
+ algorithm: BanditAlgorithm;
232
+ forgetting?: ForgettingConfig;
233
+ status: ExperimentStatus;
234
+ contentType: ContentType;
235
+ treatments: Treatment[];
236
+ context?: Record<string, any>;
237
+ bundleId?: string;
238
+ image?: string;
239
+ emoji?: string;
240
+ assignmentTtl: number;
241
+ companyId: string;
242
+ createdAt: Date;
243
+ updatedAt: Date;
244
+ endAt?: Date;
245
+ placement?: Placement;
246
+ }
247
+ interface Treatment {
248
+ id: string;
249
+ experimentId: string;
250
+ name: string;
251
+ description?: string;
252
+ config: VariantConfig;
253
+ weight?: number;
254
+ companyId: string;
255
+ createdAt: Date;
256
+ }
257
+ interface AlgorithmResult {
258
+ treatmentId: string;
259
+ confidence: number;
260
+ probabilityBest?: number;
261
+ }
262
+ interface BanditResult {
263
+ assignmentId: string;
264
+ treatmentId: string;
265
+ confidence: number;
266
+ probabilityBest?: number;
267
+ metadata?: Record<string, any>;
268
+ }
269
+ interface ContextualFeatures {
270
+ [key: string]: string | number | boolean;
271
+ }
272
+ declare enum ExperimentStatus {
273
+ DRAFT = "draft",
274
+ ACTIVE = "active",
275
+ PAUSED = "paused",
276
+ COMPLETED = "completed",
277
+ ARCHIVED = "archived"
278
+ }
279
+ interface TreatmentMetadata {
280
+ strategy?: string;
281
+ tone?: string;
282
+ ctaStyle?: string;
283
+ emotionalHook?: string;
284
+ reasoning?: string;
285
+ tags?: string[];
286
+ generated?: boolean;
287
+ generatedAt?: string;
288
+ }
289
+ interface VariantConfig {
290
+ content: string;
291
+ metadata?: TreatmentMetadata & Record<string, any>;
292
+ }
293
+ declare enum BanditAlgorithm {
294
+ THOMPSON_SAMPLING = "thompson_sampling",
295
+ CONTEXTUAL_LINEAR = "contextual_linear"
296
+ }
297
+ declare enum Posterior {
298
+ BETA = "beta",
299
+ NORMAL_GAMMA = "normal_gamma"
300
+ }
301
+ declare function normalizePosterior(posterior: string | null | undefined): Posterior;
302
+ declare enum ForgettingMode {
303
+ NONE = "none",
304
+ DISCOUNTED = "discounted",
305
+ SLIDING_WINDOW = "sliding_window"
306
+ }
307
+ interface ForgettingConfig {
308
+ mode: ForgettingMode;
309
+ halfLifeMs?: number;
310
+ windowMs?: number;
311
+ }
312
+ declare const DEFAULT_HALF_LIFE_MS: number;
313
+ declare const DEFAULT_WINDOW_MS: number;
314
+ declare const STATIONARY: ForgettingConfig;
315
+ declare function resolveForgetting(config?: Partial<ForgettingConfig> | null): ForgettingConfig;
316
+ declare function normalizeAlgorithm(algorithm: string | null | undefined): BanditAlgorithm;
317
+ declare enum ContentType {
318
+ PLAIN_TEXT = "plain_text",
319
+ MARKDOWN = "markdown",
320
+ HTML = "html",
321
+ CSS = "css",
322
+ JAVASCRIPT = "javascript",
323
+ JSON = "json",
324
+ IMAGE = "image",
325
+ VIDEO = "video",
326
+ AUDIO = "audio",
327
+ DOCUMENT = "document"
328
+ }
329
+ declare function getContentTypeCategory(contentType: ContentType): 'text' | 'code' | 'file';
330
+ interface BanditConfig {
331
+ algorithm: BanditAlgorithm;
332
+ parameters: Record<string, any>;
333
+ }
334
+ interface ExperimentStats {
335
+ totalAssignments: number;
336
+ totalConversions: number;
337
+ conversionRate: number;
338
+ treatmentStats: Record<string, TreatmentStats>;
339
+ }
340
+ interface TreatmentStats {
341
+ assignments: number;
342
+ conversions: number;
343
+ conversionRate: number;
344
+ confidence: number;
345
+ lift?: number;
346
+ }
347
+ interface APIResponse<T = any> {
348
+ success: boolean;
349
+ data?: T;
350
+ error?: string;
351
+ timestamp: Date;
352
+ }
353
+ interface CreateExperimentRequest {
354
+ name: string;
355
+ description?: string;
356
+ algorithm: BanditAlgorithm;
357
+ contentType: ContentType;
358
+ algorithmConfig?: Record<string, any>;
359
+ treatments?: Omit<Treatment, 'id' | 'experimentId' | 'createdAt'>[];
360
+ }
361
+ interface AssignmentRequest {
362
+ experimentId: string;
363
+ userId: string;
364
+ context?: ContextualFeatures;
365
+ sessionId?: string;
366
+ pageUrl?: string;
367
+ }
368
+ interface TrackNamedEventRequest {
369
+ name: string;
370
+ category?: string;
371
+ value?: number;
372
+ cost?: number;
373
+ lineItems?: OrderLineItem[];
374
+ metadata?: Record<string, any>;
375
+ sessionId: string;
376
+ userId?: string;
377
+ assignmentId?: string;
378
+ }
379
+ declare enum FunnelStatus {
380
+ DRAFT = "draft",
381
+ ACTIVE = "active",
382
+ PAUSED = "paused",
383
+ COMPLETED = "completed"
384
+ }
385
+ interface Funnel {
386
+ id: string;
387
+ name: string;
388
+ description?: string;
389
+ status: FunnelStatus;
390
+ inactivityTimeoutMs?: number;
391
+ revisionWindowMs?: number;
392
+ companyId: string;
393
+ createdAt: Date;
394
+ updatedAt: Date;
395
+ }
396
+ interface FunnelRewardRequest {
397
+ funnelId: string;
398
+ userId: string;
399
+ value: number;
400
+ }
401
+ interface ApiKey {
402
+ id: string;
403
+ name: string;
404
+ keyPrefix: string;
405
+ status: 'active' | 'revoked';
406
+ createdBy: string;
407
+ createdAt: Date;
408
+ lastUsedAt?: Date;
409
+ revokedAt?: Date;
410
+ revokedBy?: string;
411
+ }
412
+ interface CreateApiKeyRequest {
413
+ name: string;
414
+ }
415
+ interface CreateApiKeyResponse {
416
+ id: string;
417
+ key: string;
418
+ name: string;
419
+ }
420
+ type IdentifyMergeReason = 'user_signup' | 'email_verification' | 'social_login' | 'account_recovery' | 'manual';
421
+ interface IdentifyUserRequest {
422
+ anonymousId: string;
423
+ identifiedUserId: string;
424
+ mergeReason?: IdentifyMergeReason;
425
+ }
426
+ interface IdentifyUserResponse {
427
+ anonymousId: string;
428
+ identifiedUserId: string;
429
+ alreadyMapped: boolean;
430
+ }
431
+ interface ResolvedIdentity {
432
+ canonicalId: string;
433
+ anonymousIds: string[];
434
+ isIdentified: boolean;
435
+ }
436
+ type BundleMode = 'factored' | 'joint';
437
+ interface Bundle {
438
+ id: string;
439
+ name: string;
440
+ description?: string;
441
+ status: ExperimentStatus;
442
+ mode: BundleMode;
443
+ funnelId?: string;
444
+ assignmentTtl: number;
445
+ conversionWindowMs: number;
446
+ inactivityTimeoutMs?: number;
447
+ revisionWindowMs?: number;
448
+ companyId: string;
449
+ createdAt: Date;
450
+ updatedAt: Date;
451
+ }
452
+ interface BundleAssignmentRequest {
453
+ bundleId: string;
454
+ userId: string;
455
+ context?: ContextualFeatures;
456
+ sessionId?: string;
457
+ pageUrl?: string;
458
+ }
459
+ interface BundleSlotAssignment {
460
+ assignmentId: string;
461
+ experimentId: string;
462
+ treatmentId: string;
463
+ config: VariantConfig | Record<string, unknown>;
464
+ }
465
+ interface BundleAssignmentResponse {
466
+ bundleAssignmentId: string;
467
+ slots: Record<string, BundleSlotAssignment>;
468
+ }
469
+ interface SnapshotTreatment {
470
+ id: string;
471
+ name?: string;
472
+ config: unknown;
473
+ pct: number;
474
+ }
475
+ interface SnapshotExperiment {
476
+ name?: string;
477
+ mode: 'snapshot' | 'network';
478
+ assignmentTtl: number;
479
+ treatments: SnapshotTreatment[];
480
+ target?: SiteTarget;
481
+ funnelId?: string;
482
+ }
483
+ interface CompanySnapshot {
484
+ ttl: number;
485
+ generatedAt: number;
486
+ experiments: Record<string, SnapshotExperiment>;
487
+ goals?: Record<string, FunnelGoal>;
488
+ }
489
+
490
+ declare const VISITOR_COOKIE = "bandit_v";
491
+ declare const DECISIONS_COOKIE = "bandit_d";
492
+ interface CookieDecision {
493
+ experimentId: string;
494
+ treatmentId: string;
495
+ clientAssignmentId: string;
496
+ expiresAt: number;
497
+ }
498
+ type CookieDecisions = Record<string, CookieDecision>;
499
+ declare function readCookie(header: string | null | undefined, name: string): string | null;
500
+ declare function parseDecisions(value: string | null | undefined, now: number): CookieDecisions;
501
+ declare function serializeDecisions(decisions: CookieDecisions): string;
502
+
503
+ export { type BundleMode as $, type Account as A, type BundleAssignmentResponse as B, type ContextualFeatures as C, DECISIONS_COOKIE as D, type Experiment as E, ForgettingMode as F, type TreatmentStats as G, type APIResponse as H, type CreateExperimentRequest as I, type AssignmentRequest as J, type TrackNamedEventRequest as K, FunnelStatus as L, type Funnel as M, type FunnelRewardRequest as N, type OrderLineItem as O, Posterior as P, type ApiKey as Q, type CreateApiKeyRequest as R, type SnapshotTreatment as S, type Treatment as T, type User as U, VISITOR_COOKIE as V, type CreateApiKeyResponse as W, type IdentifyMergeReason as X, type IdentifyUserRequest as Y, type IdentifyUserResponse as Z, type ResolvedIdentity as _, type CompanySnapshot as a, type Bundle as a0, type BundleAssignmentRequest as a1, type BundleSlotAssignment as a2, STOREFRONT_KINDS as a3, type StorefrontKind as a4, PLACEMENTS_BY_KIND as a5, type Placement as a6, PLACEMENTS as a7, isPlacement as a8, kindOfPlacement as a9, pickStep as aA, parseAlternative as aB, PICK_CHANNEL as aC, PICK_PROTOCOL_VERSION as aD, PICK_MODES as aE, type PickMode as aF, PICK_REJECTIONS as aG, type PickRejection as aH, type ClickFunnelGoal as aI, type PickerToPanel as aJ, type PanelToPicker as aK, PICK_TOKEN_PREFIX as aL, type PickEnvelope as aM, pickEnvelope as aN, parsePickerMessage as aO, parsePanelMessage as aP, type OrderAmounts as aQ, CONTENT_TYPE_BY_KIND as aa, MIN_ORDERING_ITEMS as ab, MAX_ORDERING_ITEMS as ac, type ImageContent as ad, type OfferContent as ae, type TreatmentContent as af, isShopifyCdnUrl as ag, parseTreatmentContent as ah, serializeTreatmentConfig as ai, SITE_TARGET_KINDS as aj, type SiteTargetKind as ak, type SiteTarget as al, type FunnelGoal as am, parseSiteContent as an, normalizeSiteTarget as ao, normalizeFunnelGoal as ap, targetMatchesPage as aq, goalMatchesPage as ar, MAX_ALTERNATIVES as as, MAX_TEXT_ALTERNATIVE_LENGTH as at, MAX_IMAGE_URL_LENGTH as au, type PickDraft as av, type PickState as aw, SUGGESTED_SITE_EXPERIMENTS as ax, moreExperimentsSentence as ay, type PickStep as az, type SnapshotExperiment as b, type CookieDecision as c, type CookieDecisions as d, type Company as e, type Session as f, type AlgorithmResult as g, type BanditResult as h, ExperimentStatus as i, type TreatmentMetadata as j, type VariantConfig as k, BanditAlgorithm as l, type ForgettingConfig as m, normalizePosterior as n, DEFAULT_HALF_LIFE_MS as o, parseDecisions as p, DEFAULT_WINDOW_MS as q, readCookie as r, serializeDecisions as s, STATIONARY as t, resolveForgetting as u, normalizeAlgorithm as v, ContentType as w, getContentTypeCategory as x, type BanditConfig as y, type ExperimentStats as z };