@ada-cx/messaging-sdk 1.0.0-setup.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/README.md +211 -0
- package/dist/client/ada-settings-reader.d.ts +10 -0
- package/dist/client/client-channel-handlers.d.ts +92 -0
- package/dist/client/client-errors.d.ts +7 -0
- package/dist/client/client-frame-constants.d.ts +41 -0
- package/dist/client/client-frame-runtime.d.ts +54 -0
- package/dist/client/client-host-runtime.d.ts +73 -0
- package/dist/client/client-types.d.ts +231 -0
- package/dist/client/client.d.ts +843 -0
- package/dist/client/config-helpers.d.ts +157 -0
- package/dist/client/constants.d.ts +61 -0
- package/dist/client/core-channel-test-harness.d.ts +47 -0
- package/dist/client/embed-interface.d.ts +172 -0
- package/dist/client/embed-lifecycle.d.ts +12 -0
- package/dist/client/fallback-html.d.ts +1 -0
- package/dist/client/frame-manager.d.ts +64 -0
- package/dist/client/frame-styles.d.ts +164 -0
- package/dist/client/frame-visibility.d.ts +53 -0
- package/dist/client/integration-manager.d.ts +73 -0
- package/dist/client/legacy-callback-adapter.d.ts +22 -0
- package/dist/client/mask-element.d.ts +19 -0
- package/dist/client/proactive/index.d.ts +5 -0
- package/dist/client/proactive/proactive-channel.d.ts +33 -0
- package/dist/client/proactive/proactive-runtime.d.ts +65 -0
- package/dist/client/proactive/proactive-utils.d.ts +51 -0
- package/dist/client/sdk-error-reporter.d.ts +22 -0
- package/dist/client/sdk-event-bus.d.ts +116 -0
- package/dist/client/service-worker-notifications.d.ts +1 -0
- package/dist/client/url-business-events.d.ts +19 -0
- package/dist/frame-channel/frame-channel.d.ts +64 -0
- package/dist/frame-channel/frame-child.d.ts +45 -0
- package/dist/frame-channel/index.d.ts +3 -0
- package/dist/frame-channel/types.d.ts +736 -0
- package/dist/helpers/rollout.d.ts +18 -0
- package/dist/host-telemetry.d.ts +15 -0
- package/dist/index.d.ts +8 -0
- package/dist/logger.d.ts +59 -0
- package/dist/mobile-webview-runtime.d.ts +122 -0
- package/dist/npm/build-info.d.cts +17 -0
- package/dist/npm/build-info.d.ts +17 -0
- package/dist/npm/index.cjs +276 -0
- package/dist/npm/index.cjs.map +1 -0
- package/dist/npm/index.d.cts +15 -0
- package/dist/npm/index.d.ts +9 -0
- package/dist/npm/index.js +270 -0
- package/dist/npm/index.js.map +1 -0
- package/dist/npm/loader.d.cts +120 -0
- package/dist/npm/loader.d.ts +120 -0
- package/dist/npm/testing.cjs +155 -0
- package/dist/npm/testing.cjs.map +1 -0
- package/dist/npm/testing.d.cts +39 -0
- package/dist/npm/testing.d.ts +39 -0
- package/dist/npm/testing.js +154 -0
- package/dist/npm/testing.js.map +1 -0
- package/dist/sdk-module-loader.d.ts +1 -0
- package/dist/shared-utils/clusters.d.ts +5 -0
- package/dist/shared-utils/csat.d.ts +116 -0
- package/dist/shared-utils/host-telemetry.d.ts +35 -0
- package/dist/shared-utils/index.d.ts +3 -0
- package/dist/voice/voice-manager.d.ts +120 -0
- package/package.json +77 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/** CSS styles for hidden utility iframes (collapsed intro, etc.) */
|
|
2
|
+
export declare const HIDDEN_FRAME_STYLES = "position:absolute;width:0;height:0;border:0;overflow:hidden;";
|
|
3
|
+
/**
|
|
4
|
+
* Transparent halo (px) the button iframe reserves on every side so the unread
|
|
5
|
+
* badge, which overhangs the button's top-right corner, isn't clipped by the
|
|
6
|
+
* iframe bounds. Must match `BADGE_HALO` in `public/button.html`: button.html
|
|
7
|
+
* adds it to the reported frame size, and `getButtonFrameStyles` pulls the
|
|
8
|
+
* anchor in by the same amount so the 24px visual edge gap is unchanged.
|
|
9
|
+
*/
|
|
10
|
+
export declare const BUTTON_BADGE_HALO = 8;
|
|
11
|
+
/**
|
|
12
|
+
* Transparent band (px) the proactive iframe reserves on every side so the
|
|
13
|
+
* bubble's drop shadow isn't clipped by the iframe bounds. `0 8px 24px` reaches
|
|
14
|
+
* 12px sideways and 20px below the box, and an iframe clips its own document
|
|
15
|
+
* regardless of the element's `overflow`, so anything short of that leaves the
|
|
16
|
+
* shadow ending on a hard line.
|
|
17
|
+
*
|
|
18
|
+
* Must match `.ada-intro-container`'s padding in
|
|
19
|
+
* `packages/integrations/src/intro-page.tsx`: the container paints the band, and
|
|
20
|
+
* {@link getProactiveFrameStyles} pulls the anchors out by the same amount so the
|
|
21
|
+
* content's visual position is unchanged. Same arrangement as
|
|
22
|
+
* {@link BUTTON_BADGE_HALO} and `public/button.html`.
|
|
23
|
+
*/
|
|
24
|
+
export declare const PROACTIVE_SHADOW_HALO = 24;
|
|
25
|
+
/**
|
|
26
|
+
* The gap every floating surface keeps from the viewport edge. Shared so the
|
|
27
|
+
* launcher, the drawer and the proactive bubble cannot drift apart — the bubble
|
|
28
|
+
* lining up with the launcher is the whole point of threading it through.
|
|
29
|
+
*/
|
|
30
|
+
export declare const EDGE_GAP = 24;
|
|
31
|
+
/** Default launcher diameter — `--btn-size` in `public/button.html`. */
|
|
32
|
+
export declare const DEFAULT_LAUNCHER_SIZE = 64;
|
|
33
|
+
/**
|
|
34
|
+
* The launcher frame's height before `button.resize` reports the measured one:
|
|
35
|
+
* the default button plus the badge halo it reserves on each side.
|
|
36
|
+
*/
|
|
37
|
+
export declare const DEFAULT_LAUNCHER_FRAME_HEIGHT: number;
|
|
38
|
+
/**
|
|
39
|
+
* Read the launcher frame's current height off the element the `button.resize`
|
|
40
|
+
* handler sizes. Falls back to the default when the frame hasn't reported yet —
|
|
41
|
+
* a proactive can be shown before the launcher measures itself.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getLauncherFrameHeight(launcher: HTMLElement | null | undefined): number;
|
|
44
|
+
export declare const VIEWPORT_HEIGHT_CSS_VAR = "--ada-messaging-viewport-height";
|
|
45
|
+
/** Legacy embed-2's drawer durations (`ChatFrame/index.tsx` `:389` and `:178`). */
|
|
46
|
+
export declare const CHAT_OPEN_TRANSITION_MS = 300;
|
|
47
|
+
export declare const CHAT_CLOSE_TRANSITION_MS = 200;
|
|
48
|
+
/**
|
|
49
|
+
* The closed drawer's resting styles — used both to mount the core frame and to
|
|
50
|
+
* park it after a close. Collapsed to 0×0 *and* carrying the animation's start
|
|
51
|
+
* values: a transition needs a committed start value to interpolate from, so a
|
|
52
|
+
* frame resting at plain {@link HIDDEN_FRAME_STYLES} (`opacity` 1, no
|
|
53
|
+
* `transform`) would snap open however the open styles are written.
|
|
54
|
+
*/
|
|
55
|
+
export declare const CHAT_FRAME_COLLAPSED_STYLES = "position:absolute;width:0;height:0;border:0;overflow:hidden;opacity:0;transform:translateY(100px);";
|
|
56
|
+
/**
|
|
57
|
+
* Ada's own stacking scale, named so the scrim's position is declared alongside
|
|
58
|
+
* the frames it has to sit under rather than inferred from them. The invariant
|
|
59
|
+
* has two halves — the scrim must stay below every frame, and above the band
|
|
60
|
+
* host chrome occupies — so it is pinned by `frame-styles.test.ts` rather than
|
|
61
|
+
* derived: a `Math.min` over the frames would satisfy the first half while a
|
|
62
|
+
* future low-stacked frame silently dragged the scrim under host content.
|
|
63
|
+
*
|
|
64
|
+
* `scrim` is embed-2's `.drawer-mask` value.
|
|
65
|
+
*
|
|
66
|
+
* `proactive` sits one below `launcher` deliberately. The proactive frame reserves
|
|
67
|
+
* a transparent shadow halo that reaches down over the launcher, and an iframe is
|
|
68
|
+
* atomic for hit-testing — a click anywhere in its box is consumed by its own
|
|
69
|
+
* document and never falls through to what is underneath, whatever
|
|
70
|
+
* `pointer-events` that document sets. At an equal z-index the winner would be DOM
|
|
71
|
+
* order, including a lazily mounted `intro` frame appended after `button`,
|
|
72
|
+
* so the halo would paint over the launcher and swallow clicks on its top edge
|
|
73
|
+
* while a bubble is showing — exactly when the user is most likely to reach for it.
|
|
74
|
+
*/
|
|
75
|
+
export declare const FRAME_Z_INDEX: {
|
|
76
|
+
readonly scrim: 9998;
|
|
77
|
+
readonly proactive: 9999;
|
|
78
|
+
readonly launcher: 10000;
|
|
79
|
+
readonly chat: 10001;
|
|
80
|
+
readonly chatMobile: 10010;
|
|
81
|
+
readonly hostViewport: 10020;
|
|
82
|
+
};
|
|
83
|
+
/** Legacy Embed2's mobile signal: fixed for the page lifetime and UA-based. */
|
|
84
|
+
export declare function isMobileViewport(): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Legacy Generative Chat's content-layout signal. Unlike Embed2's outer drawer
|
|
87
|
+
* geometry above, Chat included iPad when choosing mobile quick-reply layouts.
|
|
88
|
+
*/
|
|
89
|
+
export declare function isMobileContentLayout(): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* A media query can't be expressed in an inline `style` attribute, and injecting
|
|
92
|
+
* a `<style>` element is not reliable on a host page whose CSP omits
|
|
93
|
+
* `'unsafe-inline'` — so the drawer's reduced-motion branch is resolved in JS.
|
|
94
|
+
* Degrades to "animate" when `matchMedia` is unavailable, matching
|
|
95
|
+
* {@link isMobileViewport}.
|
|
96
|
+
*/
|
|
97
|
+
export declare function prefersReducedMotion(): boolean;
|
|
98
|
+
export declare function syncFrameViewportHeight(element: HTMLElement): () => void;
|
|
99
|
+
/**
|
|
100
|
+
* CSS styles for the button launcher iframe.
|
|
101
|
+
*
|
|
102
|
+
* The iframe starts invisible (opacity:0) and at 0×0 size. Once the
|
|
103
|
+
* button.html content renders and measures itself, it sends a
|
|
104
|
+
* "button.resize" postMessage with its dimensions. The SDK then
|
|
105
|
+
* resizes the iframe to fit and fades it in.
|
|
106
|
+
*
|
|
107
|
+
* The reported size is intentionally oversized by `BUTTON_BADGE_HALO` on each
|
|
108
|
+
* side so the overhanging unread badge isn't clipped by the iframe bounds, and
|
|
109
|
+
* the anchor is pulled in by the same amount to preserve the 24px visual edge
|
|
110
|
+
* gap. The halo is an inert band around the launcher (matching legacy chat,
|
|
111
|
+
* which reserves an even larger buffer) — it is not click-through.
|
|
112
|
+
*/
|
|
113
|
+
export declare function getButtonFrameStyles(align: "left" | "right", _isText: boolean, isParentElement: boolean): string;
|
|
114
|
+
/**
|
|
115
|
+
* CSS styles for the open chat widget iframe.
|
|
116
|
+
*
|
|
117
|
+
* @param align - "left" | "right" (from client config)
|
|
118
|
+
* @param isParentElement - true when the SDK is mounted inside a host element
|
|
119
|
+
* @param isMobile - true for legacy's UA-detected mobile form factor;
|
|
120
|
+
* renders the drawer edge-to-edge full screen instead of the
|
|
121
|
+
* floating desktop card.
|
|
122
|
+
* @param animate - false reproduces the pre-animation styles exactly (reduced motion,
|
|
123
|
+
* and any restyle that must land instantly). Geometry is never
|
|
124
|
+
* transitioned — only `opacity`/`transform` — so the drawer's box
|
|
125
|
+
* still snaps to full size while the content slides and fades in.
|
|
126
|
+
*/
|
|
127
|
+
export declare function getChatFrameStyles(align: "left" | "right", isParentElement: boolean, isMobile?: boolean, animate?: boolean): string;
|
|
128
|
+
/**
|
|
129
|
+
* Temporary host-viewport geometry for content that needs more room than the
|
|
130
|
+
* floating drawer (for example, an image lightbox). This is deliberately an
|
|
131
|
+
* SDK-owned iframe style, not a host-DOM portal: old SDKs ignore the request,
|
|
132
|
+
* and parent-element/headless clients never apply it.
|
|
133
|
+
*
|
|
134
|
+
* `100%` and the synchronized viewport-height custom property avoid the mobile
|
|
135
|
+
* browser chrome traps of `100vw`/`100vh`. Every declaration needed to restore
|
|
136
|
+
* an interactive frame is explicit because `applyFrameStyle` replaces the
|
|
137
|
+
* complete inline style block.
|
|
138
|
+
*/
|
|
139
|
+
export declare function getHostViewportFrameStyles(): string;
|
|
140
|
+
/**
|
|
141
|
+
* The drawer's styles for the duration of the close animation: the *open*
|
|
142
|
+
* geometry, so there is a box to animate, plus the hidden end state.
|
|
143
|
+
*
|
|
144
|
+
* `visibility` flips only after the transition completes (`0ms linear` with a
|
|
145
|
+
* matching delay, legacy embed-2's shape) and `pointer-events:none` applies at
|
|
146
|
+
* once, so a frame still holding open geometry is inert over the customer's page
|
|
147
|
+
* even if the caller's collapse never lands.
|
|
148
|
+
*/
|
|
149
|
+
export declare function getChatFrameClosingStyles(align: "left" | "right", isMobile?: boolean): string;
|
|
150
|
+
/**
|
|
151
|
+
* CSS styles for the proactive message intro iframe.
|
|
152
|
+
*
|
|
153
|
+
* Returns `HIDDEN_FRAME_STYLES` in parentElement mode because proactive
|
|
154
|
+
* popups are suppressed when the SDK is embedded in a host element.
|
|
155
|
+
*
|
|
156
|
+
* The anchors are the *visual* gaps minus {@link PROACTIVE_SHADOW_HALO}, since
|
|
157
|
+
* the container inside the frame insets the content by the halo. `EDGE_GAP`
|
|
158
|
+
* matches `getButtonFrameStyles` so the bubble and the launcher share a right
|
|
159
|
+
* edge.
|
|
160
|
+
*
|
|
161
|
+
* @param align - "left" | "right" (from client config)
|
|
162
|
+
* @param isParentElement - true when the SDK is mounted inside a host element
|
|
163
|
+
*/
|
|
164
|
+
export declare function getProactiveFrameStyles(align: "left" | "right", isParentElement: boolean, launcherFrameHeight?: number): string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a frame carrying this style block is invisible to a sighted user. The SDK
|
|
3
|
+
* expresses that three ways and only three — collapsing to 0×0, fading to
|
|
4
|
+
* `opacity: 0`, and the closing drawer's `visibility: hidden` — so the style block
|
|
5
|
+
* is the whole answer.
|
|
6
|
+
*
|
|
7
|
+
* Read from the declaration string rather than the element's parsed
|
|
8
|
+
* `style.width`/`style.opacity`, because jsdom drops every declaration after an
|
|
9
|
+
* `overflow` shorthand: the launcher's own mount style parses to an empty
|
|
10
|
+
* `CSSStyleDeclaration` there, so an element-based reading would be right in a
|
|
11
|
+
* browser and silently wrong in every unit test.
|
|
12
|
+
*
|
|
13
|
+
* A block that declares the *end* of a transition rather than the frame's current
|
|
14
|
+
* appearance is not something the string can distinguish — those callers write the
|
|
15
|
+
* style and set exposure themselves.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isHiddenFrameStyle(style: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Whether the frame has been sized by something other than its collapsed mount
|
|
20
|
+
* style. The launcher mounts at 0×0 and only becomes a real control once
|
|
21
|
+
* `button.resize` reports a measurement, so exposing it before that publishes an
|
|
22
|
+
* empty node the chatter cannot reach.
|
|
23
|
+
*/
|
|
24
|
+
export declare function hasMeasuredSize(frame: HTMLElement | null | undefined): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Add or drop a frame's `aria-hidden`, keeping its focusability in step.
|
|
27
|
+
*
|
|
28
|
+
* `aria-hidden` alone leaves the frame's own controls in the tab order, so a
|
|
29
|
+
* keyboard user lands on something their screen reader has been told to ignore
|
|
30
|
+
* (axe `aria-hidden-focus`) — `inert` is what takes the subtree out of sequential
|
|
31
|
+
* focus, and it crosses into a frame's nested document where `tabindex` cannot.
|
|
32
|
+
*
|
|
33
|
+
* Where `inert` is unimplemented, `visibility: hidden` is the fallback: a 0×0 or
|
|
34
|
+
* faded frame still offers its nested controls to Tab, and `visibility` is the one
|
|
35
|
+
* property that removes a whole subtree — nested browsing context included — from
|
|
36
|
+
* both the tree and sequential focus. It costs the fade/slide on those browsers,
|
|
37
|
+
* which is the right trade against a reader-invisible control being reachable.
|
|
38
|
+
*
|
|
39
|
+
* Exposure drops the attribute rather than setting `aria-hidden="false"`, which
|
|
40
|
+
* cannot override a hidden ancestor and so reads as an opt-back-in it can never be.
|
|
41
|
+
*/
|
|
42
|
+
export declare function setFrameHidden(frame: HTMLElement | null | undefined, hidden: boolean): void;
|
|
43
|
+
/**
|
|
44
|
+
* Write a frame's style block and bring its accessibility exposure with it.
|
|
45
|
+
*
|
|
46
|
+
* Derived from the style rather than passed alongside it because the two must not
|
|
47
|
+
* be able to disagree: a collapsed frame left in the tree offers a reader a control
|
|
48
|
+
* that cannot be operated, and a visible frame kept out of it is invisible to
|
|
49
|
+
* assistive technology while the chatter can see it. Frames whose visibility changes
|
|
50
|
+
* without a new style block — the launcher, which is faded by property writes —
|
|
51
|
+
* call {@link setFrameHidden} directly.
|
|
52
|
+
*/
|
|
53
|
+
export declare function applyFrameStyle(frame: HTMLElement | null | undefined, style: string): void;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { FrameChannel } from "../frame-channel/index.js";
|
|
2
|
+
import type { IntegrationCommand, IntegrationFrameId, TrackedIntegrationCommand } from "./config-helpers.js";
|
|
3
|
+
export interface IntegrationManagerDeps {
|
|
4
|
+
/** Build a URL pointing to an asset file within a given package directory. */
|
|
5
|
+
buildAssetUrl: (dir: "integrations", file: string) => string;
|
|
6
|
+
/** Container element into which integration iframes are appended. */
|
|
7
|
+
container: HTMLElement;
|
|
8
|
+
/** Forward a message to the core frame channel. */
|
|
9
|
+
sendToCore: (type: string, payload: unknown) => void;
|
|
10
|
+
/** Publish a named SDK event to host-page subscribers. */
|
|
11
|
+
routePublishedEvent: (key: string, data: unknown) => void;
|
|
12
|
+
/** Deliver the current SDK config to a newly-connected integration channel. */
|
|
13
|
+
deliverConfig: (channel: FrameChannel) => void;
|
|
14
|
+
/** Resolve the absolute origin for a mounted iframe (null if unavailable). */
|
|
15
|
+
getFrameOrigin: (iframe: HTMLIFrameElement) => string | null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Manages the lifecycle of integration iframes (zendesk, zendeskMessaging,
|
|
19
|
+
* oauth, csat) and the command bus that routes commands to them.
|
|
20
|
+
*
|
|
21
|
+
* Designed with constructor dependency injection so it can be tested in
|
|
22
|
+
* isolation without requiring a full `AdaMessagingClient` instance.
|
|
23
|
+
*/
|
|
24
|
+
export declare class IntegrationManager {
|
|
25
|
+
private readonly _deps;
|
|
26
|
+
private readonly _frames;
|
|
27
|
+
private readonly _channels;
|
|
28
|
+
private readonly _ready;
|
|
29
|
+
private readonly _loadTimers;
|
|
30
|
+
private readonly _pendingCommands;
|
|
31
|
+
private readonly _trackedCommands;
|
|
32
|
+
private readonly _trackedCommandTimers;
|
|
33
|
+
/** Terminal command ids whose eventual late receipts should be ignored. */
|
|
34
|
+
private readonly _settledCommandIds;
|
|
35
|
+
private _commandCounter;
|
|
36
|
+
private _activePlatform;
|
|
37
|
+
private _destroyed;
|
|
38
|
+
private readonly _loadHandlers;
|
|
39
|
+
constructor(deps: IntegrationManagerDeps);
|
|
40
|
+
/**
|
|
41
|
+
* Dispatch a raw integration command payload (as received from the core
|
|
42
|
+
* frame via `sdk.integration.command`). Validates, normalizes, routes to
|
|
43
|
+
* the appropriate iframe, and emits `ada:integration:command` for public
|
|
44
|
+
* integration work.
|
|
45
|
+
*/
|
|
46
|
+
dispatch(rawPayload: unknown): void;
|
|
47
|
+
/**
|
|
48
|
+
* Wire the frame channel for a freshly-loaded integration iframe.
|
|
49
|
+
* Called by the SDK after the iframe's `load` event fires.
|
|
50
|
+
*/
|
|
51
|
+
onFrameLoaded(frameId: IntegrationFrameId, iframe: HTMLIFrameElement): void;
|
|
52
|
+
/** Disconnect all channels, cancel all timers, and clear all state. */
|
|
53
|
+
teardown(): void;
|
|
54
|
+
/** Clear identity-bound integration state while keeping the manager reusable. */
|
|
55
|
+
resetForIdentityChange(): void;
|
|
56
|
+
private _clearRuntimeState;
|
|
57
|
+
private _ensureFrame;
|
|
58
|
+
private _mountFrame;
|
|
59
|
+
private _failPendingCommandsForFrame;
|
|
60
|
+
private _queueCommand;
|
|
61
|
+
private _removePending;
|
|
62
|
+
private _clearTracked;
|
|
63
|
+
private _rememberSettledCommandId;
|
|
64
|
+
private _trackCommand;
|
|
65
|
+
private _flush;
|
|
66
|
+
private _handleResult;
|
|
67
|
+
private _emitResult;
|
|
68
|
+
private _handleEvent;
|
|
69
|
+
/** @internal — used by client.test.ts integration buffering tests */
|
|
70
|
+
get _integrationPendingCommands(): Map<IntegrationFrameId, IntegrationCommand[]>;
|
|
71
|
+
/** @internal — used by client.test.ts integration buffering tests */
|
|
72
|
+
get _trackedIntegrationCommands(): Map<string, TrackedIntegrationCommand>;
|
|
73
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AdaSdkEventCallback } from "./client-types.js";
|
|
2
|
+
export interface AdaptLegacyCallbacksOptions {
|
|
3
|
+
/** Raw `window.adaSettings` object (may contain any shape). */
|
|
4
|
+
adaSettings: Record<string, unknown>;
|
|
5
|
+
/** The `eventCallbacks` map from the constructor config (if any). */
|
|
6
|
+
constructorEventCallbacks: Record<string, AdaSdkEventCallback> | undefined;
|
|
7
|
+
/** Bound reference to `AdaMessagingClient.subscribeEvent`. */
|
|
8
|
+
subscribeEvent: (key: string, callback: AdaSdkEventCallback) => number;
|
|
9
|
+
}
|
|
10
|
+
export interface AdaptLegacyCallbacksResult {
|
|
11
|
+
/**
|
|
12
|
+
* The `zdChatterAuthCallback` function extracted from adaSettings, or
|
|
13
|
+
* `null` if not present / not a function. The caller stores it separately
|
|
14
|
+
* and invokes it on demand (request-response pattern, not an event).
|
|
15
|
+
*/
|
|
16
|
+
zdChatterAuthCallback: ((callback: (token: string) => void) => void) | null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Registers applicable adaSettings callbacks as `subscribeEvent` subscribers
|
|
20
|
+
* and returns the extracted `zdChatterAuthCallback`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function adaptLegacyCallbacks(options: AdaptLegacyCallbacksOptions): AdaptLegacyCallbacksResult;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface MaskElementHandle {
|
|
2
|
+
/** Drawer open/closed. The scrim renders only while open and off mobile. */
|
|
3
|
+
setOpen(isOpen: boolean): void;
|
|
4
|
+
destroy(): void;
|
|
5
|
+
}
|
|
6
|
+
export interface CreateMaskElementOptions {
|
|
7
|
+
/** The SDK's frame container, which also scopes teardown. */
|
|
8
|
+
container: HTMLElement;
|
|
9
|
+
/** Invoked on a scrim click or an Escape press while the scrim is showing. */
|
|
10
|
+
onDismiss: () => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The host-page scrim behind an open chat drawer, for hosts that opt in with
|
|
14
|
+
* `hideMask: false`.
|
|
15
|
+
*
|
|
16
|
+
* Mobile form factor uses legacy's page-lifetime UA signal, so `setOpen()` can
|
|
17
|
+
* render synchronously without a resize/breakpoint subscription.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createMaskElement(options: CreateMaskElementOptions): MaskElementHandle;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { IntroChannelDependencies } from "./proactive-channel.js";
|
|
2
|
+
export { setupIntroChannelHandlers } from "./proactive-channel.js";
|
|
3
|
+
export type { IntroDisplayKind, IntroShowingState, ProactiveRuntimeDependencies, } from "./proactive-runtime.js";
|
|
4
|
+
export { evaluateProactiveConditionsRuntime, matchesIntroPathRuntime, onLocationChangeRuntime, openCtaUrlRuntime, scheduleIntroRuntime, } from "./proactive-runtime.js";
|
|
5
|
+
export { findMatchingProactives, isProactiveShown, markProactiveShown, markProactiveShownForUser, } from "./proactive-utils.js";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { FrameChannel, FrameRegistry, StartupConfig } from "../../frame-channel/index.js";
|
|
2
|
+
export interface IntroChannelDependencies {
|
|
3
|
+
channel: FrameChannel;
|
|
4
|
+
frames: FrameRegistry;
|
|
5
|
+
getStartupConfig: () => StartupConfig | null;
|
|
6
|
+
sendToCore: (type: string, payload: unknown) => void;
|
|
7
|
+
routePublishedEvent: (key: string, data: unknown) => void;
|
|
8
|
+
open: () => void;
|
|
9
|
+
/** Open after an exact proactive click without clearing its armed attribution. */
|
|
10
|
+
openFromProactiveEngagement?: () => void;
|
|
11
|
+
setIntroShowing: (state: "greeting" | "proactive" | null) => void;
|
|
12
|
+
getCurrentIntroSurface?: () => {
|
|
13
|
+
kind: "greeting";
|
|
14
|
+
displayId: number;
|
|
15
|
+
} | {
|
|
16
|
+
kind: "proactive";
|
|
17
|
+
campaignKey: string;
|
|
18
|
+
surfaceId: number;
|
|
19
|
+
intentId?: number;
|
|
20
|
+
} | null;
|
|
21
|
+
acknowledgeProactiveShown?: (campaignKey: string, surfaceId: number) => boolean;
|
|
22
|
+
/** Mark current-session intro metadata when an accepted proactive is removed. */
|
|
23
|
+
markIntroShown?: () => void;
|
|
24
|
+
clearCurrentIntroSurface?: () => void;
|
|
25
|
+
/** Retire an acknowledged bubble so a later open cannot publish it as opened. */
|
|
26
|
+
clearShownCampaign?: () => void;
|
|
27
|
+
/** Open a proactive bubble's branded CTA URL from the host-page context. The
|
|
28
|
+
* intro frame is sandboxed without allow-popups, so it cannot navigate itself;
|
|
29
|
+
* it delegates the open to the SDK running on the host page. */
|
|
30
|
+
openCtaUrl?: (url: string, openInNewTab: boolean) => void;
|
|
31
|
+
}
|
|
32
|
+
/** Wire all message handlers for the intro (proactive messages + greeting) frame. */
|
|
33
|
+
export declare function setupIntroChannelHandlers(deps: IntroChannelDependencies): void;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { FrameChannel, FrameName, FrameRegistry, StartupConfig } from "../../frame-channel/index.js";
|
|
2
|
+
export type IntroShowingState = "greeting" | "proactive" | null;
|
|
3
|
+
export type IntroDisplayKind = "greeting" | "proactive";
|
|
4
|
+
export interface ProactiveRuntimeDependencies {
|
|
5
|
+
handle: string;
|
|
6
|
+
language?: string;
|
|
7
|
+
parentElement: HTMLElement | null;
|
|
8
|
+
/** Whether the resolved host layout currently permits launcher/intro chrome. */
|
|
9
|
+
hasFloatingWidgetChrome: boolean;
|
|
10
|
+
channels: Map<FrameName, FrameChannel>;
|
|
11
|
+
frames: FrameRegistry;
|
|
12
|
+
getAlign: () => "left" | "right";
|
|
13
|
+
getIsChatOpen: () => boolean;
|
|
14
|
+
getHasChatOpened: () => boolean;
|
|
15
|
+
getHasIntroShown: () => boolean;
|
|
16
|
+
setHasIntroShown: (shown: boolean) => void;
|
|
17
|
+
/** Mark legacy's sticky `wasIntroShown` chatter metadata fact. */
|
|
18
|
+
markIntroShown: () => void;
|
|
19
|
+
resetIntroShownForNavigation: () => void;
|
|
20
|
+
sendToCore: (type: string, payload: unknown) => void;
|
|
21
|
+
routePublishedEvent: (key: string, data: unknown) => void;
|
|
22
|
+
getStartupConfig: () => StartupConfig | null;
|
|
23
|
+
getIntroTimer: () => ReturnType<typeof setTimeout> | null;
|
|
24
|
+
setIntroTimer: (timer: ReturnType<typeof setTimeout> | null) => void;
|
|
25
|
+
getProactiveTimers: () => Set<ReturnType<typeof setTimeout>>;
|
|
26
|
+
/** Retire all pre-chat content on a real navigation. */
|
|
27
|
+
retirePreChatSurface: () => void;
|
|
28
|
+
/** Allocate the ordering token carried through SDK -> core -> SDK. */
|
|
29
|
+
beginProactiveIntent: () => number;
|
|
30
|
+
/** True while no later SDK intent or navigation has superseded this one. */
|
|
31
|
+
isCurrentProactiveIntent: (intentId: number) => boolean;
|
|
32
|
+
setIntroShowing: (state: IntroShowingState) => void;
|
|
33
|
+
getLastEvaluatedUrl: () => string;
|
|
34
|
+
setLastEvaluatedUrl: (url: string) => void;
|
|
35
|
+
/** Deliver now when intro is ready, otherwise retain only the latest display. */
|
|
36
|
+
showOrQueueIntroDisplay: (kind: IntroDisplayKind, display: () => void, onDropped?: () => void) => void;
|
|
37
|
+
/** Deliver an emoji after the button channel is ready, retaining only latest. */
|
|
38
|
+
showOrQueueEmojiDisplay: (display: () => void) => void;
|
|
39
|
+
/** Mount the card-based intro runtime once a real surface has passed its gates. */
|
|
40
|
+
ensureIntroFrame: () => void;
|
|
41
|
+
beginGreetingDisplay: () => number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Open a proactive bubble's branded CTA URL. The URL round-trips through the
|
|
45
|
+
* sandboxed intro frame before reaching the host page, so re-validate the
|
|
46
|
+
* destination with the shared credential-free navigation policy before opening —
|
|
47
|
+
* never open a `javascript:`/`data:`/relative URL. `open` is
|
|
48
|
+
* injected (`window.open`) so this stays pure and unit-testable.
|
|
49
|
+
*/
|
|
50
|
+
export declare function openCtaUrlRuntime(url: string, openInNewTab: boolean, open: (url: string, target: string, features: string) => unknown): void;
|
|
51
|
+
/** Match an intro path pattern against the current pathname. Supports trailing `*` wildcard. */
|
|
52
|
+
export declare function matchesIntroPathRuntime(pattern: string, pathname: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Schedule the intro greeting popup to display after the configured delay.
|
|
55
|
+
* Skipped when: chat has already opened, this client instance already showed it,
|
|
56
|
+
* or paths don't match.
|
|
57
|
+
*/
|
|
58
|
+
export declare function scheduleIntroRuntime(deps: ProactiveRuntimeDependencies, intro: NonNullable<StartupConfig["intro"]>): void;
|
|
59
|
+
/** Called on every SPA navigation. Re-evaluates intro and proactive conditions. */
|
|
60
|
+
export declare function onLocationChangeRuntime(deps: ProactiveRuntimeDependencies): void;
|
|
61
|
+
/**
|
|
62
|
+
* Evaluate URL-triggered proactive conversation conditions.
|
|
63
|
+
* Called on every SPA location change.
|
|
64
|
+
*/
|
|
65
|
+
export declare function evaluateProactiveConditionsRuntime(deps: ProactiveRuntimeDependencies, ignoreFrequency?: boolean, surfaceAlreadyRetired?: boolean): boolean;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { StartupConfigProactiveConversation } from "../../frame-channel/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Compile an admin-authored URL regex within the existing defensive length ceiling.
|
|
4
|
+
* Successful and rejected compiles share a bounded cache across SPA evaluations.
|
|
5
|
+
* Native matching remains the legacy JavaScript contract for ordinary patterns.
|
|
6
|
+
* A conservative nested-repetition family is rejected because it can freeze the
|
|
7
|
+
* host page with only a few dozen URL characters (for example, `(a+)+`). Repeated
|
|
8
|
+
* alternation fails closed for the same reason. A small fixed repeat around
|
|
9
|
+
* flat, non-alternating optional tokens remains accepted because its optional-decision
|
|
10
|
+
* count is statically capped above. This heuristic is not a complete ReDoS proof.
|
|
11
|
+
*/
|
|
12
|
+
export declare function compileCachedUrlRegex(source: string): RegExp | null;
|
|
13
|
+
/**
|
|
14
|
+
* Match one URL trigger condition, per-type, against the host page URL — mirroring
|
|
15
|
+
* legacy's `evalUrlMatchTriggerCondition`: `ends-with` and `equals` ignore query params,
|
|
16
|
+
* while `contains` and `regex` deliberately see the full URL including query params.
|
|
17
|
+
*
|
|
18
|
+
* The two differ on trailing slashes, and NOT symmetrically:
|
|
19
|
+
* - `equals` treats one as insignificant on either side (EXP-462 — docs.ada.cx documents
|
|
20
|
+
* `.../checkout` matching `.../checkout/`, so the matcher conforms to the docs).
|
|
21
|
+
* - `ends-with` tolerates one only on the PAGE url. A condition authored as `/checkout/`
|
|
22
|
+
* still will not match a page ending `/checkout`. That asymmetry is legacy's and is
|
|
23
|
+
* left alone deliberately: the docs promise nothing about slashes for `Ends With`, so
|
|
24
|
+
* there is no documented behaviour to conform to, and stripping the condition side
|
|
25
|
+
* needs a root guard (`"/"` would strip to `""`, which every URL ends with).
|
|
26
|
+
*
|
|
27
|
+
* An unknown type never matches, so a condition legacy cannot express (e.g.
|
|
28
|
+
* `starts-with`) cannot fire a proactive here either.
|
|
29
|
+
*/
|
|
30
|
+
export declare function matchesUrlTriggerCondition(type: string, condValue: string, href: string): boolean;
|
|
31
|
+
interface ProactiveMatch {
|
|
32
|
+
key: string;
|
|
33
|
+
entry: StartupConfigProactiveConversation;
|
|
34
|
+
}
|
|
35
|
+
/** Select the final eligible unranked match, or the next ranked match. */
|
|
36
|
+
export declare function findMatchingProactives(proactives: Record<string, StartupConfigProactiveConversation> | null, href: string, handle: string): ProactiveMatch[];
|
|
37
|
+
/** Returns true if the proactive conversation has already been shown this session. */
|
|
38
|
+
export declare function isProactiveShown(key: string, handle: string): boolean;
|
|
39
|
+
/** Record that a proactive conversation has been shown this session. */
|
|
40
|
+
export declare function markProactiveShown(key: string, handle: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Returns true if the proactive conversation has already been shown to this user.
|
|
43
|
+
* Backed by localStorage so suppression survives tab close (once-per-user), under
|
|
44
|
+
* a key distinct from the once-per-session sessionStorage key.
|
|
45
|
+
*/
|
|
46
|
+
export declare function isProactiveShownForUser(key: string, handle: string): boolean;
|
|
47
|
+
/** Record that a proactive conversation has been shown to this user (persists across sessions). */
|
|
48
|
+
export declare function markProactiveShownForUser(key: string, handle: string): void;
|
|
49
|
+
/** Record a ranked URL-triggered proactive so the next visit advances. */
|
|
50
|
+
export declare function markRankedProactiveShown(key: string, handle: string): void;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK error reporter.
|
|
3
|
+
*
|
|
4
|
+
* Captures errors that originate from Ada Messaging scripts running on the
|
|
5
|
+
* host page and forwards them to the core iframe via sendToCore so that core
|
|
6
|
+
* can route them to Sentry.
|
|
7
|
+
*
|
|
8
|
+
* Filtering strategy (host-page safety):
|
|
9
|
+
* - `error` events: when `event.filename` is non-empty, check it against our
|
|
10
|
+
* assets origin and skip errors from customer scripts. When filename is
|
|
11
|
+
* empty (cross-origin scripts or browser-sanitised events), we forward
|
|
12
|
+
* unconditionally as "opaque SDK context" — we can't attribute it but it
|
|
13
|
+
* may still reflect a crash in our code triggered by a 3rd-party call.
|
|
14
|
+
* Note: inline scripts on the host page also produce an empty filename;
|
|
15
|
+
* those will be forwarded but will not contain Ada stack frames and will
|
|
16
|
+
* appear as attributionless errors in Sentry.
|
|
17
|
+
* - `unhandledrejection` events: check the rejection's stack trace for our
|
|
18
|
+
* assets origin; skip rejections with no stack or a stack that doesn't
|
|
19
|
+
* reference our origin (can't attribute them to our code).
|
|
20
|
+
* - `ada:error` CustomEvents: always ours — forwarded with full detail.
|
|
21
|
+
*/
|
|
22
|
+
export declare function setupSdkErrorReporter(sendToCore: (type: string, payload: unknown) => void): () => void;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { AdaSdkEventCallback, WindowInfo } from "./client-types.js";
|
|
2
|
+
/**
|
|
3
|
+
* SdkEventBus — owns the pub/sub subscriber registry and getInfo() promise tracking.
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* - subscribeEvent / unsubscribeEvent: namespace-matched event routing
|
|
7
|
+
* - routePublishedEvent: distribute published events to matching subscribers
|
|
8
|
+
* - requestInfo: issue sdk.info.get requests and resolve them asynchronously
|
|
9
|
+
* - teardown: flush pending info promises and clear all state
|
|
10
|
+
*/
|
|
11
|
+
export declare class SdkEventBus {
|
|
12
|
+
private readonly _eventSubscribers;
|
|
13
|
+
private _nextSubscriberId;
|
|
14
|
+
private readonly _infoRequestCallbacks;
|
|
15
|
+
private readonly _infoRequestTimers;
|
|
16
|
+
private _infoRequestCounter;
|
|
17
|
+
private readonly _dataRequests;
|
|
18
|
+
/** Subscribe to an event key. Returns a stable subscription ID. */
|
|
19
|
+
subscribe(key: string, callback: AdaSdkEventCallback): number;
|
|
20
|
+
/**
|
|
21
|
+
* Subscribe to broad published events. Transcript-bearing events
|
|
22
|
+
* (`ada:message:sent` and `ada:message:received`) require exact
|
|
23
|
+
* subscribeEvent listeners and are not delivered to wildcard subscribers.
|
|
24
|
+
* Designed for bridge adapters (e.g. React Native, iOS, Android) that need to
|
|
25
|
+
* forward SDK events to native code.
|
|
26
|
+
*
|
|
27
|
+
* Returns a stable subscription ID that can be passed to unsubscribe().
|
|
28
|
+
*/
|
|
29
|
+
subscribeAll(callback: (key: string, data: unknown) => void): number;
|
|
30
|
+
/** Cancel a subscription registered via subscribe() or subscribeAll(). */
|
|
31
|
+
unsubscribe(id: number): void;
|
|
32
|
+
/** Route a published event key to all matching subscribers. */
|
|
33
|
+
routePublishedEvent(key: string, data: unknown): void;
|
|
34
|
+
/** Whether a published event key would currently be observed by any subscriber. */
|
|
35
|
+
hasSubscribersFor(key: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Whether the exact event key has a direct subscribeEvent listener.
|
|
38
|
+
*
|
|
39
|
+
* Wildcard (`subscribeAll`) subscribers are intentionally excluded: the
|
|
40
|
+
* transcript-bearing events (`ada:message:sent`/`ada:message:received`)
|
|
41
|
+
* require an explicit per-key opt-in so conversation content is never
|
|
42
|
+
* delivered to generic event loggers that subscribe to everything.
|
|
43
|
+
*/
|
|
44
|
+
hasExactSubscriberFor(key: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Request current window info from the core frame.
|
|
47
|
+
*
|
|
48
|
+
* `sendFn` dispatches the sdk.info.get message to core.
|
|
49
|
+
* `getFallbackInfo` provides local state if core does not respond within 5 s.
|
|
50
|
+
*
|
|
51
|
+
* The Maps exposed by `infoRequestCallbacks` and `infoRequestTimers` are
|
|
52
|
+
* passed directly to `setupCoreChannelHandlers` so the channel handler can
|
|
53
|
+
* resolve the promise without going through an additional layer.
|
|
54
|
+
*/
|
|
55
|
+
requestInfo(sendFn: (type: string, payload: unknown) => void, getFallbackInfo: () => WindowInfo): Promise<WindowInfo>;
|
|
56
|
+
/**
|
|
57
|
+
* Exposed so CoreChannelDependencies can resolve and cancel info requests
|
|
58
|
+
* directly without additional indirection.
|
|
59
|
+
*/
|
|
60
|
+
get infoRequestCallbacks(): Map<string, (info: WindowInfo) => void>;
|
|
61
|
+
get infoRequestTimers(): Map<string, ReturnType<typeof setTimeout>>;
|
|
62
|
+
/**
|
|
63
|
+
* Generic request/response round-trip to the core frame, modelled on
|
|
64
|
+
* {@link requestInfo}. Backs the read-only programmatic getters
|
|
65
|
+
* (getMetaFields/getConversation/getMessages). `sendFn` dispatches
|
|
66
|
+
* `messageType` with a `{ requestId }` payload; the matching `core.*.response`
|
|
67
|
+
* handler calls {@link resolveDataRequest}. If core does not respond within
|
|
68
|
+
* the timeout, the promise resolves with `fallback()` unless
|
|
69
|
+
* `timeoutErrorMessage` is set, in which case it rejects.
|
|
70
|
+
*/
|
|
71
|
+
requestData<T>(sendFn: (type: string, payload: unknown) => void, messageType: string, fallback: () => T, options?: {
|
|
72
|
+
timeoutErrorMessage?: string;
|
|
73
|
+
payload?: Record<string, unknown>;
|
|
74
|
+
timeoutMs?: number;
|
|
75
|
+
reArmOnProgress?: boolean;
|
|
76
|
+
maxTotalMs?: number;
|
|
77
|
+
preserveForCoreReplacement?: boolean;
|
|
78
|
+
}): Promise<T>;
|
|
79
|
+
/** Register a bounded correlated response without sending the request. */
|
|
80
|
+
registerAckRequest<T>(fallback: () => T, options?: {
|
|
81
|
+
timeoutErrorMessage?: string;
|
|
82
|
+
timeoutMs?: number;
|
|
83
|
+
reArmOnProgress?: boolean;
|
|
84
|
+
maxTotalMs?: number;
|
|
85
|
+
preserveForCoreReplacement?: boolean;
|
|
86
|
+
}): {
|
|
87
|
+
requestId: string;
|
|
88
|
+
promise: Promise<T>;
|
|
89
|
+
};
|
|
90
|
+
/** Settle an abandoned acknowledgement through its compatibility fallback. */
|
|
91
|
+
settleUnconfirmed(requestId: string): void;
|
|
92
|
+
private _settleOnTimeout;
|
|
93
|
+
/**
|
|
94
|
+
* Re-arm requests whose response waits behind a multi-step activation. The
|
|
95
|
+
* absolute ceiling is measured from registration, so progress from another
|
|
96
|
+
* operation cannot keep a stale request alive indefinitely.
|
|
97
|
+
*/
|
|
98
|
+
reArmPendingRequests(): void;
|
|
99
|
+
/** Resolve a pending requestData() promise with the core response payload. */
|
|
100
|
+
resolveDataRequest(requestId: string, data: unknown): void;
|
|
101
|
+
/** Reject a pending requestData() promise with a core-supplied error. */
|
|
102
|
+
rejectDataRequest(requestId: string, message: string): void;
|
|
103
|
+
/**
|
|
104
|
+
* Settle every pending requestData() promise. Ungated reads resolve with their
|
|
105
|
+
* fallback value; gated/programmatic reads reject with their timeout error.
|
|
106
|
+
* Used on core-frame crash (frame.error) and teardown.
|
|
107
|
+
*/
|
|
108
|
+
flushDataRequests(options?: {
|
|
109
|
+
preserveForCoreReplacement?: boolean;
|
|
110
|
+
}): void;
|
|
111
|
+
/**
|
|
112
|
+
* Tear down: cancel pending info timers, resolve all pending getInfo()
|
|
113
|
+
* promises with `finalInfo` so callers don't hang, then clear all state.
|
|
114
|
+
*/
|
|
115
|
+
teardown(finalInfo: WindowInfo): void;
|
|
116
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupServiceWorkerNotificationClickHandler(onNotificationClick: () => void): (() => void) | null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface UrlMatchCondition {
|
|
2
|
+
type: string;
|
|
3
|
+
value: string;
|
|
4
|
+
}
|
|
5
|
+
interface UrlTriggerCondition {
|
|
6
|
+
type: "url-match";
|
|
7
|
+
conditionsAny: UrlMatchCondition[];
|
|
8
|
+
}
|
|
9
|
+
export interface UrlBusinessEvent {
|
|
10
|
+
key: string;
|
|
11
|
+
value: number;
|
|
12
|
+
triggerConditions: UrlTriggerCondition[];
|
|
13
|
+
}
|
|
14
|
+
/** Parse the public `GET business_events/` response without trusting its shape. */
|
|
15
|
+
export declare function parseUrlBusinessEvents(payload: unknown): UrlBusinessEvent[];
|
|
16
|
+
/** Return every event with ANY matching URL trigger, matching legacy Embed2. */
|
|
17
|
+
export declare function getMatchingUrlBusinessEvents(events: UrlBusinessEvent[], href: string): UrlBusinessEvent[];
|
|
18
|
+
export declare function fetchUrlBusinessEvents(endpoint: string, fetcher?: typeof globalThis.fetch, signal?: AbortSignal): Promise<UrlBusinessEvent[]>;
|
|
19
|
+
export {};
|