@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 +68 -65
- package/THIRD_PARTY_NOTICES.md +34 -0
- package/dist/iframe-loader.d.ts +5 -5
- package/dist/index.d.ts +4 -4
- package/dist/loader.d.ts +10 -10
- package/dist/postmessage.d.ts +2 -2
- package/dist/types.d.ts +11 -6
- package/dist/widget.es.js +3145 -1780
- package/dist/widget.umd.js +75 -32
- package/package.json +20 -14
package/README.md
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
[](#typescript)
|
|
6
6
|
[](./LICENSE)
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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 **
|
|
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
|
|
97
|
-
from your catalogue, your stock, your CRM, your knowledge
|
|
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
|
|
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
|
|
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 |
|
|
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
|
-
###
|
|
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.
|
|
219
|
+
When using the script tag, the API is available on `window.Gamaro`:
|
|
219
220
|
|
|
220
221
|
```javascript
|
|
221
|
-
window.
|
|
222
|
-
window.
|
|
223
|
-
window.
|
|
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.
|
|
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
|
|
268
|
-
| `cta-clicked` | `{ ctaType: string, objectiveId?: string }` | A call-to-action was clicked
|
|
269
|
-
| `lead-captured` | `{ hasEmail: boolean, hasPhone: boolean }` |
|
|
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
|
-
|
|
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:
|
|
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
|
|
385
|
+
import { createWidget, type GamaroWidget } from "@gamaro.io/widget";
|
|
385
386
|
|
|
386
387
|
export function ContactWidget() {
|
|
387
|
-
const widgetRef = useRef<
|
|
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
|
-
|
|
416
|
-
the `<script>` tag
|
|
417
|
-
|
|
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
|
|
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
|
|
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
|
|
520
|
-
|
|
|
521
|
-
| `widget-root`
|
|
522
|
-
| `widget-input`
|
|
523
|
-
| `widget-send`
|
|
524
|
-
| `widget-message`
|
|
525
|
-
| `widget-loading-status`
|
|
526
|
-
| `widget-suggestion`
|
|
527
|
-
| `widget-cta-
|
|
528
|
-
| `widget-
|
|
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
|
|
533
|
-
> SDK consumers — the full contract lives in the
|
|
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
|
|
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
|
|
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
|
+
```
|
package/dist/iframe-loader.d.ts
CHANGED
|
@@ -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 (`
|
|
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 `
|
|
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 `
|
|
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 `
|
|
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 `
|
|
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
|
-
*
|
|
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 {
|
|
37
|
+
import { GamaroWidget, createWidget } from "./loader";
|
|
38
38
|
import type { WidgetConfig } from "./types";
|
|
39
|
-
export { createWidget,
|
|
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,
|
|
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,
|
|
9
|
+
import type { WidgetConfig, WidgetEventType, WidgetEventHandler, GamaroAPI, ColorScheme, ThemeConfig } from "./types";
|
|
10
10
|
export declare function __resetInstanceCounter(): void;
|
|
11
|
-
export declare class
|
|
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
|
|
76
|
-
*
|
|
77
|
-
* 4xx and parse errors are permanent config/setup
|
|
78
|
-
* retry cannot fix, so we surface them immediately. If
|
|
79
|
-
*
|
|
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 `
|
|
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):
|
|
146
|
+
export declare function createWidget(config: WidgetConfig): GamaroWidget;
|
package/dist/postmessage.d.ts
CHANGED
|
@@ -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
|
|
18
|
+
* Check if an event contains a valid Gamaro message.
|
|
19
19
|
*/
|
|
20
|
-
export declare function
|
|
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, `
|
|
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.
|
|
148
|
+
* Public API exposed on window.Gamaro.
|
|
149
149
|
*/
|
|
150
|
-
export interface
|
|
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.
|
|
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
|
-
|
|
183
|
-
|
|
187
|
+
Gamaro?: GamaroAPI;
|
|
188
|
+
GamaroApps?: Map<string, GamaroAPI>;
|
|
184
189
|
}
|
|
185
190
|
}
|