@clivly/chat-widget 0.14.1 → 0.16.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 +61 -1
- package/dist/browser-mount.cjs +470 -58
- package/dist/browser-mount.d.cts +73 -1
- package/dist/browser-mount.d.mts +73 -1
- package/dist/browser-mount.mjs +471 -59
- package/dist/browser.cjs +470 -58
- package/dist/browser.d.cts +73 -1
- package/dist/browser.d.mts +73 -1
- package/dist/browser.mjs +471 -59
- package/dist/index.cjs +470 -58
- package/dist/index.d.cts +76 -4
- package/dist/index.d.mts +76 -4
- package/dist/index.mjs +471 -59
- package/dist/widget.global.js +151 -299
- package/package.json +1 -1
package/dist/browser.d.cts
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
import { Root } from "react-dom/client";
|
|
2
2
|
import { CSSProperties } from "react";
|
|
3
|
+
//#region src/layout.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Where the widget sits on the host page, and what its launcher looks like.
|
|
6
|
+
*
|
|
7
|
+
* Until 0.16 the widget rendered in normal flow wherever it was mounted — the
|
|
8
|
+
* script tag inserted it directly after itself, so most embeds showed a
|
|
9
|
+
* full-width-label pill at the end of the page rather than a floating button.
|
|
10
|
+
* Floating in a corner is now the default; `"inline"` keeps the old behaviour
|
|
11
|
+
* for a host that positions the widget itself.
|
|
12
|
+
*/
|
|
13
|
+
type ChatWidgetPlacement = "bottom-left" | "bottom-right" | "inline";
|
|
14
|
+
/**
|
|
15
|
+
* - `"auto"` (default): the labelled pill on wide screens, a 48px icon-only
|
|
16
|
+
* button below 48rem, where a pill covers the host's own controls.
|
|
17
|
+
* - `"pill"`: always the labelled pill.
|
|
18
|
+
* - `"icon"`: always the icon-only button.
|
|
19
|
+
*
|
|
20
|
+
* The label stays the button's accessible name in every variant.
|
|
21
|
+
*/
|
|
22
|
+
type ChatWidgetLauncher = "auto" | "icon" | "pill";
|
|
23
|
+
//#endregion
|
|
3
24
|
//#region src/theme.d.ts
|
|
4
25
|
/**
|
|
5
26
|
* Theme resolution for the widget.
|
|
@@ -34,11 +55,30 @@ interface WidgetSummary {
|
|
|
34
55
|
}
|
|
35
56
|
interface WidgetMessage {
|
|
36
57
|
author: string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Set on messages the support assistant wrote (`greeting`, `topic`,
|
|
60
|
+
* `handoff`, `ai`, `ai_clarify`) and on a visitor's topic click
|
|
61
|
+
* (`topic_choice`). Absent or null on everything a person typed, and on
|
|
62
|
+
* every message from a server that predates the assistant.
|
|
63
|
+
*/
|
|
64
|
+
automation?: string | null;
|
|
37
65
|
body: string;
|
|
38
66
|
createdAt: string;
|
|
39
67
|
id: string;
|
|
40
68
|
senderType: WidgetSenderType;
|
|
41
69
|
}
|
|
70
|
+
type WidgetSupportState = "automated" | "handoff" | "human";
|
|
71
|
+
interface WidgetSupportTopic {
|
|
72
|
+
action: "answer" | "ask" | "link" | "human";
|
|
73
|
+
id: string;
|
|
74
|
+
label: string;
|
|
75
|
+
}
|
|
76
|
+
/** Guided support for one conversation. Answers stay on the server. */
|
|
77
|
+
interface WidgetSupport {
|
|
78
|
+
mode: "human" | "guided" | "ai";
|
|
79
|
+
state: WidgetSupportState | null;
|
|
80
|
+
topics: WidgetSupportTopic[];
|
|
81
|
+
}
|
|
42
82
|
interface WidgetSessionPayload {
|
|
43
83
|
contact: WidgetContact | null;
|
|
44
84
|
conversation: WidgetConversation;
|
|
@@ -46,6 +86,8 @@ interface WidgetSessionPayload {
|
|
|
46
86
|
messages: WidgetMessage[];
|
|
47
87
|
/** Absolute socket URL returned by Clivly's bootstrap. */
|
|
48
88
|
socketUrl?: string;
|
|
89
|
+
/** Absent or null when the widget has no guided support configured. */
|
|
90
|
+
support?: WidgetSupport | null;
|
|
49
91
|
token: string;
|
|
50
92
|
visitorToken: string;
|
|
51
93
|
widget: WidgetSummary;
|
|
@@ -65,6 +107,12 @@ interface WidgetClientCreateMessageEvent {
|
|
|
65
107
|
id: string;
|
|
66
108
|
type: "message.create";
|
|
67
109
|
}
|
|
110
|
+
/** The visitor picked a guided topic (see `ChatTransportConnection.selectTopic`). */
|
|
111
|
+
interface WidgetClientTopicEvent {
|
|
112
|
+
id: string;
|
|
113
|
+
topicId: string;
|
|
114
|
+
type: "topic.select";
|
|
115
|
+
}
|
|
68
116
|
interface WidgetSessionReadyEvent {
|
|
69
117
|
conversationId: string;
|
|
70
118
|
type: "session.ready";
|
|
@@ -83,11 +131,20 @@ interface WidgetMessageAckEvent {
|
|
|
83
131
|
message: WidgetMessage;
|
|
84
132
|
type: "message.ack";
|
|
85
133
|
}
|
|
134
|
+
interface WidgetSupportStateEvent {
|
|
135
|
+
state: WidgetSupportState;
|
|
136
|
+
type: "support.state";
|
|
137
|
+
}
|
|
138
|
+
/** The assistant is preparing an answer (`thinking`) or has finished (`idle`). */
|
|
139
|
+
interface WidgetAssistantStatusEvent {
|
|
140
|
+
status: "thinking" | "idle";
|
|
141
|
+
type: "assistant.status";
|
|
142
|
+
}
|
|
86
143
|
interface WidgetErrorEvent {
|
|
87
144
|
message: string;
|
|
88
145
|
type: "error";
|
|
89
146
|
}
|
|
90
|
-
type WidgetServerEvent = WidgetConversationSnapshotEvent | WidgetErrorEvent | WidgetMessageAckEvent | WidgetMessageCreatedEvent | WidgetSessionReadyEvent;
|
|
147
|
+
type WidgetServerEvent = WidgetAssistantStatusEvent | WidgetConversationSnapshotEvent | WidgetErrorEvent | WidgetMessageAckEvent | WidgetMessageCreatedEvent | WidgetSessionReadyEvent | WidgetSupportStateEvent;
|
|
91
148
|
//#endregion
|
|
92
149
|
//#region src/transport.d.ts
|
|
93
150
|
interface ChatTransportHandlers {
|
|
@@ -104,6 +161,11 @@ interface ChatTransportConnection {
|
|
|
104
161
|
* without it still works, its visitors are just emailed replies they saw.
|
|
105
162
|
*/
|
|
106
163
|
markRead?: () => void;
|
|
164
|
+
/**
|
|
165
|
+
* Send a guided-topic click. Optional: without it the widget sends the
|
|
166
|
+
* topic's label as an ordinary message, so a custom transport still works.
|
|
167
|
+
*/
|
|
168
|
+
selectTopic?: (event: WidgetClientTopicEvent) => void;
|
|
107
169
|
sendMessage: (event: WidgetClientCreateMessageEvent) => void;
|
|
108
170
|
}
|
|
109
171
|
interface CreateChatTransportOptions {
|
|
@@ -136,7 +198,17 @@ interface ChatWidgetProps {
|
|
|
136
198
|
defaultVisitor?: Partial<ChatWidgetVisitor>;
|
|
137
199
|
getSession: GetSession;
|
|
138
200
|
initiallyOpen?: boolean;
|
|
201
|
+
/** Launcher shape; see {@link ChatWidgetLauncher}. Defaults to `"auto"`. */
|
|
202
|
+
launcher?: ChatWidgetLauncher;
|
|
203
|
+
/** The launcher's visible text, and always its accessible name. */
|
|
139
204
|
launcherLabel?: string;
|
|
205
|
+
/**
|
|
206
|
+
* Where the widget sits; see {@link ChatWidgetPlacement}. Defaults to
|
|
207
|
+
* `"bottom-right"`, floating clear of the device's safe-area insets. Stacks
|
|
208
|
+
* at `--clivly-chat-z-index` (default 2147483000) — lower it through
|
|
209
|
+
* `style` to sit beneath the host's own dialogs.
|
|
210
|
+
*/
|
|
211
|
+
placement?: ChatWidgetPlacement;
|
|
140
212
|
storage?: Pick<Storage, "getItem" | "setItem">;
|
|
141
213
|
/**
|
|
142
214
|
* Inline styles on the widget root. The intended use is overriding palette
|
package/dist/browser.d.mts
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
import { Root } from "react-dom/client";
|
|
2
2
|
import { CSSProperties } from "react";
|
|
3
|
+
//#region src/layout.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Where the widget sits on the host page, and what its launcher looks like.
|
|
6
|
+
*
|
|
7
|
+
* Until 0.16 the widget rendered in normal flow wherever it was mounted — the
|
|
8
|
+
* script tag inserted it directly after itself, so most embeds showed a
|
|
9
|
+
* full-width-label pill at the end of the page rather than a floating button.
|
|
10
|
+
* Floating in a corner is now the default; `"inline"` keeps the old behaviour
|
|
11
|
+
* for a host that positions the widget itself.
|
|
12
|
+
*/
|
|
13
|
+
type ChatWidgetPlacement = "bottom-left" | "bottom-right" | "inline";
|
|
14
|
+
/**
|
|
15
|
+
* - `"auto"` (default): the labelled pill on wide screens, a 48px icon-only
|
|
16
|
+
* button below 48rem, where a pill covers the host's own controls.
|
|
17
|
+
* - `"pill"`: always the labelled pill.
|
|
18
|
+
* - `"icon"`: always the icon-only button.
|
|
19
|
+
*
|
|
20
|
+
* The label stays the button's accessible name in every variant.
|
|
21
|
+
*/
|
|
22
|
+
type ChatWidgetLauncher = "auto" | "icon" | "pill";
|
|
23
|
+
//#endregion
|
|
3
24
|
//#region src/theme.d.ts
|
|
4
25
|
/**
|
|
5
26
|
* Theme resolution for the widget.
|
|
@@ -34,11 +55,30 @@ interface WidgetSummary {
|
|
|
34
55
|
}
|
|
35
56
|
interface WidgetMessage {
|
|
36
57
|
author: string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Set on messages the support assistant wrote (`greeting`, `topic`,
|
|
60
|
+
* `handoff`, `ai`, `ai_clarify`) and on a visitor's topic click
|
|
61
|
+
* (`topic_choice`). Absent or null on everything a person typed, and on
|
|
62
|
+
* every message from a server that predates the assistant.
|
|
63
|
+
*/
|
|
64
|
+
automation?: string | null;
|
|
37
65
|
body: string;
|
|
38
66
|
createdAt: string;
|
|
39
67
|
id: string;
|
|
40
68
|
senderType: WidgetSenderType;
|
|
41
69
|
}
|
|
70
|
+
type WidgetSupportState = "automated" | "handoff" | "human";
|
|
71
|
+
interface WidgetSupportTopic {
|
|
72
|
+
action: "answer" | "ask" | "link" | "human";
|
|
73
|
+
id: string;
|
|
74
|
+
label: string;
|
|
75
|
+
}
|
|
76
|
+
/** Guided support for one conversation. Answers stay on the server. */
|
|
77
|
+
interface WidgetSupport {
|
|
78
|
+
mode: "human" | "guided" | "ai";
|
|
79
|
+
state: WidgetSupportState | null;
|
|
80
|
+
topics: WidgetSupportTopic[];
|
|
81
|
+
}
|
|
42
82
|
interface WidgetSessionPayload {
|
|
43
83
|
contact: WidgetContact | null;
|
|
44
84
|
conversation: WidgetConversation;
|
|
@@ -46,6 +86,8 @@ interface WidgetSessionPayload {
|
|
|
46
86
|
messages: WidgetMessage[];
|
|
47
87
|
/** Absolute socket URL returned by Clivly's bootstrap. */
|
|
48
88
|
socketUrl?: string;
|
|
89
|
+
/** Absent or null when the widget has no guided support configured. */
|
|
90
|
+
support?: WidgetSupport | null;
|
|
49
91
|
token: string;
|
|
50
92
|
visitorToken: string;
|
|
51
93
|
widget: WidgetSummary;
|
|
@@ -65,6 +107,12 @@ interface WidgetClientCreateMessageEvent {
|
|
|
65
107
|
id: string;
|
|
66
108
|
type: "message.create";
|
|
67
109
|
}
|
|
110
|
+
/** The visitor picked a guided topic (see `ChatTransportConnection.selectTopic`). */
|
|
111
|
+
interface WidgetClientTopicEvent {
|
|
112
|
+
id: string;
|
|
113
|
+
topicId: string;
|
|
114
|
+
type: "topic.select";
|
|
115
|
+
}
|
|
68
116
|
interface WidgetSessionReadyEvent {
|
|
69
117
|
conversationId: string;
|
|
70
118
|
type: "session.ready";
|
|
@@ -83,11 +131,20 @@ interface WidgetMessageAckEvent {
|
|
|
83
131
|
message: WidgetMessage;
|
|
84
132
|
type: "message.ack";
|
|
85
133
|
}
|
|
134
|
+
interface WidgetSupportStateEvent {
|
|
135
|
+
state: WidgetSupportState;
|
|
136
|
+
type: "support.state";
|
|
137
|
+
}
|
|
138
|
+
/** The assistant is preparing an answer (`thinking`) or has finished (`idle`). */
|
|
139
|
+
interface WidgetAssistantStatusEvent {
|
|
140
|
+
status: "thinking" | "idle";
|
|
141
|
+
type: "assistant.status";
|
|
142
|
+
}
|
|
86
143
|
interface WidgetErrorEvent {
|
|
87
144
|
message: string;
|
|
88
145
|
type: "error";
|
|
89
146
|
}
|
|
90
|
-
type WidgetServerEvent = WidgetConversationSnapshotEvent | WidgetErrorEvent | WidgetMessageAckEvent | WidgetMessageCreatedEvent | WidgetSessionReadyEvent;
|
|
147
|
+
type WidgetServerEvent = WidgetAssistantStatusEvent | WidgetConversationSnapshotEvent | WidgetErrorEvent | WidgetMessageAckEvent | WidgetMessageCreatedEvent | WidgetSessionReadyEvent | WidgetSupportStateEvent;
|
|
91
148
|
//#endregion
|
|
92
149
|
//#region src/transport.d.ts
|
|
93
150
|
interface ChatTransportHandlers {
|
|
@@ -104,6 +161,11 @@ interface ChatTransportConnection {
|
|
|
104
161
|
* without it still works, its visitors are just emailed replies they saw.
|
|
105
162
|
*/
|
|
106
163
|
markRead?: () => void;
|
|
164
|
+
/**
|
|
165
|
+
* Send a guided-topic click. Optional: without it the widget sends the
|
|
166
|
+
* topic's label as an ordinary message, so a custom transport still works.
|
|
167
|
+
*/
|
|
168
|
+
selectTopic?: (event: WidgetClientTopicEvent) => void;
|
|
107
169
|
sendMessage: (event: WidgetClientCreateMessageEvent) => void;
|
|
108
170
|
}
|
|
109
171
|
interface CreateChatTransportOptions {
|
|
@@ -136,7 +198,17 @@ interface ChatWidgetProps {
|
|
|
136
198
|
defaultVisitor?: Partial<ChatWidgetVisitor>;
|
|
137
199
|
getSession: GetSession;
|
|
138
200
|
initiallyOpen?: boolean;
|
|
201
|
+
/** Launcher shape; see {@link ChatWidgetLauncher}. Defaults to `"auto"`. */
|
|
202
|
+
launcher?: ChatWidgetLauncher;
|
|
203
|
+
/** The launcher's visible text, and always its accessible name. */
|
|
139
204
|
launcherLabel?: string;
|
|
205
|
+
/**
|
|
206
|
+
* Where the widget sits; see {@link ChatWidgetPlacement}. Defaults to
|
|
207
|
+
* `"bottom-right"`, floating clear of the device's safe-area insets. Stacks
|
|
208
|
+
* at `--clivly-chat-z-index` (default 2147483000) — lower it through
|
|
209
|
+
* `style` to sit beneath the host's own dialogs.
|
|
210
|
+
*/
|
|
211
|
+
placement?: ChatWidgetPlacement;
|
|
140
212
|
storage?: Pick<Storage, "getItem" | "setItem">;
|
|
141
213
|
/**
|
|
142
214
|
* Inline styles on the widget root. The intended use is overriding palette
|