@gamaro.io/widget 0.6.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/README.md CHANGED
@@ -5,9 +5,10 @@
5
5
  [![types](https://img.shields.io/npm/types/@gamaro.io/widget.svg)](#typescript)
6
6
  [![license](https://img.shields.io/badge/license-Commercial%20Source--available-blue.svg)](./LICENSE)
7
7
 
8
- Versiq Widget SDK — embed a conversational conversion agent that answers
9
- visitors using **your** site's data (catalogue, inventory, CRM, knowledge base),
10
- not the public-web average a generic LLM assistant returns.
8
+ Gamaro Widget SDK — embed a conversational conversion agent that grounds every
9
+ response in **your** site's own data (catalogue, inventory, CRM, knowledge base)
10
+ instead of the undifferentiated public training data a generic LLM assistant
11
+ would otherwise draw on.
11
12
 
12
13
  ## Table of Contents
13
14
 
@@ -71,7 +72,7 @@ the cost of having to bump it manually on every release.
71
72
  ### Programmatic API
72
73
 
73
74
  The minimal integration is one line — every visual and behavioural aspect
74
- (theme, position, language, open-state, branding) is configured in the **Versiq
75
+ (theme, position, language, open-state, branding) is configured in the **Gamaro
75
76
  admin portal** for your Agent and resolved server-side from the API key.
76
77
 
77
78
  ```typescript
@@ -93,16 +94,16 @@ widget.destroy();
93
94
  Two reasons most platforms fail to convert mobile visitors, and two reasons this
94
95
  widget does:
95
96
 
96
- 1. **It speaks with your data, not the public-web average.** The agent answers
97
- from your catalogue, your stock, your CRM, your knowledge base — what your
98
- competitors and generic AI assistants don't have.
97
+ 1. **It grounds every answer in your own data, not generic AI training data.**
98
+ The agent answers from your catalogue, your stock, your CRM, your knowledge
99
+ base — what your competitors and generic AI assistants don't have.
99
100
  2. **It is driven by your thumb, not your keyboard.** The LLM dynamically picks
100
101
  the right component at every turn — quick replies, sliders, product cards —
101
102
  instead of forcing a form. Visitors qualify their need in a few taps on
102
103
  mobile, where 3+ field forms lose 50%+ of users (HubSpot).
103
104
 
104
105
  The widget rendering layer (`QuickReplies`, `PropertyCard`, `ActionButtons`) is
105
- the runtime that materialises this. Schemas live in the Versiq backend
106
+ the runtime that materialises this. Schemas live in the Gamaro backend
106
107
  repository and are out of scope for the SDK consumer.
107
108
 
108
109
  ## Configuration
@@ -125,22 +126,22 @@ context (DOM, identity, environment).
125
126
  | `userId` | `string` | - | Host-side stable user identifier — must be paired with `userHash`. |
126
127
  | `userHash` | `string` | - | HMAC-SHA256 of `email` (or `userId`), signed with the Agent identity secret. See _Identity_. |
127
128
 
128
- ### 2. Server-resolved (configured in the Versiq admin portal)
129
+ ### 2. Server-resolved (configured in the Gamaro admin portal)
129
130
 
130
131
  These are **not** passed by the integration — they are stored in the Agent's
131
132
  `widget_config` JSONB row and fetched at bootstrap from the API key. To change
132
133
  any of them, edit the Agent in the portal.
133
134
 
134
- | Field | Configured in admin | Notes |
135
- | ----------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------- |
136
- | `theme` | Apparence → palette | Full palette (`primaryColor`, `backgroundColor`, `textColor`, `borderRadius`, `fontFamily`, `colorScheme`). |
137
- | `position` | Apparence → position | `"bottom-right"`, `"bottom-left"`, or `"inline"`. |
138
- | `language` | Apparence → langue | ISO 639-1 (e.g. `fr`, `en`). Falls back to browser language when unset. |
139
- | `showProfile` | Apparence → panneau profil | Toggles the profile panel in the widget header. |
140
- | `open` | Apparence → état initial | Default open state on page load. Host can still call `widget.open()` programmatically. |
141
- | `brand.title` | Branding → titre | Custom header title (falls back to a vertical-specific default). |
142
- | `brand.avatarUrl` | Branding → avatar | Custom avatar URL (must originate from the portal upload — arbitrary URLs are rejected). |
143
- | `vertical` | Agent creation | `real-estate`, `b2b-qualification`, … Bound to the API key. |
135
+ | Field | Configured in admin | Notes |
136
+ | ----------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
137
+ | `theme` | Apparence → palette | Full palette (`primaryColor`, `backgroundColor`, `textColor`, `borderRadius`, `fontFamily`, `colorScheme`). |
138
+ | `position` | Apparence → position | `"bottom-right"`, `"bottom-left"`, or `"inline"`. |
139
+ | `language` | Apparence → langue | ISO 639-1 (e.g. `fr`, `en`). Falls back to browser language when unset. |
140
+ | `showProfile` | Apparence → panneau profil | Forces the profile panel visible from the start of the conversation. The panel already shows on its own once the visitor's profile has data, regardless of this flag. |
141
+ | `open` | Apparence → état initial | Default open state on page load. Host can still call `widget.open()` programmatically. |
142
+ | `brand.title` | Branding → titre | Custom header title (falls back to a vertical-specific default). |
143
+ | `brand.avatarUrl` | Branding → avatar | Custom avatar URL (must originate from the portal upload — arbitrary URLs are rejected). |
144
+ | `vertical` | Agent creation | `real-estate`, `b2b-qualification`, … Bound to the API key. |
144
145
 
145
146
  ### 3. Client overrides (advanced — rarely needed in production)
146
147
 
@@ -199,7 +200,7 @@ const widget = createWidget({
199
200
  });
200
201
  ```
201
202
 
202
- ### VersiqWidget Methods
203
+ ### GamaroWidget Methods
203
204
 
204
205
  | Method | Description |
205
206
  | ----------------------------------------------------- | -------------------------------------------------------- |
@@ -215,15 +216,15 @@ const widget = createWidget({
215
216
 
216
217
  ### Window API (Script Tag)
217
218
 
218
- When using the script tag, the API is available on `window.Versiq`:
219
+ When using the script tag, the API is available on `window.Gamaro`:
219
220
 
220
221
  ```javascript
221
- window.Versiq.open();
222
- window.Versiq.close();
223
- window.Versiq.setTheme({ primaryColor: "#10B981" });
222
+ window.Gamaro.open();
223
+ window.Gamaro.close();
224
+ window.Gamaro.setTheme({ primaryColor: "#10B981" });
224
225
 
225
226
  // Wire your own dark-mode toggle to the widget:
226
- window.Versiq.setColorScheme("dark"); // or "light", or "auto"
227
+ window.Gamaro.setColorScheme("dark"); // or "light", or "auto"
227
228
  ```
228
229
 
229
230
  ## Events
@@ -255,23 +256,23 @@ widget.on("error", (data) => {
255
256
 
256
257
  ### Event Types
257
258
 
258
- | Event | Payload | Description |
259
- | --------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------- |
260
- | `ready` | - | Widget is loaded and ready |
261
- | `open` | - | Widget was opened |
262
- | `close` | - | Widget was closed |
263
- | `message` | `{ message: WidgetMessage }` | New chat message |
264
- | `profile-update` | - | Profile was updated (signal only — subscribe to webhooks for the data) |
265
- | `qualified` | - | Lead qualified (signal only — subscribe to the `lead.qualified` webhook for the data) |
266
- | `funnel-stage-change` | `{ stage: string, previousStage: string \| null }` | Conversion funnel stage transition |
267
- | `cta-shown` | `{ ctaType: string, objectiveId?: string }` | A call-to-action was displayed |
268
- | `cta-clicked` | `{ ctaType: string, objectiveId?: string }` | A call-to-action was clicked |
269
- | `lead-captured` | `{ hasEmail: boolean, hasPhone: boolean }` | Lead contact details captured |
270
- | `error` | `{ code: string, message: string }` | An error occurred |
271
- | `quota-warning` | `{ remaining: number, limit: number }` | Lead quota running low |
272
- | `quota-exceeded` | - | Lead quota exceeded |
273
- | `identity-verified` | `{ email: string, userId?: string }` | Host identity verified (HMAC) |
274
- | `widget-unavailable` | `{ reason: "timeout" \| "error", attempts: number }` | SDK exhausted all load retries — the widget degrades to a static state |
259
+ | Event | Payload | Description |
260
+ | --------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
261
+ | `ready` | - | Widget is loaded and ready |
262
+ | `open` | - | Widget was opened |
263
+ | `close` | - | Widget was closed |
264
+ | `message` | `{ message: WidgetMessage }` | New chat message |
265
+ | `profile-update` | - | Profile was updated (signal only — subscribe to webhooks for the data) |
266
+ | `qualified` | - | Lead qualified (signal only — subscribe to the `lead.qualified` webhook for the data) |
267
+ | `funnel-stage-change` | `{ stage: string, previousStage: string \| null }` | Conversion funnel stage transition |
268
+ | `cta-shown` | `{ ctaType: string, objectiveId?: string }` | A call-to-action was rendered — once per objective per conversation (mount, not viewport visibility) |
269
+ | `cta-clicked` | `{ ctaType: string, objectiveId?: string }` | A call-to-action was clicked |
270
+ | `lead-captured` | `{ hasEmail: boolean, hasPhone: boolean }` | A contact was saved this turn (channels only, never the value); not emitted when the agent reply fails |
271
+ | `error` | `{ code: string, message: string }` | An error occurred |
272
+ | `quota-warning` | `{ remaining: number, limit: number }` | Lead quota running low |
273
+ | `quota-exceeded` | - | Lead quota exceeded |
274
+ | `identity-verified` | `{ email: string, userId?: string }` | Host identity verified (HMAC) |
275
+ | `widget-unavailable` | `{ reason: "timeout" \| "error", attempts: number }` | SDK exhausted all load retries — the widget degrades to a static state |
275
276
 
276
277
  ## TypeScript
277
278
 
@@ -281,7 +282,7 @@ The package includes full TypeScript support with exported types:
281
282
  import type {
282
283
  WidgetConfig,
283
284
  ThemeConfig,
284
- VersiqWidget,
285
+ GamaroWidget,
285
286
  WidgetEventType,
286
287
  WidgetProfile,
287
288
  WidgetMessage,
@@ -307,7 +308,7 @@ vertical = creating a new Agent + new key.
307
308
  ### Real-Estate flow
308
309
 
309
310
  When the resolved vertical is `real-estate`, the widget runs in qualification
310
- mode: Versiq qualifies the buyer through conversation and emits the profile — no
311
+ mode: Gamaro qualifies the buyer through conversation and emits the profile — no
311
312
  property data is needed from the integrator (data-dependent tools like
312
313
  `searchProperties`, `getCityStats`, `estimateProperty` are automatically
313
314
  excluded).
@@ -381,10 +382,10 @@ createWidget({
381
382
  "use client";
382
383
 
383
384
  import { useEffect, useRef } from "react";
384
- import { createWidget, type VersiqWidget } from "@gamaro.io/widget";
385
+ import { createWidget, type GamaroWidget } from "@gamaro.io/widget";
385
386
 
386
387
  export function ContactWidget() {
387
- const widgetRef = useRef<VersiqWidget | null>(null);
388
+ const widgetRef = useRef<GamaroWidget | null>(null);
388
389
  const containerRef = useRef<HTMLDivElement>(null);
389
390
 
390
391
  useEffect(() => {
@@ -412,9 +413,10 @@ export function ContactWidget() {
412
413
 
413
414
  ## Data Attributes (Script Tag)
414
415
 
415
- All `WidgetConfig` options can be passed as kebab-cased `data-*` attributes on
416
- the `<script>` tag. The same scope split as the JavaScript API applies — in
417
- practice only `data-api-key` is needed.
416
+ Most `WidgetConfig` options can be passed as kebab-cased `data-*` attributes on
417
+ the `<script>` tag — the parser reads a fixed attribute list, so
418
+ `initialMessage` and `responsive` are programmatic-only. The same scope split as
419
+ the JavaScript API applies — in practice only `data-api-key` is needed.
418
420
 
419
421
  ### Host-side (essential)
420
422
 
@@ -448,7 +450,7 @@ attestation, the host `Permissions-Policy`, and your `Content-Security-Policy`.
448
450
  ### Identity verification (HMAC)
449
451
 
450
452
  By default a visitor is anonymous. If your page already knows who the visitor is
451
- (a logged-in user), you can attest that identity to Versiq so leads are attached
453
+ (a logged-in user), you can attest that identity to Gamaro so leads are attached
452
454
  to the right account — without trusting a client-supplied email blindly.
453
455
 
454
456
  Pass `email` (or `userId`) **together with** a `userHash`: an HMAC-SHA256 of the
@@ -507,7 +509,7 @@ conversation still works; the visitor just types the city manually.
507
509
  Permissions-Policy controls **what the iframe is allowed to do**;
508
510
  Content-Security-Policy controls **where scripts / iframes / styles can come
509
511
  from**. Both are independent and both are needed in production. The CSP
510
- directives required for the Versiq widget are documented in the Versiq backend
512
+ directives required for the Gamaro widget are documented in the Gamaro backend
511
513
  repo at `docs/B2B_INTEGRATION.md` § "Content-Security-Policy pour intégrateurs".
512
514
 
513
515
  ## E2E Test Selectors (data-testid)
@@ -516,21 +518,22 @@ For a smoke test that the widget mounted and works on your page, a small core of
516
518
  `data-testid` selectors is exposed. These are guaranteed not to change without a
517
519
  major version bump.
518
520
 
519
- | Selector | Element | Additional attributes |
520
- | ----------------------- | ----------------------------------------------------------------------------- | ---------------------------------- |
521
- | `widget-root` | Chat container (open) | — |
522
- | `widget-input` | Message input field | — |
523
- | `widget-send` | Send button | — |
524
- | `widget-message` | Message bubble | `data-role="user" \| "assistant"` |
525
- | `widget-loading-status` | Running-tool status label beside the typing dots (e.g. "Recherche de biens…") | — (absent until a tool runs) |
526
- | `widget-suggestion` | Quick reply chip | `data-index="<N>"` (position) |
527
- | `widget-cta-button` | Call-to-action button | `data-objective="<objectiveType>"` |
528
- | `widget-avatar` | Header avatar | — |
521
+ | Selector | Element | Additional attributes |
522
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
523
+ | `widget-root` | Chat container (open) | — |
524
+ | `widget-input` | Message input field | — |
525
+ | `widget-send` | Send button | — |
526
+ | `widget-message` | Message bubble | `data-role="user" \| "assistant"` |
527
+ | `widget-loading-status` | Running-tool status label beside the typing dots (e.g. "Recherche de biens…") | — (absent until a tool runs) |
528
+ | `widget-suggestion` | Quick reply chip | `data-index="<N>"` (position) |
529
+ | `widget-cta-summary-continue` | Pre-CTA recap card "Continue" button (#3028) — precedes `widget-cta-button` when the visitor's profile has display config for the active vertical | — (absent otherwise, `widget-cta-button` mounts directly) |
530
+ | `widget-cta-button` | Call-to-action button | `data-objective="<objectiveType>"` |
531
+ | `widget-avatar` | Header avatar | — |
529
532
 
530
533
  > The widget also exposes a large set of vertical-specific selectors
531
534
  > (real-estate map, areas-overview, exploration mode, criteria popup, range
532
- > slider, contact form). They are internal to the Versiq UI and out of scope for
533
- > SDK consumers — the full contract lives in the Versiq backend repository under
535
+ > slider, contact form). They are internal to the Gamaro UI and out of scope for
536
+ > SDK consumers — the full contract lives in the Gamaro backend repository under
534
537
  > `apps/app/src/app/widget/embed/components/`.
535
538
 
536
539
  ### Example (Playwright)
@@ -612,7 +615,7 @@ Lighthouse manually:
612
615
  analytics pipeline (Google Analytics 4, Sentry, etc.) to track field LCP per
613
616
  real visitor — Lighthouse alone only measures synthetic loads.
614
617
 
615
- The Versiq widget itself does not emit web-vitals events (out of scope — the SDK
618
+ The Gamaro widget itself does not emit web-vitals events (out of scope — the SDK
616
619
  should not impose an analytics dependency on the host). Integrators own the
617
620
  measurement pipeline for their own page.
618
621
 
@@ -656,7 +659,7 @@ Commercial Source-available — see [LICENSE](./LICENSE).
656
659
  This is **not** an open-source release: the source is published so integrators
657
660
  can audit what runs in their visitors' browsers, but fork / redistribution /
658
661
  competing-SDK use are prohibited without a written agreement. Production use
659
- against the Versiq backend is governed by the Versiq Commercial Terms of
662
+ against the Gamaro backend is governed by the Gamaro Commercial Terms of
660
663
  Service.
661
664
 
662
665
  For commercial licensing inquiries: admin@dolard.eu
@@ -0,0 +1,34 @@
1
+ # Third-party notices
2
+
3
+ The published bundles (`dist/widget.umd.js`, `dist/widget.es.js`) include the
4
+ following third-party software. `@gamaro.io/core-types`, also inlined, is Gamaro
5
+ code under its own license.
6
+
7
+ ## zod
8
+
9
+ - Source: <https://github.com/colinhacks/zod>
10
+ - License: MIT
11
+
12
+ ```text
13
+ MIT License
14
+
15
+ Copyright (c) 2025 Colin McDonnell
16
+
17
+ Permission is hereby granted, free of charge, to any person obtaining a copy
18
+ of this software and associated documentation files (the "Software"), to deal
19
+ in the Software without restriction, including without limitation the rights
20
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+ copies of the Software, and to permit persons to whom the Software is
22
+ furnished to do so, subject to the following conditions:
23
+
24
+ The above copyright notice and this permission notice shall be included in all
25
+ copies or substantial portions of the Software.
26
+
27
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
+ SOFTWARE.
34
+ ```
@@ -3,10 +3,10 @@
3
3
  *
4
4
  * Promotes a skeleton placeholder into an operational iframe with a per-attempt
5
5
  * timeout and a configurable backoff between retries. Single responsibility —
6
- * the host (`VersiqWidget`) keeps the application FSM, this module owns the
6
+ * the host (`GamaroWidget`) keeps the application FSM, this module owns the
7
7
  * mechanics of getting the iframe up.
8
8
  *
9
- * Success criterion: iframe `load` event AND a `versiq:ready` postMessage from
9
+ * Success criterion: iframe `load` event AND a `gamaro:ready` postMessage from
10
10
  * the embed React app. The AND is mandatory — a 5xx Next page rendered inside
11
11
  * the iframe still fires `load`; relying on that alone would mask deployment
12
12
  * failures as silent successes.
@@ -48,7 +48,7 @@ export interface IframeLoaderOptions {
48
48
  buildIframe: () => HTMLIFrameElement;
49
49
  /** DOM node the iframe will be appended to. */
50
50
  container: HTMLElement;
51
- /** Allowed origins for the `versiq:ready` ack (passed to `isValidOrigin`). */
51
+ /** Allowed origins for the `gamaro:ready` ack (passed to `isValidOrigin`). */
52
52
  allowedOrigins: string[];
53
53
  /** Per-attempt timeout in ms. Defaults to `IFRAME_LOAD_TIMEOUT_MS`. */
54
54
  timeoutMs?: number;
@@ -69,10 +69,10 @@ export declare class IframeLoadError extends Error {
69
69
  * success; throws `IframeLoadError` (reason + final attempt count) on final
70
70
  * failure, or `DOMException("AbortError")` when `opts.signal` aborts.
71
71
  *
72
- * The `versiq:ready` message is observed via a LOCAL listener that is detached
72
+ * The `gamaro:ready` message is observed via a LOCAL listener that is detached
73
73
  * the moment the handshake completes — the caller is expected to attach its
74
74
  * own applicative listener AFTER this resolves, and to manually set
75
75
  * `isReady = true` + send any post-ready commands, since the embed React app
76
- * only emits `versiq:ready` once on mount.
76
+ * only emits `gamaro:ready` once on mount.
77
77
  */
78
78
  export declare function loadIframeWithRetry(opts: IframeLoaderOptions): Promise<HTMLIFrameElement>;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Versiq Widget SDK
2
+ * Gamaro Widget SDK
3
3
  *
4
4
  * Entry point for the widget SDK. Supports both auto-initialization from
5
5
  * script tags and programmatic usage.
@@ -34,14 +34,14 @@
34
34
  * admin sandbox's live-preview use case (client-wins merge). Partner
35
35
  * integrators should configure those fields from the admin portal.
36
36
  */
37
- import { VersiqWidget, createWidget } from "./loader";
37
+ import { GamaroWidget, createWidget } from "./loader";
38
38
  import type { WidgetConfig } from "./types";
39
- export { createWidget, VersiqWidget };
39
+ export { createWidget, GamaroWidget };
40
40
  export { parseScriptAttributes as __parseScriptAttributes };
41
41
  export { getCurrentScript as __getCurrentScript };
42
42
  export { autoInit as __autoInit };
43
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";
44
+ export type { WidgetConfig, WidgetPosition, ColorScheme, ThemeConfig, B2BProfile, WidgetProfile, WidgetMessage, WidgetEvent, WidgetEventType, WidgetEventHandler, GamaroAPI, ApplicationConfigResponse, } from "./types";
45
45
  export { fetchApplicationConfig, ConfigFetchError } from "./config";
46
46
  /**
47
47
  * Parse script tag data attributes to extract widget config (#726).
package/dist/loader.d.ts CHANGED
@@ -6,9 +6,9 @@
6
6
  * - postMessage communication
7
7
  * - Public API exposure
8
8
  */
9
- import type { WidgetConfig, WidgetEventType, WidgetEventHandler, VersiqAPI, ColorScheme, ThemeConfig } from "./types";
9
+ import type { WidgetConfig, WidgetEventType, WidgetEventHandler, GamaroAPI, ColorScheme, ThemeConfig } from "./types";
10
10
  export declare function __resetInstanceCounter(): void;
11
- export declare class VersiqWidget implements VersiqAPI {
11
+ export declare class GamaroWidget implements GamaroAPI {
12
12
  readonly version = "0.1.0";
13
13
  /**
14
14
  * Original config as passed by the caller — preserved separately from
@@ -72,12 +72,12 @@ export declare class VersiqWidget implements VersiqAPI {
72
72
  */
73
73
  private setSkeletonStateUnavailable;
74
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.
75
+ * Resolve the widget runtime config from the server (#726). Retries
76
+ * along CONFIG_FETCH_BACKOFF_MS on *transient* failures (network,
77
+ * timeout, 5xx) — 4xx and parse errors are permanent config/setup
78
+ * problems that a retry cannot fix, so we surface them immediately. If
79
+ * every attempt fails, the skeleton stays visible and the widget emits
80
+ * `error` — visible degraded mode rather than a silently absent widget.
81
81
  */
82
82
  private resolveConfig;
83
83
  private isTransientFetchError;
@@ -100,7 +100,7 @@ export declare class VersiqWidget implements VersiqAPI {
100
100
  private init;
101
101
  /**
102
102
  * Strip any path from `baseUrl` so the resulting string matches the
103
- * `event.origin` field of a `versiq:ready` postMessage (which is always
103
+ * `event.origin` field of a `gamaro:ready` postMessage (which is always
104
104
  * scheme + host + port, no path). Falls back to the raw value if parsing
105
105
  * fails so a malformed config does not silently break the loader gate.
106
106
  */
@@ -143,4 +143,4 @@ export declare class VersiqWidget implements VersiqAPI {
143
143
  /**
144
144
  * Create a new widget instance.
145
145
  */
146
- export declare function createWidget(config: WidgetConfig): VersiqWidget;
146
+ export declare function createWidget(config: WidgetConfig): GamaroWidget;
@@ -15,9 +15,9 @@ import type { WidgetCommand, WidgetEvent } from "./types";
15
15
  */
16
16
  export declare function isValidOrigin(origin: string, allowedOrigins: string[]): boolean;
17
17
  /**
18
- * Check if an event contains a valid Versiq message.
18
+ * Check if an event contains a valid Gamaro message.
19
19
  */
20
- export declare function isVersiqMessage(event: MessageEvent): event is MessageEvent<WidgetCommand | WidgetEvent>;
20
+ export declare function isGamaroMessage(event: MessageEvent): event is MessageEvent<WidgetCommand | WidgetEvent>;
21
21
  /**
22
22
  * Send a command to the widget iframe.
23
23
  */
package/dist/types.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * re-exports them so existing consumers (`apps/marketing`,
7
7
  * `apps/app/src/components/portal/sandbox`) keep working unchanged. The only
8
8
  * types still defined locally are widget-specific SDK surfaces (B2B profile
9
- * schemas, `VersiqAPI`, `window` augmentation).
9
+ * schemas, `GamaroAPI`, `window` augmentation).
10
10
  */
11
11
  import { z } from "zod";
12
12
  import type { ColorScheme, ThemeConfig, WidgetEventHandler, WidgetEventType } from "@gamaro.io/core-types";
@@ -145,9 +145,9 @@ export declare const b2bProfileSchema: z.ZodObject<{
145
145
  }, z.core.$strip>;
146
146
  export type B2BProfile = z.infer<typeof b2bProfileSchema>;
147
147
  /**
148
- * Public API exposed on window.Versiq.
148
+ * Public API exposed on window.Gamaro.
149
149
  */
150
- export interface VersiqAPI {
150
+ export interface GamaroAPI {
151
151
  /** Application ID (available after config resolution) */
152
152
  readonly applicationId: string;
153
153
  /** Open the widget */
@@ -156,12 +156,17 @@ export interface VersiqAPI {
156
156
  close(): void;
157
157
  /** Reset the conversation */
158
158
  reset(): void;
159
+ /**
160
+ * Tear the widget down: remove it from the DOM, detach its listeners and
161
+ * abort in-flight requests. Idempotent.
162
+ */
163
+ destroy(): void;
159
164
  /** Update theme dynamically */
160
165
  setTheme(theme: ThemeConfig): void;
161
166
  /**
162
167
  * Update only the color scheme. Sugar over `setTheme({ colorScheme })` so
163
168
  * integrators can wire their own dark-mode toggle without rebuilding the
164
- * full theme object: `window.Versiq.setColorScheme("dark")`.
169
+ * full theme object: `window.Gamaro.setColorScheme("dark")`.
165
170
  */
166
171
  setColorScheme(scheme: ColorScheme): void;
167
172
  /** Identify the current user with host-attested HMAC verification */
@@ -179,7 +184,7 @@ export interface VersiqAPI {
179
184
  }
180
185
  declare global {
181
186
  interface Window {
182
- Versiq?: VersiqAPI;
183
- VersiqApps?: Map<string, VersiqAPI>;
187
+ Gamaro?: GamaroAPI;
188
+ GamaroApps?: Map<string, GamaroAPI>;
184
189
  }
185
190
  }