@gamaro.io/widget 0.6.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/LICENSE +55 -0
- package/README.md +662 -0
- package/dist/config.d.ts +6 -0
- package/dist/iframe-loader.d.ts +78 -0
- package/dist/index.d.ts +64 -0
- package/dist/loader.d.ts +146 -0
- package/dist/logger.d.ts +26 -0
- package/dist/postmessage.d.ts +52 -0
- package/dist/types.d.ts +185 -0
- package/dist/widget.es.js +3529 -0
- package/dist/widget.umd.js +39 -0
- package/package.json +87 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Iframe loader with timeout + retry (issue #867).
|
|
3
|
+
*
|
|
4
|
+
* Promotes a skeleton placeholder into an operational iframe with a per-attempt
|
|
5
|
+
* timeout and a configurable backoff between retries. Single responsibility —
|
|
6
|
+
* the host (`VersiqWidget`) keeps the application FSM, this module owns the
|
|
7
|
+
* mechanics of getting the iframe up.
|
|
8
|
+
*
|
|
9
|
+
* Success criterion: iframe `load` event AND a `versiq:ready` postMessage from
|
|
10
|
+
* the embed React app. The AND is mandatory — a 5xx Next page rendered inside
|
|
11
|
+
* the iframe still fires `load`; relying on that alone would mask deployment
|
|
12
|
+
* failures as silent successes.
|
|
13
|
+
*
|
|
14
|
+
* Source: Harel, *Statecharts: A Visual Formalism for Complex Systems*, 1987
|
|
15
|
+
* (FSM); Akkoyunlu et al., *Some Constraints and Tradeoffs in the Design of
|
|
16
|
+
* Network Communications*, SOSP 1975 (Two-Generals handshake); Martin,
|
|
17
|
+
* *Clean Architecture* §7 (SRP).
|
|
18
|
+
*/
|
|
19
|
+
/** Per-attempt timeout (ms). */
|
|
20
|
+
export declare const IFRAME_LOAD_TIMEOUT_MS = 5000;
|
|
21
|
+
/**
|
|
22
|
+
* Backoff delays between retries (ms). Length determines the number of retries
|
|
23
|
+
* (total attempts = length + 1). [1s, 3s] covers the 5-15s Docker redeploy
|
|
24
|
+
* window observed on this project without exceeding the visitor patience
|
|
25
|
+
* threshold (19s wall-time worst case). Aligned with `resolveConfig()` which
|
|
26
|
+
* already does a 1s retry on the config fetch. No jitter — single client per
|
|
27
|
+
* page, no thundering-herd risk.
|
|
28
|
+
*/
|
|
29
|
+
export declare const IFRAME_LOAD_BACKOFF_MS: readonly [1000, 3000];
|
|
30
|
+
export type IframeLoadFailureReason = "timeout" | "error";
|
|
31
|
+
export type IframeLoadState = {
|
|
32
|
+
kind: "loading";
|
|
33
|
+
attempt: number;
|
|
34
|
+
} | {
|
|
35
|
+
kind: "loaded";
|
|
36
|
+
iframe: HTMLIFrameElement;
|
|
37
|
+
} | {
|
|
38
|
+
kind: "retrying";
|
|
39
|
+
attempt: number;
|
|
40
|
+
reason: IframeLoadFailureReason;
|
|
41
|
+
} | {
|
|
42
|
+
kind: "failed";
|
|
43
|
+
reason: IframeLoadFailureReason;
|
|
44
|
+
attempts: number;
|
|
45
|
+
};
|
|
46
|
+
export interface IframeLoaderOptions {
|
|
47
|
+
/** Factory producing a fresh iframe on every attempt. */
|
|
48
|
+
buildIframe: () => HTMLIFrameElement;
|
|
49
|
+
/** DOM node the iframe will be appended to. */
|
|
50
|
+
container: HTMLElement;
|
|
51
|
+
/** Allowed origins for the `versiq:ready` ack (passed to `isValidOrigin`). */
|
|
52
|
+
allowedOrigins: string[];
|
|
53
|
+
/** Per-attempt timeout in ms. Defaults to `IFRAME_LOAD_TIMEOUT_MS`. */
|
|
54
|
+
timeoutMs?: number;
|
|
55
|
+
/** Backoff delays between retries; length = number of retries. */
|
|
56
|
+
backoffMs?: readonly number[];
|
|
57
|
+
/** Notified on every FSM transition. */
|
|
58
|
+
onStateChange?: (state: IframeLoadState) => void;
|
|
59
|
+
/** Abort signal — rejects pending attempt and cleans up. */
|
|
60
|
+
signal?: AbortSignal;
|
|
61
|
+
}
|
|
62
|
+
export declare class IframeLoadError extends Error {
|
|
63
|
+
readonly reason: IframeLoadFailureReason;
|
|
64
|
+
readonly attempts: number;
|
|
65
|
+
constructor(reason: IframeLoadFailureReason, attempts: number);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Load an iframe with timeout + retry. Resolves with the live iframe on
|
|
69
|
+
* success; throws `IframeLoadError` (reason + final attempt count) on final
|
|
70
|
+
* failure, or `DOMException("AbortError")` when `opts.signal` aborts.
|
|
71
|
+
*
|
|
72
|
+
* The `versiq:ready` message is observed via a LOCAL listener that is detached
|
|
73
|
+
* the moment the handshake completes — the caller is expected to attach its
|
|
74
|
+
* own applicative listener AFTER this resolves, and to manually set
|
|
75
|
+
* `isReady = true` + send any post-ready commands, since the embed React app
|
|
76
|
+
* only emits `versiq:ready` once on mount.
|
|
77
|
+
*/
|
|
78
|
+
export declare function loadIframeWithRetry(opts: IframeLoaderOptions): Promise<HTMLIFrameElement>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Versiq Widget SDK
|
|
3
|
+
*
|
|
4
|
+
* Entry point for the widget SDK. Supports both auto-initialization from
|
|
5
|
+
* script tags and programmatic usage.
|
|
6
|
+
*
|
|
7
|
+
* Auto-init usage (canonical integrator surface — #726):
|
|
8
|
+
* ```html
|
|
9
|
+
* <script
|
|
10
|
+
* src="https://unpkg.com/@gamaro.io/widget@latest/dist/widget.umd.js"
|
|
11
|
+
* data-api-key="pk_live_xxx">
|
|
12
|
+
* </script>
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* The integrator's HTML carries only the publishable key (plus optional
|
|
16
|
+
* host-context attributes like `data-container` / `data-debug` / identity
|
|
17
|
+
* fields). Theme, position, language, showProfile, and the default open
|
|
18
|
+
* state are configured from the admin portal (`/portal/widget`) and
|
|
19
|
+
* resolved at load time via the publishable key — editing them from
|
|
20
|
+
* HTML is no longer supported. The legacy `data-theme` / `data-position` /
|
|
21
|
+
* `data-language` / `data-show-profile` / `data-open` attributes are
|
|
22
|
+
* silently ignored.
|
|
23
|
+
*
|
|
24
|
+
* Programmatic usage (internal dev surface — admin preview, marketing
|
|
25
|
+
* demo — not recommended for partner integrations):
|
|
26
|
+
* ```javascript
|
|
27
|
+
* import { createWidget } from '@gamaro.io/widget';
|
|
28
|
+
*
|
|
29
|
+
* const widget = createWidget({ apiKey: 'pk_live_xxx' });
|
|
30
|
+
* widget.on('qualified', () => sendToAnalytics()); // signal only, no data
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Programmatic `theme` / `position` / ... overrides are preserved for the
|
|
34
|
+
* admin sandbox's live-preview use case (client-wins merge). Partner
|
|
35
|
+
* integrators should configure those fields from the admin portal.
|
|
36
|
+
*/
|
|
37
|
+
import { VersiqWidget, createWidget } from "./loader";
|
|
38
|
+
import type { WidgetConfig } from "./types";
|
|
39
|
+
export { createWidget, VersiqWidget };
|
|
40
|
+
export { parseScriptAttributes as __parseScriptAttributes };
|
|
41
|
+
export { getCurrentScript as __getCurrentScript };
|
|
42
|
+
export { autoInit as __autoInit };
|
|
43
|
+
export { themeConfigSchema, widgetPositionSchema, widgetConfigSchema, b2bProfileSchema, widgetMessageSchema, applicationConfigResponseSchema, } from "./types";
|
|
44
|
+
export type { WidgetConfig, WidgetPosition, ColorScheme, ThemeConfig, B2BProfile, WidgetProfile, WidgetMessage, WidgetEvent, WidgetEventType, WidgetEventHandler, VersiqAPI, ApplicationConfigResponse, } from "./types";
|
|
45
|
+
export { fetchApplicationConfig, ConfigFetchError } from "./config";
|
|
46
|
+
/**
|
|
47
|
+
* Parse script tag data attributes to extract widget config (#726).
|
|
48
|
+
*
|
|
49
|
+
* Only host-context attributes are read here — fields that cannot live
|
|
50
|
+
* server-side because they are tied to the integrator's page (DOM
|
|
51
|
+
* selectors, dev flags, HMAC-verified identity). Theme, position,
|
|
52
|
+
* language, showProfile, and the default open state are resolved from
|
|
53
|
+
* the admin portal via `fetchApplicationConfig` in `loader.ts`.
|
|
54
|
+
*/
|
|
55
|
+
declare function parseScriptAttributes(script: HTMLScriptElement): WidgetConfig | null;
|
|
56
|
+
/**
|
|
57
|
+
* Find the current script tag.
|
|
58
|
+
*/
|
|
59
|
+
declare function getCurrentScript(): HTMLScriptElement | null;
|
|
60
|
+
/**
|
|
61
|
+
* Initialize widgets from script tags with data-api-key attributes.
|
|
62
|
+
* Supports multiple widgets on the same page (multi-instance).
|
|
63
|
+
*/
|
|
64
|
+
declare function autoInit(): void;
|
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget Loader
|
|
3
|
+
*
|
|
4
|
+
* Creates and manages the widget iframe, handling:
|
|
5
|
+
* - iFrame injection and positioning
|
|
6
|
+
* - postMessage communication
|
|
7
|
+
* - Public API exposure
|
|
8
|
+
*/
|
|
9
|
+
import type { WidgetConfig, WidgetEventType, WidgetEventHandler, VersiqAPI, ColorScheme, ThemeConfig } from "./types";
|
|
10
|
+
export declare function __resetInstanceCounter(): void;
|
|
11
|
+
export declare class VersiqWidget implements VersiqAPI {
|
|
12
|
+
readonly version = "0.1.0";
|
|
13
|
+
/**
|
|
14
|
+
* Original config as passed by the caller — preserved separately from
|
|
15
|
+
* `this.config` (which has defaults merged on top) so the server-config
|
|
16
|
+
* merge in `resolveConfig()` can tell "field not set by the caller,
|
|
17
|
+
* use the server value" from "caller explicitly passed a default".
|
|
18
|
+
*/
|
|
19
|
+
private originalConfig;
|
|
20
|
+
private config;
|
|
21
|
+
private iframe;
|
|
22
|
+
private container;
|
|
23
|
+
private skeletonButton;
|
|
24
|
+
private isOpen;
|
|
25
|
+
private isReady;
|
|
26
|
+
private isInitialized;
|
|
27
|
+
private isDestroyed;
|
|
28
|
+
private fetchAbortController;
|
|
29
|
+
private iframeLoadAbortController;
|
|
30
|
+
private _applicationId;
|
|
31
|
+
private vertical;
|
|
32
|
+
private instanceId;
|
|
33
|
+
private pendingCommands;
|
|
34
|
+
private eventHandlers;
|
|
35
|
+
private cleanupListener;
|
|
36
|
+
private debugLog;
|
|
37
|
+
private currentViewportMode;
|
|
38
|
+
private mobileMediaQuery;
|
|
39
|
+
private tabletMediaQuery;
|
|
40
|
+
private debounceTimer;
|
|
41
|
+
private viewportChangeHandler;
|
|
42
|
+
get applicationId(): string;
|
|
43
|
+
constructor(config: WidgetConfig);
|
|
44
|
+
/**
|
|
45
|
+
* Minimal placeholder launcher rendered synchronously before the server
|
|
46
|
+
* config arrives. Uses the default position (bottom-right) unless the
|
|
47
|
+
* caller explicitly provided one. Replaced by the real iframe in
|
|
48
|
+
* `init()` after `resolveConfig()` succeeds.
|
|
49
|
+
*/
|
|
50
|
+
private renderSkeleton;
|
|
51
|
+
/**
|
|
52
|
+
* Insert the skeleton button into the given container. Extracted so the
|
|
53
|
+
* post-config `init()` can re-create the skeleton inside a fresh container
|
|
54
|
+
* (positioned per the server config) and keep it visible across iframe
|
|
55
|
+
* load + retries (#867 — the skeleton survives until either the iframe
|
|
56
|
+
* resolves or the loader exhausts retries, at which point it mutates to
|
|
57
|
+
* the "unavailable" state).
|
|
58
|
+
*/
|
|
59
|
+
private renderSkeletonInto;
|
|
60
|
+
/**
|
|
61
|
+
* Mutate the skeleton to its degraded "unavailable" state (#867). Called
|
|
62
|
+
* when `loadIframeWithRetry` reports a final `failed` transition.
|
|
63
|
+
*
|
|
64
|
+
* Snap the opacity instantly (no 300ms fade) — by the time this fires
|
|
65
|
+
* the user has already waited 9-19s and a slow fade would feel like
|
|
66
|
+
* the widget is still working (Nielsen heuristic #1 — visibility of
|
|
67
|
+
* system status: degraded states must be unambiguous). The
|
|
68
|
+
* `data-state="unavailable"` attribute also gives integrators a CSS
|
|
69
|
+
* hook to override the visual treatment without touching the SDK.
|
|
70
|
+
* No-op in inline mode (the skeleton is never rendered there — the
|
|
71
|
+
* integrator owns the UI).
|
|
72
|
+
*/
|
|
73
|
+
private setSkeletonStateUnavailable;
|
|
74
|
+
/**
|
|
75
|
+
* Resolve the widget runtime config from the server (#726). Retries once
|
|
76
|
+
* with a 1s backoff on *transient* failures (network, timeout, 5xx) —
|
|
77
|
+
* 4xx and parse errors are permanent config/setup problems that a
|
|
78
|
+
* retry cannot fix, so we surface them immediately. If both attempts
|
|
79
|
+
* fail, the skeleton stays visible and the widget emits `error` —
|
|
80
|
+
* visible degraded mode rather than a silently absent widget.
|
|
81
|
+
*/
|
|
82
|
+
private resolveConfig;
|
|
83
|
+
private isTransientFetchError;
|
|
84
|
+
/**
|
|
85
|
+
* Merge the server-resolved application config into the widget state
|
|
86
|
+
* and promote the skeleton to a fully-initialised iframe.
|
|
87
|
+
*
|
|
88
|
+
* Merge semantics (#726):
|
|
89
|
+
* 1. Fields explicitly passed to `createWidget(...)` win (`originalConfig`).
|
|
90
|
+
* This keeps the admin sandbox's live preview working: unsaved edits
|
|
91
|
+
* stay visible on the preview widget.
|
|
92
|
+
* 2. Otherwise the server's `widget` block (from the publishable key
|
|
93
|
+
* lookup) provides theme/position/language/showProfile/open.
|
|
94
|
+
* 3. Legacy `server.theme` is still merged underneath `server.widget.theme`
|
|
95
|
+
* for backward compatibility with pre-#726 data shapes — it will
|
|
96
|
+
* be removed once all consumers land the new contract.
|
|
97
|
+
*/
|
|
98
|
+
private applyServerConfig;
|
|
99
|
+
private flushPendingCommands;
|
|
100
|
+
private init;
|
|
101
|
+
/**
|
|
102
|
+
* Strip any path from `baseUrl` so the resulting string matches the
|
|
103
|
+
* `event.origin` field of a `versiq:ready` postMessage (which is always
|
|
104
|
+
* scheme + host + port, no path). Falls back to the raw value if parsing
|
|
105
|
+
* fails so a malformed config does not silently break the loader gate.
|
|
106
|
+
*/
|
|
107
|
+
private resolveReadyOrigin;
|
|
108
|
+
/** Insert the active container in the host DOM at the configured slot. */
|
|
109
|
+
private attachContainerToDom;
|
|
110
|
+
private createContainer;
|
|
111
|
+
private createIframe;
|
|
112
|
+
private buildIframeUrl;
|
|
113
|
+
private setupViewportListener;
|
|
114
|
+
private handleViewportChange;
|
|
115
|
+
private getViewportMode;
|
|
116
|
+
/**
|
|
117
|
+
* Re-apply the container resize transition, gated on the host's current
|
|
118
|
+
* reduced-motion preference. Called before every geometry change (open/close
|
|
119
|
+
* AND viewport-mode change) so a mid-session OS reduced-motion toggle is
|
|
120
|
+
* honoured on whichever path runs next, not only on open/close.
|
|
121
|
+
*/
|
|
122
|
+
private applyContainerTransition;
|
|
123
|
+
private updateContainerForViewport;
|
|
124
|
+
private handleMessage;
|
|
125
|
+
private sendConfig;
|
|
126
|
+
private updateVisibility;
|
|
127
|
+
private emit;
|
|
128
|
+
open(): void;
|
|
129
|
+
close(): void;
|
|
130
|
+
reset(): void;
|
|
131
|
+
identify(params: {
|
|
132
|
+
email: string;
|
|
133
|
+
userId?: string;
|
|
134
|
+
userHash: string;
|
|
135
|
+
}): void;
|
|
136
|
+
setTheme(theme: ThemeConfig): void;
|
|
137
|
+
setColorScheme(scheme: ColorScheme): void;
|
|
138
|
+
on<T = unknown>(event: WidgetEventType, handler: WidgetEventHandler<T>): void;
|
|
139
|
+
off<T = unknown>(event: WidgetEventType, handler: WidgetEventHandler<T>): void;
|
|
140
|
+
destroy(): void;
|
|
141
|
+
private log;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Create a new widget instance.
|
|
145
|
+
*/
|
|
146
|
+
export declare function createWidget(config: WidgetConfig): VersiqWidget;
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget Logger
|
|
3
|
+
*
|
|
4
|
+
* Lightweight logger for the widget SDK with consistent prefix.
|
|
5
|
+
* Provides a centralized logging interface for debug, info, warn, and error levels.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Log an error message.
|
|
9
|
+
*/
|
|
10
|
+
export declare function logError(msg: string, ...args: unknown[]): void;
|
|
11
|
+
/**
|
|
12
|
+
* Log a warning message.
|
|
13
|
+
*/
|
|
14
|
+
export declare function logWarn(msg: string, ...args: unknown[]): void;
|
|
15
|
+
/**
|
|
16
|
+
* Log an info message.
|
|
17
|
+
*/
|
|
18
|
+
export declare function logInfo(msg: string, ...args: unknown[]): void;
|
|
19
|
+
/**
|
|
20
|
+
* Log a debug message.
|
|
21
|
+
*/
|
|
22
|
+
export declare function logDebug(msg: string, ...args: unknown[]): void;
|
|
23
|
+
/**
|
|
24
|
+
* Create a conditional debug logger based on debug flag.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createDebugLogger(enabled: boolean): typeof logDebug;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* postMessage Protocol
|
|
3
|
+
*
|
|
4
|
+
* Handles secure bidirectional communication between the parent page
|
|
5
|
+
* and the widget iframe using the postMessage API.
|
|
6
|
+
*/
|
|
7
|
+
import type { WidgetCommand, WidgetEvent } from "./types";
|
|
8
|
+
/**
|
|
9
|
+
* Validate that a message origin is trusted.
|
|
10
|
+
*
|
|
11
|
+
* Exact match only — no subdomain wildcarding. Every real caller compares
|
|
12
|
+
* against a single origin derived from the widget's own configured `baseUrl`
|
|
13
|
+
* (`resolveReadyOrigin()`), never a family of subdomains, so a suffix match
|
|
14
|
+
* only widens the trusted surface without covering a legitimate case.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isValidOrigin(origin: string, allowedOrigins: string[]): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Check if an event contains a valid Versiq message.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isVersiqMessage(event: MessageEvent): event is MessageEvent<WidgetCommand | WidgetEvent>;
|
|
21
|
+
/**
|
|
22
|
+
* Send a command to the widget iframe.
|
|
23
|
+
*/
|
|
24
|
+
export declare function sendCommand(iframe: HTMLIFrameElement, command: WidgetCommand, targetOrigin: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Send an event to the parent window.
|
|
27
|
+
* Used by the embedded widget to notify the parent of state changes.
|
|
28
|
+
*/
|
|
29
|
+
export declare function sendEvent(event: WidgetEvent, targetOrigin: string): void;
|
|
30
|
+
export interface MessageListenerOptions {
|
|
31
|
+
/** Allowed origins for incoming messages */
|
|
32
|
+
allowedOrigins?: string[];
|
|
33
|
+
/** Callback for received messages */
|
|
34
|
+
onMessage: (message: WidgetCommand | WidgetEvent, origin: string) => void;
|
|
35
|
+
/** Enable debug logging */
|
|
36
|
+
debug?: boolean;
|
|
37
|
+
/** Only accept messages from this window (for multi-instance isolation) */
|
|
38
|
+
sourceWindow?: Window | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a message listener with origin validation.
|
|
42
|
+
* Returns a cleanup function to remove the listener.
|
|
43
|
+
*/
|
|
44
|
+
export declare function createMessageListener(options: MessageListenerOptions): () => void;
|
|
45
|
+
/**
|
|
46
|
+
* Encode theme config for URL parameter.
|
|
47
|
+
*/
|
|
48
|
+
export declare function encodeTheme(theme: object): string;
|
|
49
|
+
/**
|
|
50
|
+
* Decode theme config from URL parameter.
|
|
51
|
+
*/
|
|
52
|
+
export declare function decodeTheme<T>(encoded: string): T | null;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget SDK Types
|
|
3
|
+
*
|
|
4
|
+
* Cross-workspace contracts (viewport, theme, widget config, application
|
|
5
|
+
* config, postMessage protocol) now live in `@gamaro.io/core-types` — this file
|
|
6
|
+
* re-exports them so existing consumers (`apps/marketing`,
|
|
7
|
+
* `apps/app/src/components/portal/sandbox`) keep working unchanged. The only
|
|
8
|
+
* types still defined locally are widget-specific SDK surfaces (B2B profile
|
|
9
|
+
* schemas, `VersiqAPI`, `window` augmentation).
|
|
10
|
+
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import type { ColorScheme, ThemeConfig, WidgetEventHandler, WidgetEventType } from "@gamaro.io/core-types";
|
|
13
|
+
export { applicationConfigResponseSchema, breakpointsConfigSchema, MESSAGE_TYPES, messageRoleSchema, resolveTheme, responsiveConfigSchema, themeConfigSchema, viewportModeSchema, widgetConfigSchema, widgetMessageSchema, widgetPositionSchema, } from "@gamaro.io/core-types";
|
|
14
|
+
export type { ApplicationConfigResponse, BreakpointsConfig, ColorScheme, MessageRole, MessageType, ResolvedTheme, ResponsiveConfig, ThemeConfig, ThemeDefaults, ViewportMode, WidgetCommand, WidgetConfig, WidgetEvent, WidgetEventHandler, WidgetEventType, WidgetMessage, WidgetPosition, WidgetProfile, WidgetUnavailablePayload, } from "@gamaro.io/core-types";
|
|
15
|
+
/**
|
|
16
|
+
* User type enum.
|
|
17
|
+
*/
|
|
18
|
+
export declare const b2bUserTypeSchema: z.ZodEnum<{
|
|
19
|
+
prospect: "prospect";
|
|
20
|
+
partner: "partner";
|
|
21
|
+
unknown: "unknown";
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Business sector enum.
|
|
25
|
+
*/
|
|
26
|
+
export declare const b2bSectorSchema: z.ZodEnum<{
|
|
27
|
+
ecommerce: "ecommerce";
|
|
28
|
+
"real-estate": "real-estate";
|
|
29
|
+
automotive: "automotive";
|
|
30
|
+
travel: "travel";
|
|
31
|
+
recruitment: "recruitment";
|
|
32
|
+
other: "other";
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Company size enum.
|
|
36
|
+
*/
|
|
37
|
+
export declare const b2bCompanySizeSchema: z.ZodEnum<{
|
|
38
|
+
startup: "startup";
|
|
39
|
+
pme: "pme";
|
|
40
|
+
eti: "eti";
|
|
41
|
+
"grand-groupe": "grand-groupe";
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Monthly traffic enum.
|
|
45
|
+
*/
|
|
46
|
+
export declare const b2bMonthlyTrafficSchema: z.ZodEnum<{
|
|
47
|
+
"< 10k": "< 10k";
|
|
48
|
+
"10k-50k": "10k-50k";
|
|
49
|
+
"50k-200k": "50k-200k";
|
|
50
|
+
"> 200k": "> 200k";
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Business objectives enum.
|
|
54
|
+
*/
|
|
55
|
+
export declare const b2bObjectiveSchema: z.ZodEnum<{
|
|
56
|
+
other: "other";
|
|
57
|
+
"lead-qualification": "lead-qualification";
|
|
58
|
+
personalization: "personalization";
|
|
59
|
+
"cart-abandonment": "cart-abandonment";
|
|
60
|
+
conversion: "conversion";
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* E-commerce platform enum.
|
|
64
|
+
*/
|
|
65
|
+
export declare const b2bPlatformSchema: z.ZodEnum<{
|
|
66
|
+
shopify: "shopify";
|
|
67
|
+
woocommerce: "woocommerce";
|
|
68
|
+
prestashop: "prestashop";
|
|
69
|
+
custom: "custom";
|
|
70
|
+
none: "none";
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* Implementation timeline enum.
|
|
74
|
+
*/
|
|
75
|
+
export declare const b2bTimelineSchema: z.ZodEnum<{
|
|
76
|
+
immediate: "immediate";
|
|
77
|
+
"1-month": "1-month";
|
|
78
|
+
"3-months": "3-months";
|
|
79
|
+
exploring: "exploring";
|
|
80
|
+
}>;
|
|
81
|
+
/**
|
|
82
|
+
* Budget range enum.
|
|
83
|
+
*/
|
|
84
|
+
export declare const b2bBudgetRangeSchema: z.ZodEnum<{
|
|
85
|
+
"< 500": "< 500";
|
|
86
|
+
"500-2000": "500-2000";
|
|
87
|
+
"2000-5000": "2000-5000";
|
|
88
|
+
"> 5000": "> 5000";
|
|
89
|
+
}>;
|
|
90
|
+
/**
|
|
91
|
+
* B2B qualification profile schema.
|
|
92
|
+
*/
|
|
93
|
+
export declare const b2bProfileSchema: z.ZodObject<{
|
|
94
|
+
userType: z.ZodOptional<z.ZodEnum<{
|
|
95
|
+
prospect: "prospect";
|
|
96
|
+
partner: "partner";
|
|
97
|
+
unknown: "unknown";
|
|
98
|
+
}>>;
|
|
99
|
+
sector: z.ZodOptional<z.ZodEnum<{
|
|
100
|
+
ecommerce: "ecommerce";
|
|
101
|
+
"real-estate": "real-estate";
|
|
102
|
+
automotive: "automotive";
|
|
103
|
+
travel: "travel";
|
|
104
|
+
recruitment: "recruitment";
|
|
105
|
+
other: "other";
|
|
106
|
+
}>>;
|
|
107
|
+
companySize: z.ZodOptional<z.ZodEnum<{
|
|
108
|
+
startup: "startup";
|
|
109
|
+
pme: "pme";
|
|
110
|
+
eti: "eti";
|
|
111
|
+
"grand-groupe": "grand-groupe";
|
|
112
|
+
}>>;
|
|
113
|
+
monthlyTraffic: z.ZodOptional<z.ZodEnum<{
|
|
114
|
+
"< 10k": "< 10k";
|
|
115
|
+
"10k-50k": "10k-50k";
|
|
116
|
+
"50k-200k": "50k-200k";
|
|
117
|
+
"> 200k": "> 200k";
|
|
118
|
+
}>>;
|
|
119
|
+
objectives: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
120
|
+
other: "other";
|
|
121
|
+
"lead-qualification": "lead-qualification";
|
|
122
|
+
personalization: "personalization";
|
|
123
|
+
"cart-abandonment": "cart-abandonment";
|
|
124
|
+
conversion: "conversion";
|
|
125
|
+
}>>>;
|
|
126
|
+
platform: z.ZodOptional<z.ZodEnum<{
|
|
127
|
+
shopify: "shopify";
|
|
128
|
+
woocommerce: "woocommerce";
|
|
129
|
+
prestashop: "prestashop";
|
|
130
|
+
custom: "custom";
|
|
131
|
+
none: "none";
|
|
132
|
+
}>>;
|
|
133
|
+
timeline: z.ZodOptional<z.ZodEnum<{
|
|
134
|
+
immediate: "immediate";
|
|
135
|
+
"1-month": "1-month";
|
|
136
|
+
"3-months": "3-months";
|
|
137
|
+
exploring: "exploring";
|
|
138
|
+
}>>;
|
|
139
|
+
budgetRange: z.ZodOptional<z.ZodEnum<{
|
|
140
|
+
"< 500": "< 500";
|
|
141
|
+
"500-2000": "500-2000";
|
|
142
|
+
"2000-5000": "2000-5000";
|
|
143
|
+
"> 5000": "> 5000";
|
|
144
|
+
}>>;
|
|
145
|
+
}, z.core.$strip>;
|
|
146
|
+
export type B2BProfile = z.infer<typeof b2bProfileSchema>;
|
|
147
|
+
/**
|
|
148
|
+
* Public API exposed on window.Versiq.
|
|
149
|
+
*/
|
|
150
|
+
export interface VersiqAPI {
|
|
151
|
+
/** Application ID (available after config resolution) */
|
|
152
|
+
readonly applicationId: string;
|
|
153
|
+
/** Open the widget */
|
|
154
|
+
open(): void;
|
|
155
|
+
/** Close the widget */
|
|
156
|
+
close(): void;
|
|
157
|
+
/** Reset the conversation */
|
|
158
|
+
reset(): void;
|
|
159
|
+
/** Update theme dynamically */
|
|
160
|
+
setTheme(theme: ThemeConfig): void;
|
|
161
|
+
/**
|
|
162
|
+
* Update only the color scheme. Sugar over `setTheme({ colorScheme })` so
|
|
163
|
+
* integrators can wire their own dark-mode toggle without rebuilding the
|
|
164
|
+
* full theme object: `window.Versiq.setColorScheme("dark")`.
|
|
165
|
+
*/
|
|
166
|
+
setColorScheme(scheme: ColorScheme): void;
|
|
167
|
+
/** Identify the current user with host-attested HMAC verification */
|
|
168
|
+
identify(params: {
|
|
169
|
+
email: string;
|
|
170
|
+
userId?: string;
|
|
171
|
+
userHash: string;
|
|
172
|
+
}): void;
|
|
173
|
+
/** Subscribe to events */
|
|
174
|
+
on<T = unknown>(event: WidgetEventType, handler: WidgetEventHandler<T>): void;
|
|
175
|
+
/** Unsubscribe from events */
|
|
176
|
+
off<T = unknown>(event: WidgetEventType, handler: WidgetEventHandler<T>): void;
|
|
177
|
+
/** Widget version */
|
|
178
|
+
version: string;
|
|
179
|
+
}
|
|
180
|
+
declare global {
|
|
181
|
+
interface Window {
|
|
182
|
+
Versiq?: VersiqAPI;
|
|
183
|
+
VersiqApps?: Map<string, VersiqAPI>;
|
|
184
|
+
}
|
|
185
|
+
}
|