@customerhero/js 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.d.cts CHANGED
@@ -123,6 +123,133 @@ interface IdentityData {
123
123
  userHash?: string;
124
124
  customProperties?: Record<string, string | number | boolean>;
125
125
  }
126
+ type TriggerConditionNode = {
127
+ all: TriggerConditionNode[];
128
+ } | {
129
+ any: TriggerConditionNode[];
130
+ } | TriggerConditionLeaf;
131
+ type TriggerConditionLeaf = {
132
+ kind: "url_path";
133
+ op: "equals" | "contains" | "regex" | "starts_with";
134
+ value: string;
135
+ } | {
136
+ kind: "url_query";
137
+ key: string;
138
+ op: "equals" | "contains" | "exists";
139
+ value?: string;
140
+ } | {
141
+ kind: "referrer";
142
+ op: "contains" | "equals" | "regex";
143
+ value: string;
144
+ } | {
145
+ kind: "time_on_page";
146
+ seconds: number;
147
+ } | {
148
+ kind: "scroll_depth";
149
+ percent: number;
150
+ } | {
151
+ kind: "exit_intent";
152
+ } | {
153
+ kind: "device";
154
+ op: "equals";
155
+ value: "mobile" | "tablet" | "desktop";
156
+ } | {
157
+ kind: "browser_language";
158
+ op: "in";
159
+ values: string[];
160
+ } | {
161
+ kind: "visitor_trait";
162
+ key: string;
163
+ op: "equals" | "exists" | "gt" | "lt";
164
+ value?: string | number | boolean;
165
+ } | {
166
+ kind: "return_visit";
167
+ op: "gte" | "eq";
168
+ count: number;
169
+ };
170
+ type TriggerAction = {
171
+ kind: "open_widget";
172
+ } | {
173
+ kind: "send_message";
174
+ message: string;
175
+ } | {
176
+ kind: "show_form";
177
+ } | {
178
+ kind: "open_with_prefill";
179
+ prefill: string;
180
+ };
181
+ type TriggerFrequency = "once_ever" | "once_per_session" | "every_time";
182
+ interface TriggerDefinition {
183
+ id: string;
184
+ priority: number;
185
+ conditions: TriggerConditionNode;
186
+ action: TriggerAction;
187
+ frequency: TriggerFrequency;
188
+ }
189
+ type PreChatFieldKind = "name" | "email" | "phone" | "text" | "textarea" | "select" | "consent";
190
+ type PreChatField = {
191
+ kind: "name";
192
+ required?: boolean;
193
+ label?: string;
194
+ } | {
195
+ kind: "email";
196
+ required?: boolean;
197
+ label?: string;
198
+ validateMx?: boolean;
199
+ } | {
200
+ kind: "phone";
201
+ required?: boolean;
202
+ label?: string;
203
+ } | {
204
+ kind: "text";
205
+ key: string;
206
+ label: string;
207
+ required?: boolean;
208
+ maxLength?: number;
209
+ } | {
210
+ kind: "textarea";
211
+ key: string;
212
+ label: string;
213
+ required?: boolean;
214
+ maxLength?: number;
215
+ } | {
216
+ kind: "select";
217
+ key: string;
218
+ label: string;
219
+ options: Array<{
220
+ value: string;
221
+ label: string;
222
+ }>;
223
+ required?: boolean;
224
+ } | {
225
+ kind: "consent";
226
+ key: string;
227
+ label: string;
228
+ url?: string;
229
+ required: true;
230
+ };
231
+ interface PreChatFormConfig {
232
+ fields: PreChatField[];
233
+ title?: string | null;
234
+ description?: string | null;
235
+ submitLabel: string;
236
+ /** When true, an identified visitor (CustomerHero.identify already called)
237
+ * bypasses the form. */
238
+ skipForIdentified: boolean;
239
+ }
240
+ interface PreChatSubmission {
241
+ name?: string;
242
+ email?: string;
243
+ phone?: string;
244
+ /** Keyed answers from text/textarea/select/consent fields. */
245
+ properties?: Record<string, string | number | boolean>;
246
+ }
247
+ interface ConsentSettings {
248
+ /** When true, all condition kinds are evaluated. When false (default), only
249
+ * direct launcher clicks fire — URL/time/scroll/exit-intent/trait
250
+ * conditions stay dormant. */
251
+ analytics: boolean;
252
+ }
126
253
  interface ChatState {
127
254
  messages: ChatMessage[];
128
255
  isOpen: boolean;
@@ -137,6 +264,26 @@ interface ChatState {
137
264
  locale: SupportedLocale;
138
265
  /** True when the active locale is right-to-left. */
139
266
  isRtl: boolean;
267
+ /** Triggers loaded from the server config (active + in-window). */
268
+ triggers: TriggerDefinition[];
269
+ /** Pre-chat form configuration, if any. */
270
+ preChatForm: PreChatFormConfig | null;
271
+ /**
272
+ * True when the pre-chat form must be shown before the next chat turn.
273
+ * Flipped by trigger actions, by the first sendMessage when a form is
274
+ * configured and not yet submitted, and cleared on submit.
275
+ */
276
+ preChatFormVisible: boolean;
277
+ /** Captured pre-chat submission, sent on the first chat call. */
278
+ preChatSubmission: PreChatSubmission | null;
279
+ /** Per-visitor consent. Until set explicitly, only direct launcher clicks
280
+ * trigger; behavioral conditions stay dormant. */
281
+ consent: ConsentSettings;
282
+ /** ID of the trigger attributed to the next conversation start, if any. */
283
+ pendingTriggerId: string | null;
284
+ /** When set, the host should preload this text into the input. Cleared
285
+ * once the host consumes it (or when the conversation starts). */
286
+ pendingPrefill: string | null;
140
287
  }
141
288
 
142
289
  type Listener = (state: ChatState) => void;
@@ -148,6 +295,10 @@ declare class CustomerHeroChat {
148
295
  private identityData;
149
296
  t: TranslateFn;
150
297
  constructor(config: CustomerHeroChatConfig);
298
+ private triggersRuntime;
299
+ private preChatFormSubmitted;
300
+ private readStoredConsent;
301
+ private writeStoredConsent;
151
302
  setLocale(tag: string): void;
152
303
  private rebuildTranslator;
153
304
  subscribe(listener: Listener): () => void;
@@ -179,6 +330,38 @@ declare class CustomerHeroChat {
179
330
  open(): void;
180
331
  close(): void;
181
332
  reset(): void;
333
+ /** Update visitor consent. Until `analytics: true` is set, only direct
334
+ * launcher clicks fire — URL/time/scroll/exit-intent/trait conditions
335
+ * stay dormant. The setting is persisted in localStorage so revisits
336
+ * don't re-prompt. */
337
+ setConsent(consent: Partial<ConsentSettings>): void;
338
+ /** Set or update visitor traits used by trait-based conditions. The trait
339
+ * values are kept in memory (not persisted) so the integrator decides
340
+ * the source of truth. */
341
+ setTraits(traits: Record<string, string | number | boolean>): void;
342
+ /** Submit pre-chat form answers. Synthesizes a customer record server-side
343
+ * on the next sendMessage. Resumes any pending message that was deferred
344
+ * while the form was open. */
345
+ submitPreChatForm(submission: PreChatSubmission): Promise<void>;
346
+ /** Dismiss the pre-chat form without submitting. The form will reappear
347
+ * on the next sendMessage attempt — call `setConsent` to acknowledge a
348
+ * refusal, or `reset()` to clear pending state. */
349
+ cancelPreChatForm(): void;
350
+ /** Programmatically dispatch the action attached to a trigger. Used by
351
+ * integrators who want to act on a custom button, e.g. an exit-intent
352
+ * modal in their own UI. */
353
+ fireTrigger(triggerId: string): void;
354
+ private pendingMessageAfterPreChat;
355
+ private shouldShowPreChatForm;
356
+ private startTriggersRuntimeIfPossible;
357
+ private handleTriggerAction;
358
+ /** Read and clear the pending prefill (set by an `open_with_prefill`
359
+ * trigger). The host calls this once when mounting the input and seeds
360
+ * its controlled value with the result. */
361
+ consumePendingPrefill(): string | null;
362
+ /** Stop the triggers runtime and detach listeners. Safe to call multiple
363
+ * times; safe to call before the runtime started. */
364
+ destroy(): void;
182
365
  identify(payload: IdentifyPayload): void;
183
366
  }
184
367
 
@@ -202,4 +385,57 @@ declare class ScreenshotUnavailable extends Error {
202
385
  declare function canCaptureScreenshot(): boolean;
203
386
  declare function captureScreenshot(): Promise<Blob>;
204
387
 
205
- export { type ActionConfirmationBlock, type ChatMessage, type ChatState, CustomerHeroChat, type CustomerHeroChatConfig, DEFAULTS, type IdentifyPayload, type IdentityData, type MessageBlock, type MessageRating, type MessageSource, type MessageStatus, type QuickRepliesBlock, type ResolvedConfig, SUPPORTED_LOCALES, ScreenshotCancelled, ScreenshotUnavailable, type StringOverrides, type SupportedLocale, type TranslateFn, type TranslationKey, type Translations, canCaptureScreenshot, captureScreenshot, createTranslator, detectLocale, isRtlLocale, resolveLocale };
388
+ interface VisitorContext {
389
+ url: string;
390
+ queryParams: Record<string, string>;
391
+ referrer: string;
392
+ language: string;
393
+ device: "mobile" | "tablet" | "desktop";
394
+ /** Time spent on the current page (in ms). Pauses while the tab is hidden. */
395
+ timeOnPageMs: number;
396
+ /** Scroll depth as a percentage of the document height (0..100). Tracked as
397
+ * a high-water mark so a quick scroll-up doesn't undo a `scroll_depth`
398
+ * match. */
399
+ scrollPercent: number;
400
+ /** True after the runtime detected a desktop-style exit-intent gesture or
401
+ * the mobile fallback (visibilitychange→hidden after a grace period). */
402
+ exitIntentSeen: boolean;
403
+ /** Number of distinct sessions this visitor has visited the page. */
404
+ returnVisitCount: number;
405
+ /** Custom traits set by the integrator via `setTraits` / `identify`. */
406
+ traits: Record<string, string | number | boolean>;
407
+ }
408
+ declare function evaluate(node: TriggerConditionNode, ctx: VisitorContext): boolean;
409
+ /** Walk `triggers` in priority order (low number = high priority) and return
410
+ * the first one that matches `ctx` and isn't already in `firedSet`. The
411
+ * caller decides what `firedSet` means — once_ever uses long-lived storage,
412
+ * once_per_session uses the in-memory or sessionStorage set, every_time
413
+ * always misses the set so it can re-fire. */
414
+ declare function pickFire(triggers: TriggerDefinition[], ctx: VisitorContext, firedSet: ReadonlySet<string>): TriggerDefinition | null;
415
+
416
+ interface TriggersRuntimeHandle {
417
+ /** Stop all watchers and remove listeners. */
418
+ stop(): void;
419
+ /** Force a re-evaluation (used after the integrator calls setTraits). */
420
+ reevaluate(): void;
421
+ /** Update visitor traits and re-evaluate. */
422
+ setTraits(traits: Record<string, string | number | boolean>): void;
423
+ /** Mark a trigger as fired (used after a direct launcher click acted on
424
+ * a trigger or when the runtime fired one itself). */
425
+ markFired(triggerId: string, frequency: TriggerFrequency): void;
426
+ }
427
+ interface StartTriggersRuntimeOptions {
428
+ chatbotId: string;
429
+ triggers: TriggerDefinition[];
430
+ /** Returns true when the runtime is allowed to fire a trigger. The client
431
+ * uses this to gate on consent — only direct launcher clicks fire until
432
+ * the integrator has called `setConsent({ analytics: true })`. */
433
+ isAllowedToFire(): boolean;
434
+ /** Called when a trigger is selected to fire. */
435
+ onFire(trigger: TriggerDefinition): void;
436
+ /** Optional initial traits seed. */
437
+ initialTraits?: Record<string, string | number | boolean>;
438
+ }
439
+ declare function startTriggersRuntime(options: StartTriggersRuntimeOptions): TriggersRuntimeHandle;
440
+
441
+ export { type ActionConfirmationBlock, type ChatMessage, type ChatState, type ConsentSettings, CustomerHeroChat, type CustomerHeroChatConfig, DEFAULTS, type IdentifyPayload, type IdentityData, type MessageBlock, type MessageRating, type MessageSource, type MessageStatus, type PreChatField, type PreChatFieldKind, type PreChatFormConfig, type PreChatSubmission, type QuickRepliesBlock, type ResolvedConfig, SUPPORTED_LOCALES, ScreenshotCancelled, ScreenshotUnavailable, type StringOverrides, type SupportedLocale, type TranslateFn, type TranslationKey, type Translations, type TriggerAction, type TriggerConditionLeaf, type TriggerConditionNode, type TriggerDefinition, type TriggerFrequency, type TriggersRuntimeHandle, type VisitorContext, canCaptureScreenshot, captureScreenshot, createTranslator, detectLocale, evaluate, isRtlLocale, pickFire, resolveLocale, startTriggersRuntime };
package/dist/index.d.ts CHANGED
@@ -123,6 +123,133 @@ interface IdentityData {
123
123
  userHash?: string;
124
124
  customProperties?: Record<string, string | number | boolean>;
125
125
  }
126
+ type TriggerConditionNode = {
127
+ all: TriggerConditionNode[];
128
+ } | {
129
+ any: TriggerConditionNode[];
130
+ } | TriggerConditionLeaf;
131
+ type TriggerConditionLeaf = {
132
+ kind: "url_path";
133
+ op: "equals" | "contains" | "regex" | "starts_with";
134
+ value: string;
135
+ } | {
136
+ kind: "url_query";
137
+ key: string;
138
+ op: "equals" | "contains" | "exists";
139
+ value?: string;
140
+ } | {
141
+ kind: "referrer";
142
+ op: "contains" | "equals" | "regex";
143
+ value: string;
144
+ } | {
145
+ kind: "time_on_page";
146
+ seconds: number;
147
+ } | {
148
+ kind: "scroll_depth";
149
+ percent: number;
150
+ } | {
151
+ kind: "exit_intent";
152
+ } | {
153
+ kind: "device";
154
+ op: "equals";
155
+ value: "mobile" | "tablet" | "desktop";
156
+ } | {
157
+ kind: "browser_language";
158
+ op: "in";
159
+ values: string[];
160
+ } | {
161
+ kind: "visitor_trait";
162
+ key: string;
163
+ op: "equals" | "exists" | "gt" | "lt";
164
+ value?: string | number | boolean;
165
+ } | {
166
+ kind: "return_visit";
167
+ op: "gte" | "eq";
168
+ count: number;
169
+ };
170
+ type TriggerAction = {
171
+ kind: "open_widget";
172
+ } | {
173
+ kind: "send_message";
174
+ message: string;
175
+ } | {
176
+ kind: "show_form";
177
+ } | {
178
+ kind: "open_with_prefill";
179
+ prefill: string;
180
+ };
181
+ type TriggerFrequency = "once_ever" | "once_per_session" | "every_time";
182
+ interface TriggerDefinition {
183
+ id: string;
184
+ priority: number;
185
+ conditions: TriggerConditionNode;
186
+ action: TriggerAction;
187
+ frequency: TriggerFrequency;
188
+ }
189
+ type PreChatFieldKind = "name" | "email" | "phone" | "text" | "textarea" | "select" | "consent";
190
+ type PreChatField = {
191
+ kind: "name";
192
+ required?: boolean;
193
+ label?: string;
194
+ } | {
195
+ kind: "email";
196
+ required?: boolean;
197
+ label?: string;
198
+ validateMx?: boolean;
199
+ } | {
200
+ kind: "phone";
201
+ required?: boolean;
202
+ label?: string;
203
+ } | {
204
+ kind: "text";
205
+ key: string;
206
+ label: string;
207
+ required?: boolean;
208
+ maxLength?: number;
209
+ } | {
210
+ kind: "textarea";
211
+ key: string;
212
+ label: string;
213
+ required?: boolean;
214
+ maxLength?: number;
215
+ } | {
216
+ kind: "select";
217
+ key: string;
218
+ label: string;
219
+ options: Array<{
220
+ value: string;
221
+ label: string;
222
+ }>;
223
+ required?: boolean;
224
+ } | {
225
+ kind: "consent";
226
+ key: string;
227
+ label: string;
228
+ url?: string;
229
+ required: true;
230
+ };
231
+ interface PreChatFormConfig {
232
+ fields: PreChatField[];
233
+ title?: string | null;
234
+ description?: string | null;
235
+ submitLabel: string;
236
+ /** When true, an identified visitor (CustomerHero.identify already called)
237
+ * bypasses the form. */
238
+ skipForIdentified: boolean;
239
+ }
240
+ interface PreChatSubmission {
241
+ name?: string;
242
+ email?: string;
243
+ phone?: string;
244
+ /** Keyed answers from text/textarea/select/consent fields. */
245
+ properties?: Record<string, string | number | boolean>;
246
+ }
247
+ interface ConsentSettings {
248
+ /** When true, all condition kinds are evaluated. When false (default), only
249
+ * direct launcher clicks fire — URL/time/scroll/exit-intent/trait
250
+ * conditions stay dormant. */
251
+ analytics: boolean;
252
+ }
126
253
  interface ChatState {
127
254
  messages: ChatMessage[];
128
255
  isOpen: boolean;
@@ -137,6 +264,26 @@ interface ChatState {
137
264
  locale: SupportedLocale;
138
265
  /** True when the active locale is right-to-left. */
139
266
  isRtl: boolean;
267
+ /** Triggers loaded from the server config (active + in-window). */
268
+ triggers: TriggerDefinition[];
269
+ /** Pre-chat form configuration, if any. */
270
+ preChatForm: PreChatFormConfig | null;
271
+ /**
272
+ * True when the pre-chat form must be shown before the next chat turn.
273
+ * Flipped by trigger actions, by the first sendMessage when a form is
274
+ * configured and not yet submitted, and cleared on submit.
275
+ */
276
+ preChatFormVisible: boolean;
277
+ /** Captured pre-chat submission, sent on the first chat call. */
278
+ preChatSubmission: PreChatSubmission | null;
279
+ /** Per-visitor consent. Until set explicitly, only direct launcher clicks
280
+ * trigger; behavioral conditions stay dormant. */
281
+ consent: ConsentSettings;
282
+ /** ID of the trigger attributed to the next conversation start, if any. */
283
+ pendingTriggerId: string | null;
284
+ /** When set, the host should preload this text into the input. Cleared
285
+ * once the host consumes it (or when the conversation starts). */
286
+ pendingPrefill: string | null;
140
287
  }
141
288
 
142
289
  type Listener = (state: ChatState) => void;
@@ -148,6 +295,10 @@ declare class CustomerHeroChat {
148
295
  private identityData;
149
296
  t: TranslateFn;
150
297
  constructor(config: CustomerHeroChatConfig);
298
+ private triggersRuntime;
299
+ private preChatFormSubmitted;
300
+ private readStoredConsent;
301
+ private writeStoredConsent;
151
302
  setLocale(tag: string): void;
152
303
  private rebuildTranslator;
153
304
  subscribe(listener: Listener): () => void;
@@ -179,6 +330,38 @@ declare class CustomerHeroChat {
179
330
  open(): void;
180
331
  close(): void;
181
332
  reset(): void;
333
+ /** Update visitor consent. Until `analytics: true` is set, only direct
334
+ * launcher clicks fire — URL/time/scroll/exit-intent/trait conditions
335
+ * stay dormant. The setting is persisted in localStorage so revisits
336
+ * don't re-prompt. */
337
+ setConsent(consent: Partial<ConsentSettings>): void;
338
+ /** Set or update visitor traits used by trait-based conditions. The trait
339
+ * values are kept in memory (not persisted) so the integrator decides
340
+ * the source of truth. */
341
+ setTraits(traits: Record<string, string | number | boolean>): void;
342
+ /** Submit pre-chat form answers. Synthesizes a customer record server-side
343
+ * on the next sendMessage. Resumes any pending message that was deferred
344
+ * while the form was open. */
345
+ submitPreChatForm(submission: PreChatSubmission): Promise<void>;
346
+ /** Dismiss the pre-chat form without submitting. The form will reappear
347
+ * on the next sendMessage attempt — call `setConsent` to acknowledge a
348
+ * refusal, or `reset()` to clear pending state. */
349
+ cancelPreChatForm(): void;
350
+ /** Programmatically dispatch the action attached to a trigger. Used by
351
+ * integrators who want to act on a custom button, e.g. an exit-intent
352
+ * modal in their own UI. */
353
+ fireTrigger(triggerId: string): void;
354
+ private pendingMessageAfterPreChat;
355
+ private shouldShowPreChatForm;
356
+ private startTriggersRuntimeIfPossible;
357
+ private handleTriggerAction;
358
+ /** Read and clear the pending prefill (set by an `open_with_prefill`
359
+ * trigger). The host calls this once when mounting the input and seeds
360
+ * its controlled value with the result. */
361
+ consumePendingPrefill(): string | null;
362
+ /** Stop the triggers runtime and detach listeners. Safe to call multiple
363
+ * times; safe to call before the runtime started. */
364
+ destroy(): void;
182
365
  identify(payload: IdentifyPayload): void;
183
366
  }
184
367
 
@@ -202,4 +385,57 @@ declare class ScreenshotUnavailable extends Error {
202
385
  declare function canCaptureScreenshot(): boolean;
203
386
  declare function captureScreenshot(): Promise<Blob>;
204
387
 
205
- export { type ActionConfirmationBlock, type ChatMessage, type ChatState, CustomerHeroChat, type CustomerHeroChatConfig, DEFAULTS, type IdentifyPayload, type IdentityData, type MessageBlock, type MessageRating, type MessageSource, type MessageStatus, type QuickRepliesBlock, type ResolvedConfig, SUPPORTED_LOCALES, ScreenshotCancelled, ScreenshotUnavailable, type StringOverrides, type SupportedLocale, type TranslateFn, type TranslationKey, type Translations, canCaptureScreenshot, captureScreenshot, createTranslator, detectLocale, isRtlLocale, resolveLocale };
388
+ interface VisitorContext {
389
+ url: string;
390
+ queryParams: Record<string, string>;
391
+ referrer: string;
392
+ language: string;
393
+ device: "mobile" | "tablet" | "desktop";
394
+ /** Time spent on the current page (in ms). Pauses while the tab is hidden. */
395
+ timeOnPageMs: number;
396
+ /** Scroll depth as a percentage of the document height (0..100). Tracked as
397
+ * a high-water mark so a quick scroll-up doesn't undo a `scroll_depth`
398
+ * match. */
399
+ scrollPercent: number;
400
+ /** True after the runtime detected a desktop-style exit-intent gesture or
401
+ * the mobile fallback (visibilitychange→hidden after a grace period). */
402
+ exitIntentSeen: boolean;
403
+ /** Number of distinct sessions this visitor has visited the page. */
404
+ returnVisitCount: number;
405
+ /** Custom traits set by the integrator via `setTraits` / `identify`. */
406
+ traits: Record<string, string | number | boolean>;
407
+ }
408
+ declare function evaluate(node: TriggerConditionNode, ctx: VisitorContext): boolean;
409
+ /** Walk `triggers` in priority order (low number = high priority) and return
410
+ * the first one that matches `ctx` and isn't already in `firedSet`. The
411
+ * caller decides what `firedSet` means — once_ever uses long-lived storage,
412
+ * once_per_session uses the in-memory or sessionStorage set, every_time
413
+ * always misses the set so it can re-fire. */
414
+ declare function pickFire(triggers: TriggerDefinition[], ctx: VisitorContext, firedSet: ReadonlySet<string>): TriggerDefinition | null;
415
+
416
+ interface TriggersRuntimeHandle {
417
+ /** Stop all watchers and remove listeners. */
418
+ stop(): void;
419
+ /** Force a re-evaluation (used after the integrator calls setTraits). */
420
+ reevaluate(): void;
421
+ /** Update visitor traits and re-evaluate. */
422
+ setTraits(traits: Record<string, string | number | boolean>): void;
423
+ /** Mark a trigger as fired (used after a direct launcher click acted on
424
+ * a trigger or when the runtime fired one itself). */
425
+ markFired(triggerId: string, frequency: TriggerFrequency): void;
426
+ }
427
+ interface StartTriggersRuntimeOptions {
428
+ chatbotId: string;
429
+ triggers: TriggerDefinition[];
430
+ /** Returns true when the runtime is allowed to fire a trigger. The client
431
+ * uses this to gate on consent — only direct launcher clicks fire until
432
+ * the integrator has called `setConsent({ analytics: true })`. */
433
+ isAllowedToFire(): boolean;
434
+ /** Called when a trigger is selected to fire. */
435
+ onFire(trigger: TriggerDefinition): void;
436
+ /** Optional initial traits seed. */
437
+ initialTraits?: Record<string, string | number | boolean>;
438
+ }
439
+ declare function startTriggersRuntime(options: StartTriggersRuntimeOptions): TriggersRuntimeHandle;
440
+
441
+ export { type ActionConfirmationBlock, type ChatMessage, type ChatState, type ConsentSettings, CustomerHeroChat, type CustomerHeroChatConfig, DEFAULTS, type IdentifyPayload, type IdentityData, type MessageBlock, type MessageRating, type MessageSource, type MessageStatus, type PreChatField, type PreChatFieldKind, type PreChatFormConfig, type PreChatSubmission, type QuickRepliesBlock, type ResolvedConfig, SUPPORTED_LOCALES, ScreenshotCancelled, ScreenshotUnavailable, type StringOverrides, type SupportedLocale, type TranslateFn, type TranslationKey, type Translations, type TriggerAction, type TriggerConditionLeaf, type TriggerConditionNode, type TriggerDefinition, type TriggerFrequency, type TriggersRuntimeHandle, type VisitorContext, canCaptureScreenshot, captureScreenshot, createTranslator, detectLocale, evaluate, isRtlLocale, pickFire, resolveLocale, startTriggersRuntime };