@epam/ai-dial-chat-overlay 1.0.0-dev.550

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/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export { ChatOverlay } from './lib/ChatOverlay';
2
+ export { ChatOverlayManager, OverlayPosition } from './lib/ChatOverlayManager';
3
+ export type { ChatOverlayManagerOptions } from './lib/ChatOverlayManager';
4
+ export type { ChatOverlayOptions, GetMessagesResponse, OverlayChatMessage, SendMessageResponse, SetOverlayOptionsResponse, SetSystemPromptResponse, SetTemperatureResponse, } from '@epam/ai-dial-chat-shared';
5
+ export { OverlayEventType, OverlayFeature, OverlayRequestType, } from '@epam/ai-dial-chat-shared';
6
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC/E,YAAY,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAE1E,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,GACnB,MAAM,2BAA2B,CAAC"}
package/index.js ADDED
@@ -0,0 +1,345 @@
1
+ import { OverlayEventType as e, OverlayEventType as t, OverlayFeature as n, OverlayFeature as r, OverlayRequestType as i, OverlayRequestType as a, isOverlayMessageEvent as o, isOverlayMessageResponse as s } from "@epam/ai-dial-chat-shared";
2
+ //#region src/lib/internal/default-loader.ts
3
+ var c = "<svg viewBox=\"0 0 50 50\" width=\"32\" height=\"32\" role=\"presentation\" aria-hidden=\"true\"><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-dasharray=\"31.4 31.4\"><animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"1s\" repeatCount=\"indefinite\" /></circle></svg>", l = 0, u = () => (l += 1, `dial-overlay-${Date.now()}-${l}`), d = class {
4
+ requestId;
5
+ responseType;
6
+ promise;
7
+ resolveFn;
8
+ rejectFn;
9
+ settled = !1;
10
+ timeoutHandle;
11
+ constructor(e, t) {
12
+ this.requestId = u(), this.responseType = `${e}/RESPONSE`, this.promise = new Promise((e, t) => {
13
+ this.resolveFn = e, this.rejectFn = t;
14
+ }), this.timeoutHandle = setTimeout(() => {
15
+ this.reject(/* @__PURE__ */ Error(`ChatOverlay: request "${e}" timed out after ${t}ms`));
16
+ }, t);
17
+ }
18
+ matches(e, t) {
19
+ return this.responseType === e && this.requestId === t;
20
+ }
21
+ resolve(e) {
22
+ this.settled || (this.settled = !0, clearTimeout(this.timeoutHandle), this.resolveFn(e));
23
+ }
24
+ reject(e) {
25
+ this.settled || (this.settled = !0, clearTimeout(this.timeoutHandle), this.rejectFn(e));
26
+ }
27
+ }, f = (e, t) => {
28
+ Object.assign(e.style, t);
29
+ }, p = class {
30
+ promise;
31
+ resolveFn;
32
+ rejectFn;
33
+ settled = !1;
34
+ constructor() {
35
+ this.promise = new Promise((e, t) => {
36
+ this.resolveFn = e, this.rejectFn = t;
37
+ });
38
+ }
39
+ resolve(e) {
40
+ this.settled || (this.settled = !0, this.resolveFn(e));
41
+ }
42
+ reject(e) {
43
+ this.settled || (this.settled = !0, this.rejectFn(e));
44
+ }
45
+ }, m = 1e4, h = "data-dial-overlay-loader", g = (e) => {
46
+ if (typeof e != "string") return e;
47
+ let t = document.querySelector(e);
48
+ if (!t) throw Error(`ChatOverlay: no element matches selector "${e}"`);
49
+ return t;
50
+ }, _ = (e) => {
51
+ let t = document.createElement("iframe");
52
+ t.src = e.domain, t.name = "overlay", t.setAttribute("aria-label", "DIAL Chat"), t.setAttribute("sandbox", "allow-same-origin allow-scripts allow-modals allow-forms allow-popups allow-downloads allow-popups-to-escape-sandbox");
53
+ let n = ["clipboard-write"];
54
+ return e.enabledFeatures?.includes(r.VoiceInput) && n.push("microphone"), t.setAttribute("allow", n.join("; ")), f(t, {
55
+ border: "none",
56
+ display: "block",
57
+ width: "100%",
58
+ height: "100%"
59
+ }), t;
60
+ }, v = (e) => {
61
+ let t = document.createElement("div");
62
+ return t.setAttribute(h, ""), t.innerHTML = e.loaderInnerHTML ?? c, f(t, {
63
+ position: "absolute",
64
+ inset: "0",
65
+ zIndex: "2",
66
+ display: "flex",
67
+ alignItems: "center",
68
+ justifyContent: "center",
69
+ boxSizing: "border-box",
70
+ background: "#ffffff",
71
+ color: "#2764d9"
72
+ }), e.loaderClass && (t.className = e.loaderClass), e.loaderStyles && f(t, e.loaderStyles), t;
73
+ }, y = class {
74
+ root;
75
+ iframe;
76
+ loader;
77
+ options;
78
+ targetOrigin;
79
+ readyGate = new p();
80
+ pendingRequests = /* @__PURE__ */ new Map();
81
+ eventSubscribers = /* @__PURE__ */ new Map();
82
+ messageListener = (e) => {
83
+ this.handleMessage(e);
84
+ };
85
+ isDestroyed = !1;
86
+ constructor(e, t) {
87
+ this.root = g(e), this.options = { ...t }, this.targetOrigin = new URL(t.domain).origin, this.iframe = _(this.options), this.loader = v(this.options);
88
+ let n = window.getComputedStyle(this.root).position;
89
+ (n === "static" || n === "") && f(this.root, { position: "relative" }), this.root.appendChild(this.loader), this.root.appendChild(this.iframe), window.addEventListener("message", this.messageListener), this.readyGate.promise.catch(() => void 0);
90
+ }
91
+ ready() {
92
+ return this.readyGate.promise;
93
+ }
94
+ getMessages() {
95
+ return this.send(a.GetMessages);
96
+ }
97
+ sendMessage(e) {
98
+ let t = { content: e };
99
+ return this.send(a.SendMessage, t);
100
+ }
101
+ setInputContent(e) {
102
+ let t = { content: e };
103
+ return this.send(a.SetInputContent, t);
104
+ }
105
+ setSystemPrompt(e) {
106
+ let t = { systemPrompt: e };
107
+ return this.send(a.SetSystemPrompt, t);
108
+ }
109
+ setTemperature(e) {
110
+ let t = { temperature: e };
111
+ return this.send(a.SetTemperature, t);
112
+ }
113
+ setOverlayOptions(e) {
114
+ return this.options.theme = e.theme ?? this.options.theme, this.options.modelId = e.modelId ?? this.options.modelId, this.options.overlayConversationId = e.overlayConversationId ?? this.options.overlayConversationId, this.sendCurrentOverlayOptions();
115
+ }
116
+ subscribe(e, t) {
117
+ let n = this.eventSubscribers.get(e) ?? /* @__PURE__ */ new Set(), r = t;
118
+ return n.add(r), this.eventSubscribers.set(e, n), () => {
119
+ n.delete(r);
120
+ };
121
+ }
122
+ allowFullscreen() {
123
+ this.iframe.setAttribute("allowfullscreen", "true");
124
+ let e = this.iframe.getAttribute("allow") ?? "";
125
+ e.includes("fullscreen") || this.iframe.setAttribute("allow", [e, "fullscreen"].filter(Boolean).join("; "));
126
+ }
127
+ async openFullscreen() {
128
+ typeof this.iframe.requestFullscreen == "function" && await this.iframe.requestFullscreen();
129
+ }
130
+ destroy() {
131
+ this.isDestroyed || (this.isDestroyed = !0, window.removeEventListener("message", this.messageListener), this.pendingRequests.forEach((e) => {
132
+ e.reject(/* @__PURE__ */ Error("ChatOverlay: instance was destroyed"));
133
+ }), this.pendingRequests.clear(), this.readyGate.reject(/* @__PURE__ */ Error("ChatOverlay: instance was destroyed")), this.iframe.remove(), this.loader.remove());
134
+ }
135
+ sendCurrentOverlayOptions() {
136
+ let e = { hostDomain: window.location.origin };
137
+ return this.options.theme !== void 0 && (e.theme = this.options.theme), this.options.modelId !== void 0 && (e.modelId = this.options.modelId), this.options.overlayConversationId !== void 0 && (e.overlayConversationId = this.options.overlayConversationId), this.send(a.SetOverlayOptions, e, { bypassReadyGate: !0 });
138
+ }
139
+ send(e, t, n) {
140
+ return this.isDestroyed ? Promise.reject(/* @__PURE__ */ Error("ChatOverlay: instance was destroyed")) : n?.bypassReadyGate ? this.dispatchRequest(e, t) : this.readyGate.promise.then(() => this.dispatchRequest(e, t));
141
+ }
142
+ dispatchRequest(e, t) {
143
+ if (this.isDestroyed) return Promise.reject(/* @__PURE__ */ Error("ChatOverlay: instance was destroyed"));
144
+ let n = this.options.requestTimeout ?? m, r = new d(e, n);
145
+ this.pendingRequests.set(r.requestId, r), r.promise.finally(() => {
146
+ this.pendingRequests.delete(r.requestId);
147
+ }).catch(() => void 0);
148
+ let i = {
149
+ type: e,
150
+ requestId: r.requestId,
151
+ expiresAt: Date.now() + n,
152
+ payload: t
153
+ };
154
+ return this.iframe.contentWindow?.postMessage(i, this.targetOrigin), r.promise;
155
+ }
156
+ handleMessage(e) {
157
+ if (e.source !== this.iframe.contentWindow) return;
158
+ let t = e.data;
159
+ if (s(t)) {
160
+ this.handleResponse(t);
161
+ return;
162
+ }
163
+ o(t) && this.handleEvent(t);
164
+ }
165
+ handleResponse(e) {
166
+ let t = this.pendingRequests.get(e.requestId);
167
+ !t || !t.matches(e.type, e.requestId) || (this.pendingRequests.delete(e.requestId), t.resolve(e.payload));
168
+ }
169
+ handleEvent(e) {
170
+ let n = e.type;
171
+ n === t.Ready && this.sendCurrentOverlayOptions().catch(() => void 0), n === (this.options.loaderHideEvent ?? t.Ready) && this.hideLoader(), n === t.ReadyToInteract && this.readyGate.resolve(!0), this.notifySubscribers(n, e.payload);
172
+ }
173
+ hideLoader() {
174
+ this.loader.style.display = "none";
175
+ }
176
+ notifySubscribers(e, t) {
177
+ this.eventSubscribers.get(e)?.forEach((e) => e(t));
178
+ }
179
+ }, b = 768, x = 380, S = 600, C = 999999, w = "24px", T = "<svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" aria-hidden=\"true\" focusable=\"false\"><path fill=\"currentColor\" d=\"M4 4h16v12H7l-3 3V4z\"/></svg>", E = "<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" aria-hidden=\"true\" focusable=\"false\"><path fill=\"currentColor\" d=\"M18.3 5.71 12 12.01l-6.3-6.3-1.4 1.41 6.29 6.29-6.29 6.29 1.4 1.41 6.3-6.3 6.3 6.3 1.4-1.41-6.29-6.29 6.29-6.29z\"/></svg>", D = "<svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" aria-hidden=\"true\" focusable=\"false\"><path fill=\"currentColor\" d=\"M4 4h6v2H6v4H4V4zm10 0h6v6h-2V6h-4V4zM4 14h2v4h4v2H4v-6zm14 0h2v6h-6v-2h4v-4z\"/></svg>", O = "dial-overlay-manager-styles", k = () => {
180
+ if (document.getElementById(O)) return;
181
+ let e = document.createElement("style");
182
+ e.id = O, e.textContent = "\n.dial-overlay-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n border: none;\n border-radius: 999px;\n cursor: pointer;\n background: #2764d9;\n color: #ffffff;\n}\n.dial-overlay-btn:hover,\n.dial-overlay-btn:focus-visible {\n background: #1d4fb8;\n outline: 2px solid #1d4fb8;\n outline-offset: 2px;\n}\n", document.head.appendChild(e);
183
+ }, A = (e, t) => {
184
+ let n = document.createElement("button");
185
+ return n.type = "button", n.className = "dial-overlay-btn", n.setAttribute("aria-label", e), n.innerHTML = t, n;
186
+ }, j = (e) => typeof e == "number" ? `${e}px` : e, M = /* @__PURE__ */ function(e) {
187
+ return e.LeftBottom = "left-bottom", e.LeftTop = "left-top", e.RightBottom = "right-bottom", e.RightTop = "right-top", e;
188
+ }({}), N = {
189
+ "right-bottom": {
190
+ insetInlineEnd: w,
191
+ insetBlockEnd: w,
192
+ insetInlineStart: "auto",
193
+ insetBlockStart: "auto"
194
+ },
195
+ "right-top": {
196
+ insetInlineEnd: w,
197
+ insetBlockStart: w,
198
+ insetInlineStart: "auto",
199
+ insetBlockEnd: "auto"
200
+ },
201
+ "left-bottom": {
202
+ insetInlineStart: w,
203
+ insetBlockEnd: w,
204
+ insetInlineEnd: "auto",
205
+ insetBlockStart: "auto"
206
+ },
207
+ "left-top": {
208
+ insetInlineStart: w,
209
+ insetBlockStart: w,
210
+ insetInlineEnd: "auto",
211
+ insetBlockEnd: "auto"
212
+ }
213
+ }, P = class {
214
+ overlays = /* @__PURE__ */ new Map();
215
+ abortController = new AbortController();
216
+ isDestroyed = !1;
217
+ constructor() {
218
+ let e = () => {
219
+ this.overlays.forEach((e) => this.applyLayout(e));
220
+ };
221
+ window.addEventListener("resize", e, { signal: this.abortController.signal }), window.addEventListener("orientationchange", e, { signal: this.abortController.signal });
222
+ }
223
+ createOverlay(e) {
224
+ if (this.overlays.has(e.overlayId)) throw Error(`ChatOverlayManager: overlay "${e.overlayId}" already exists`);
225
+ k();
226
+ let t = document.createElement("div");
227
+ t.setAttribute("data-dial-overlay-container", e.overlayId), f(t, {
228
+ display: "flex",
229
+ flexDirection: "column",
230
+ overflow: "hidden",
231
+ borderRadius: "12px",
232
+ boxShadow: "0 8px 24px rgba(0, 0, 0, 0.24)",
233
+ background: "#ffffff"
234
+ });
235
+ let n = document.createElement("div");
236
+ f(n, {
237
+ display: "flex",
238
+ justifyContent: "flex-end",
239
+ gap: "8px",
240
+ padding: "8px"
241
+ });
242
+ let r = A(e.closeButtonAriaLabel ?? "Collapse", E);
243
+ n.appendChild(r);
244
+ let i;
245
+ e.allowFullscreen && (i = A(e.fullscreenButtonAriaLabel ?? "Open full screen", D), n.appendChild(i));
246
+ let a = document.createElement("div");
247
+ f(a, {
248
+ flex: "1",
249
+ minHeight: "0"
250
+ }), t.appendChild(n), t.appendChild(a), document.body.appendChild(t);
251
+ let o = new y(a, e);
252
+ e.allowFullscreen && o.allowFullscreen();
253
+ let s = A(e.toggleButtonAriaLabel ?? "Open chat", T);
254
+ document.body.appendChild(s);
255
+ let c = {
256
+ overlay: o,
257
+ container: t,
258
+ toggleButton: s,
259
+ closeButton: r,
260
+ fullscreenButton: i,
261
+ options: e
262
+ };
263
+ this.overlays.set(e.overlayId, c), s.addEventListener("click", () => this.showOverlay(e.overlayId)), r.addEventListener("click", () => this.hideOverlay(e.overlayId)), i?.addEventListener("click", () => {
264
+ this.openFullscreen(e.overlayId);
265
+ }), this.applyLayout(c), this.hideOverlay(e.overlayId);
266
+ }
267
+ showOverlay(e) {
268
+ let t = this.getEntry(e);
269
+ t.container.style.display = "flex", t.toggleButton.style.display = "none";
270
+ }
271
+ hideOverlay(e) {
272
+ let t = this.getEntry(e);
273
+ t.container.style.display = "none", t.toggleButton.style.display = "inline-flex";
274
+ }
275
+ removeOverlay(e) {
276
+ let t = this.getEntry(e);
277
+ t.overlay.destroy(), t.container.remove(), t.toggleButton.remove(), this.overlays.delete(e);
278
+ }
279
+ ready(e) {
280
+ return this.getEntry(e).overlay.ready();
281
+ }
282
+ getMessages(e) {
283
+ return this.getEntry(e).overlay.getMessages();
284
+ }
285
+ sendMessage(e, t) {
286
+ return this.getEntry(e).overlay.sendMessage(t);
287
+ }
288
+ setInputContent(e, t) {
289
+ return this.getEntry(e).overlay.setInputContent(t);
290
+ }
291
+ setSystemPrompt(e, t) {
292
+ return this.getEntry(e).overlay.setSystemPrompt(t);
293
+ }
294
+ setTemperature(e, t) {
295
+ return this.getEntry(e).overlay.setTemperature(t);
296
+ }
297
+ setOverlayOptions(e, t) {
298
+ return this.getEntry(e).overlay.setOverlayOptions(t);
299
+ }
300
+ subscribe(e, t, n) {
301
+ return this.getEntry(e).overlay.subscribe(t, n);
302
+ }
303
+ openFullscreen(e) {
304
+ return this.getEntry(e).overlay.openFullscreen();
305
+ }
306
+ destroy() {
307
+ this.isDestroyed || (this.isDestroyed = !0, this.overlays.forEach((e) => {
308
+ e.overlay.destroy(), e.container.remove(), e.toggleButton.remove();
309
+ }), this.overlays.clear(), this.abortController.abort());
310
+ }
311
+ getEntry(e) {
312
+ let t = this.overlays.get(e);
313
+ if (!t) throw Error(`ChatOverlayManager: unknown overlay id "${e}"`);
314
+ return t;
315
+ }
316
+ applyLayout(e) {
317
+ let { options: t, container: n, toggleButton: r } = e, i = t.position ?? "right-bottom", a = String(t.zIndex ?? C);
318
+ if (f(r, {
319
+ position: "fixed",
320
+ zIndex: a,
321
+ ...N[i]
322
+ }), f(n, {
323
+ position: "fixed",
324
+ zIndex: a
325
+ }), window.innerWidth <= b) {
326
+ f(n, {
327
+ insetInlineStart: "0",
328
+ insetInlineEnd: "0",
329
+ insetBlockStart: "0",
330
+ insetBlockEnd: "0",
331
+ width: "100%",
332
+ height: "100%",
333
+ borderRadius: "0"
334
+ });
335
+ return;
336
+ }
337
+ f(n, {
338
+ width: j(t.width ?? x),
339
+ height: j(t.height ?? S),
340
+ ...N[i]
341
+ });
342
+ }
343
+ };
344
+ //#endregion
345
+ export { y as ChatOverlay, P as ChatOverlayManager, e as OverlayEventType, n as OverlayFeature, M as OverlayPosition, i as OverlayRequestType };
@@ -0,0 +1,57 @@
1
+ import { ChatOverlayOptions, GetMessagesResponse, OverlayEventType, SendMessageResponse, SetOverlayOptionsResponse, SetSystemPromptResponse, SetTemperatureResponse } from '@epam/ai-dial-chat-shared';
2
+ /**
3
+ * A single embedded DIAL Chat iframe controlled over the `@DIAL_OVERLAY`
4
+ * `postMessage` protocol. Construct with a root element (or selector) and
5
+ * `ChatOverlayOptions`; call `ready()` before issuing chat requests.
6
+ */
7
+ export declare class ChatOverlay {
8
+ private readonly root;
9
+ private readonly iframe;
10
+ private readonly loader;
11
+ private readonly options;
12
+ private readonly targetOrigin;
13
+ private readonly readyGate;
14
+ private readonly pendingRequests;
15
+ private readonly eventSubscribers;
16
+ private readonly messageListener;
17
+ private isDestroyed;
18
+ constructor(root: HTMLElement | string, options: ChatOverlayOptions);
19
+ /** Resolves once the handshake reaches `READY_TO_INTERACT`. */
20
+ ready(): Promise<boolean>;
21
+ /** Fetches the active conversation's messages. */
22
+ getMessages(): Promise<GetMessagesResponse>;
23
+ /** Sends a new message in the active conversation. */
24
+ sendMessage(content: string): Promise<SendMessageResponse>;
25
+ /** Sets the current text content of the message input. */
26
+ setInputContent(content: string): Promise<void>;
27
+ /** Sets the active conversation's system prompt. */
28
+ setSystemPrompt(systemPrompt: string): Promise<SetSystemPromptResponse>;
29
+ /** Sets the active conversation's temperature. */
30
+ setTemperature(temperature: number): Promise<SetTemperatureResponse>;
31
+ /**
32
+ * Updates theme/model/conversation options and re-sends them to the
33
+ * embedded app. Bypasses the readiness gate — it is also how the initial
34
+ * handshake options exchange happens, before `ready()` resolves.
35
+ */
36
+ setOverlayOptions(options: Partial<Pick<ChatOverlayOptions, 'theme' | 'modelId' | 'overlayConversationId'>>): Promise<SetOverlayOptionsResponse>;
37
+ /** Registers `callback` to be invoked with each `eventType` event's payload. */
38
+ subscribe<T = unknown>(eventType: OverlayEventType, callback: (payload: T) => void): () => void;
39
+ /** Grants the iframe permission to enter fullscreen. */
40
+ allowFullscreen(): void;
41
+ /** Requests fullscreen on the iframe element. */
42
+ openFullscreen(): Promise<void>;
43
+ /**
44
+ * Removes the `message` listener, rejects all pending requests, and
45
+ * removes the iframe/loader from `root`. Calling twice is a no-op.
46
+ */
47
+ destroy(): void;
48
+ private sendCurrentOverlayOptions;
49
+ private send;
50
+ private dispatchRequest;
51
+ private handleMessage;
52
+ private handleResponse;
53
+ private handleEvent;
54
+ private hideLoader;
55
+ private notifySubscribers;
56
+ }
57
+ //# sourceMappingURL=ChatOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatOverlay.d.ts","sourceRoot":"","sources":["../../src/lib/ChatOverlay.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EAIxB,gBAAgB,EAIhB,KAAK,mBAAmB,EAGxB,KAAK,yBAAyB,EAE9B,KAAK,uBAAuB,EAE5B,KAAK,sBAAsB,EAG5B,MAAM,2BAA2B,CAAC;AAmEnC;;;;GAIG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAG5B;IACJ,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAG7B;IACJ,OAAO,CAAC,QAAQ,CAAC,eAAe,CAE9B;IACF,OAAO,CAAC,WAAW,CAAS;gBAEhB,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE,OAAO,EAAE,kBAAkB;IAmBnE,+DAA+D;IAC/D,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAIzB,kDAAkD;IAClD,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAI3C,sDAAsD;IACtD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQ1D,0DAA0D;IAC1D,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/C,oDAAoD;IACpD,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAQvE,kDAAkD;IAClD,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAQpE;;;;OAIG;IACH,iBAAiB,CACf,OAAO,EAAE,OAAO,CACd,IAAI,CAAC,kBAAkB,EAAE,OAAO,GAAG,SAAS,GAAG,uBAAuB,CAAC,CACxE,GACA,OAAO,CAAC,yBAAyB,CAAC;IAQrC,gFAAgF;IAChF,SAAS,CAAC,CAAC,GAAG,OAAO,EACnB,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,GAC7B,MAAM,IAAI;IAYb,wDAAwD;IACxD,eAAe,IAAI,IAAI;IAWvB,iDAAiD;IAC3C,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrC;;;OAGG;IACH,OAAO,IAAI,IAAI;IAef,OAAO,CAAC,yBAAyB;IAoBjC,OAAO,CAAC,IAAI;IAkBZ,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,iBAAiB;CAO1B"}
@@ -0,0 +1,75 @@
1
+ import { ChatOverlayOptions, GetMessagesResponse, OverlayEventType, SendMessageResponse, SetOverlayOptionsResponse, SetSystemPromptResponse, SetTemperatureResponse } from '@epam/ai-dial-chat-shared';
2
+ /** Fixed-position placement for a `ChatOverlayManager`-created overlay. */
3
+ export declare enum OverlayPosition {
4
+ /** Anchored to the start (left in LTR) edge, bottom corner. */
5
+ LeftBottom = "left-bottom",
6
+ /** Anchored to the start (left in LTR) edge, top corner. */
7
+ LeftTop = "left-top",
8
+ /** Anchored to the end (right in LTR) edge, bottom corner. Default. */
9
+ RightBottom = "right-bottom",
10
+ /** Anchored to the end (right in LTR) edge, top corner. */
11
+ RightTop = "right-top"
12
+ }
13
+ /** Options for `ChatOverlayManager.createOverlay`. */
14
+ export interface ChatOverlayManagerOptions extends ChatOverlayOptions {
15
+ /** Unique id used to reference this overlay in every manager method. */
16
+ overlayId: string;
17
+ /** Fixed-position corner. Defaults to `OverlayPosition.RightBottom`. */
18
+ position?: OverlayPosition;
19
+ /** Panel width (number treated as px). Defaults to `380`. */
20
+ width?: number | string;
21
+ /** Panel height (number treated as px). Defaults to `600`. */
22
+ height?: number | string;
23
+ /** CSS `z-index` for the panel and toggle button. Defaults to `999999`. */
24
+ zIndex?: number;
25
+ /** Whether to render a fullscreen button in the panel header. */
26
+ allowFullscreen?: boolean;
27
+ /** Accessible name for the toggle button. Defaults to `'Open chat'`. */
28
+ toggleButtonAriaLabel?: string;
29
+ /** Accessible name for the close button. Defaults to `'Collapse'`. */
30
+ closeButtonAriaLabel?: string;
31
+ /** Accessible name for the fullscreen button. Defaults to `'Open full screen'`. */
32
+ fullscreenButtonAriaLabel?: string;
33
+ }
34
+ /**
35
+ * Creates and positions one or more `ChatOverlay` instances behind
36
+ * fixed-position toggle/close/(optional) fullscreen chrome, keyed by
37
+ * `overlayId`.
38
+ */
39
+ export declare class ChatOverlayManager {
40
+ private readonly overlays;
41
+ private readonly abortController;
42
+ private isDestroyed;
43
+ constructor();
44
+ /** Creates an overlay and its toggle/close/(optional) fullscreen chrome. */
45
+ createOverlay(options: ChatOverlayManagerOptions): void;
46
+ /** Shows the overlay panel and hides its toggle button. */
47
+ showOverlay(overlayId: string): void;
48
+ /** Hides the overlay panel and shows its toggle button. */
49
+ hideOverlay(overlayId: string): void;
50
+ /** Destroys the overlay and removes its DOM (container, toggle button). */
51
+ removeOverlay(overlayId: string): void;
52
+ /** Resolves once `overlayId` reaches `READY_TO_INTERACT`. */
53
+ ready(overlayId: string): Promise<boolean>;
54
+ /** Fetches the active conversation's messages for `overlayId`. */
55
+ getMessages(overlayId: string): Promise<GetMessagesResponse>;
56
+ /** Sends a new message in `overlayId`'s active conversation. */
57
+ sendMessage(overlayId: string, content: string): Promise<SendMessageResponse>;
58
+ /** Sets `overlayId`'s message input content. */
59
+ setInputContent(overlayId: string, content: string): Promise<void>;
60
+ /** Sets `overlayId`'s active conversation system prompt. */
61
+ setSystemPrompt(overlayId: string, systemPrompt: string): Promise<SetSystemPromptResponse>;
62
+ /** Sets `overlayId`'s active conversation temperature. */
63
+ setTemperature(overlayId: string, temperature: number): Promise<SetTemperatureResponse>;
64
+ /** Updates theme/model/conversation options for `overlayId`. */
65
+ setOverlayOptions(overlayId: string, options: Partial<Pick<ChatOverlayOptions, 'theme' | 'modelId' | 'overlayConversationId'>>): Promise<SetOverlayOptionsResponse>;
66
+ /** Subscribes to an event from `overlayId`'s embedded app. */
67
+ subscribe<T = unknown>(overlayId: string, eventType: OverlayEventType, callback: (payload: T) => void): () => void;
68
+ /** Requests fullscreen for `overlayId`. */
69
+ openFullscreen(overlayId: string): Promise<void>;
70
+ /** Destroys every overlay and removes global `resize`/`orientationchange` listeners. */
71
+ destroy(): void;
72
+ private getEntry;
73
+ private applyLayout;
74
+ }
75
+ //# sourceMappingURL=ChatOverlayManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatOverlayManager.d.ts","sourceRoot":"","sources":["../../src/lib/ChatOverlayManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Default animated loader markup shown while the embedded app is not yet ready. */
2
+ export declare const DEFAULT_LOADER_INNER_HTML = "<svg viewBox=\"0 0 50 50\" width=\"32\" height=\"32\" role=\"presentation\" aria-hidden=\"true\"><circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-dasharray=\"31.4 31.4\"><animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"1s\" repeatCount=\"indefinite\" /></circle></svg>";
3
+ //# sourceMappingURL=default-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-loader.d.ts","sourceRoot":"","sources":["../../../src/lib/internal/default-loader.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,eAAO,MAAM,yBAAyB,mZAA6W,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * A single outstanding request: owns its `requestId`, races its response
3
+ * promise against a per-request timeout, and rejects with a descriptive
4
+ * error naming the request type and timeout when unanswered in time.
5
+ */
6
+ export declare class DeferredRequest<T = unknown> {
7
+ /** Unique id used to match this request to its response message. */
8
+ readonly requestId: string;
9
+ /** Exact response type expected for this request. */
10
+ readonly responseType: string;
11
+ /** Settles when the matching response arrives, or on timeout/destroy. */
12
+ readonly promise: Promise<T>;
13
+ private resolveFn;
14
+ private rejectFn;
15
+ private settled;
16
+ private readonly timeoutHandle;
17
+ constructor(requestType: string, timeoutMs: number);
18
+ /** Returns true only for this request's exact response type and id. */
19
+ matches(responseType: string, requestId: string): boolean;
20
+ /** Resolves the request with `value`. No-op if already settled. */
21
+ resolve(value: T): void;
22
+ /** Rejects the request with `reason`. No-op if already settled. */
23
+ reject(reason?: unknown): void;
24
+ }
25
+ //# sourceMappingURL=deferred-request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deferred-request.d.ts","sourceRoot":"","sources":["../../../src/lib/internal/deferred-request.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,qBAAa,eAAe,CAAC,CAAC,GAAG,OAAO;IACtC,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,qDAAqD;IACrD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAE7B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;gBAElD,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAgBlD,uEAAuE;IACvE,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAIzD,mEAAmE;IACnE,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IASvB,mEAAmE;IACnE,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;CAQ/B"}
@@ -0,0 +1,3 @@
1
+ /** Applies each entry of `styles` as an inline style property on `element`. */
2
+ export declare const setStyles: (element: HTMLElement, styles: Record<string, string>) => void;
3
+ //# sourceMappingURL=dom-styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-styles.d.ts","sourceRoot":"","sources":["../../../src/lib/internal/dom-styles.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,eAAO,MAAM,SAAS,GACpB,SAAS,WAAW,EACpB,QAAQ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC7B,IAEF,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * A promise paired with external `resolve`/`reject` control, used internally
3
+ * as a one-shot readiness gate. Settling twice is a no-op.
4
+ */
5
+ export declare class Task<T = void> {
6
+ /** Resolves/rejects exactly once, when the gate is settled. */
7
+ readonly promise: Promise<T>;
8
+ private resolveFn;
9
+ private rejectFn;
10
+ private settled;
11
+ constructor();
12
+ /** Resolves the gate with `value`. No-op if already settled. */
13
+ resolve(value: T): void;
14
+ /** Rejects the gate with `reason`. No-op if already settled. */
15
+ reject(reason?: unknown): void;
16
+ }
17
+ //# sourceMappingURL=task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../../src/lib/internal/task.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,IAAI,CAAC,CAAC,GAAG,IAAI;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAE7B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,OAAO,CAAS;;IASxB,gEAAgE;IAChE,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAQvB,gEAAgE;IAChE,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;CAO/B"}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@epam/ai-dial-chat-overlay",
3
+ "description": "Embeddable postMessage-based ChatOverlay/ChatOverlayManager widget for hosting a DIAL Chat instance inside a third-party page",
4
+ "version": "1.0.0-dev.550",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "./index.js",
8
+ "module": "./index.js",
9
+ "types": "./index.d.ts",
10
+ "exports": {
11
+ "./package.json": "./package.json",
12
+ ".": {
13
+ "types": "./index.d.ts",
14
+ "import": "./index.js",
15
+ "default": "./index.js"
16
+ }
17
+ },
18
+ "peerDependencies": {
19
+ "@epam/ai-dial-chat-shared": "1.0.0-dev.550"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/epam/ai-dial-chat.git",
24
+ "directory": "libs/chat-overlay"
25
+ }
26
+ }