@nexvio-ai/widget-js 0.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/CHANGELOG.md +83 -0
- package/README.md +365 -0
- package/dist/chunk-M2QGY5LN.js +1250 -0
- package/dist/chunk-M2QGY5LN.js.map +1 -0
- package/dist/index.cjs +1284 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +126 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/react.cjs +1550 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +29 -0
- package/dist/react.d.ts +29 -0
- package/dist/react.js +273 -0
- package/dist/react.js.map +1 -0
- package/dist/widget.js +1254 -0
- package/package.json +88 -0
|
@@ -0,0 +1,1250 @@
|
|
|
1
|
+
var __typeError = (msg) => {
|
|
2
|
+
throw TypeError(msg);
|
|
3
|
+
};
|
|
4
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
5
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
6
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
8
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
9
|
+
|
|
10
|
+
// src/utils/debug.ts
|
|
11
|
+
function debugEnabled() {
|
|
12
|
+
try {
|
|
13
|
+
return typeof window !== "undefined" && window.__NEXVIO_WIDGET_DEBUG === true;
|
|
14
|
+
} catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function log(...args) {
|
|
19
|
+
if (debugEnabled()) console.log(...args);
|
|
20
|
+
}
|
|
21
|
+
function warn(...args) {
|
|
22
|
+
if (debugEnabled()) console.warn(...args);
|
|
23
|
+
}
|
|
24
|
+
function debug(...args) {
|
|
25
|
+
if (debugEnabled()) console.debug(...args);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// src/utils/EventEmitter.ts
|
|
29
|
+
var _listeners;
|
|
30
|
+
var EventEmitter = class {
|
|
31
|
+
constructor() {
|
|
32
|
+
__privateAdd(this, _listeners, /* @__PURE__ */ new Map());
|
|
33
|
+
}
|
|
34
|
+
on(event, listener) {
|
|
35
|
+
if (!__privateGet(this, _listeners).has(event)) {
|
|
36
|
+
__privateGet(this, _listeners).set(event, /* @__PURE__ */ new Set());
|
|
37
|
+
}
|
|
38
|
+
__privateGet(this, _listeners).get(event)?.add(listener);
|
|
39
|
+
}
|
|
40
|
+
once(event, listener) {
|
|
41
|
+
const onceListener = (payload) => {
|
|
42
|
+
this.off(event, onceListener);
|
|
43
|
+
listener(payload);
|
|
44
|
+
};
|
|
45
|
+
this.on(event, onceListener);
|
|
46
|
+
}
|
|
47
|
+
emit(event, payload) {
|
|
48
|
+
__privateGet(this, _listeners).get(event)?.forEach((listener) => listener(payload));
|
|
49
|
+
}
|
|
50
|
+
off(event, listener) {
|
|
51
|
+
if (!listener) {
|
|
52
|
+
__privateGet(this, _listeners).delete(event);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
__privateGet(this, _listeners).get(event)?.delete(listener);
|
|
56
|
+
}
|
|
57
|
+
clear() {
|
|
58
|
+
__privateGet(this, _listeners).clear();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
_listeners = new WeakMap();
|
|
62
|
+
|
|
63
|
+
// src/utils/serializeError.ts
|
|
64
|
+
function serializeError(error) {
|
|
65
|
+
if (error instanceof Error) {
|
|
66
|
+
return {
|
|
67
|
+
name: error.name,
|
|
68
|
+
message: error.message,
|
|
69
|
+
stack: error.stack
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (typeof error === "object" && error !== null) {
|
|
73
|
+
const obj = error;
|
|
74
|
+
return {
|
|
75
|
+
name: typeof obj.name === "string" ? obj.name : "Error",
|
|
76
|
+
message: typeof obj.message === "string" ? obj.message : "Unknown error",
|
|
77
|
+
stack: typeof obj.stack === "string" ? obj.stack : void 0,
|
|
78
|
+
metadata: Object.fromEntries(Object.entries(obj).filter(([key]) => !["name", "message", "stack"].includes(key)))
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
name: "Error",
|
|
83
|
+
message: String(error)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function deserializeError(serialized) {
|
|
87
|
+
const error = new Error(serialized.message);
|
|
88
|
+
error.name = serialized.name;
|
|
89
|
+
if (serialized.stack) {
|
|
90
|
+
error.stack = serialized.stack;
|
|
91
|
+
}
|
|
92
|
+
return error;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// src/messenger/BaseMessenger.ts
|
|
96
|
+
var MESSAGE_TOKEN = "__nexvioWidget";
|
|
97
|
+
var DEFAULT_COMMAND_CAPABILITY = () => true;
|
|
98
|
+
var _target, _targetOrigin, _handlers, _fetch, _events, _canReceiveCommand, _pending, _abortControllers, _BaseMessenger_instances, sendMessage_fn, sendCommand_fn, _handleMessage, isWidgetMessage_fn;
|
|
99
|
+
var BaseMessenger = class {
|
|
100
|
+
constructor(config) {
|
|
101
|
+
__privateAdd(this, _BaseMessenger_instances);
|
|
102
|
+
__privateAdd(this, _target);
|
|
103
|
+
__privateAdd(this, _targetOrigin);
|
|
104
|
+
__privateAdd(this, _handlers);
|
|
105
|
+
__privateAdd(this, _fetch);
|
|
106
|
+
__privateAdd(this, _events, new EventEmitter());
|
|
107
|
+
__privateAdd(this, _canReceiveCommand);
|
|
108
|
+
__privateAdd(this, _pending, /* @__PURE__ */ new Map());
|
|
109
|
+
__privateAdd(this, _abortControllers, /* @__PURE__ */ new Map());
|
|
110
|
+
this.commands = new Proxy(
|
|
111
|
+
{},
|
|
112
|
+
{
|
|
113
|
+
get: (_, command) => {
|
|
114
|
+
return (payload, transfer) => {
|
|
115
|
+
return __privateMethod(this, _BaseMessenger_instances, sendCommand_fn).call(this, command, payload, transfer);
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
__privateAdd(this, _handleMessage, async (event) => {
|
|
121
|
+
debug("[NexvioWidget][Messenger] window.message", {
|
|
122
|
+
origin: event.origin,
|
|
123
|
+
hasToken: !!(event.data && typeof event.data === "object" && event.data[MESSAGE_TOKEN] === true)
|
|
124
|
+
});
|
|
125
|
+
if (!__privateMethod(this, _BaseMessenger_instances, isWidgetMessage_fn).call(this, event)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const data = event.data;
|
|
129
|
+
switch (data.type) {
|
|
130
|
+
case "event": {
|
|
131
|
+
log("[NexvioWidget][Messenger] <- event", { event: data.event, payload: data.payload });
|
|
132
|
+
__privateGet(this, _events).emit(data.event, data.payload);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case "response": {
|
|
136
|
+
const handler = __privateGet(this, _pending).get(data.nonce);
|
|
137
|
+
if (!handler) {
|
|
138
|
+
warn("[NexvioWidget][Messenger] missing pending handler for response", data.nonce);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
__privateGet(this, _pending).delete(data.nonce);
|
|
142
|
+
if (data.error) {
|
|
143
|
+
handler.reject(deserializeError(data.error));
|
|
144
|
+
} else {
|
|
145
|
+
handler.resolve(data.payload);
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
case "command": {
|
|
150
|
+
if (!__privateGet(this, _canReceiveCommand).call(this, data.command)) {
|
|
151
|
+
__privateMethod(this, _BaseMessenger_instances, sendMessage_fn).call(this, {
|
|
152
|
+
type: "response",
|
|
153
|
+
nonce: data.nonce,
|
|
154
|
+
error: serializeError(new Error(`Command "${data.command}" is not supported by the host`))
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const commandCapitalized = `on${data.command.charAt(0).toUpperCase()}${data.command.slice(1)}`;
|
|
159
|
+
const handler = __privateGet(this, _handlers)[commandCapitalized];
|
|
160
|
+
if (!handler) {
|
|
161
|
+
__privateMethod(this, _BaseMessenger_instances, sendMessage_fn).call(this, {
|
|
162
|
+
type: "response",
|
|
163
|
+
nonce: data.nonce,
|
|
164
|
+
error: serializeError(new Error(`Command handler "${data.command}" not implemented by host`))
|
|
165
|
+
});
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
log("[NexvioWidget][Messenger] <- command", { command: data.command, payload: data.payload });
|
|
170
|
+
const result = await handler(data.payload);
|
|
171
|
+
__privateMethod(this, _BaseMessenger_instances, sendMessage_fn).call(this, { type: "response", nonce: data.nonce, payload: result });
|
|
172
|
+
} catch (error) {
|
|
173
|
+
__privateMethod(this, _BaseMessenger_instances, sendMessage_fn).call(this, {
|
|
174
|
+
type: "response",
|
|
175
|
+
nonce: data.nonce,
|
|
176
|
+
error: serializeError(error)
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
case "fetch": {
|
|
182
|
+
log("[NexvioWidget][Messenger] <- fetch", { url: data.url });
|
|
183
|
+
const controller = new AbortController();
|
|
184
|
+
__privateGet(this, _abortControllers).set(data.nonce, controller);
|
|
185
|
+
try {
|
|
186
|
+
const response = await __privateGet(this, _fetch).call(this, data.url, {
|
|
187
|
+
...data.init,
|
|
188
|
+
signal: controller.signal
|
|
189
|
+
});
|
|
190
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
191
|
+
let payload;
|
|
192
|
+
if (contentType.includes("application/json")) {
|
|
193
|
+
payload = await response.json();
|
|
194
|
+
} else {
|
|
195
|
+
payload = await response.text();
|
|
196
|
+
}
|
|
197
|
+
__privateMethod(this, _BaseMessenger_instances, sendMessage_fn).call(this, {
|
|
198
|
+
type: "response",
|
|
199
|
+
nonce: data.nonce,
|
|
200
|
+
payload: {
|
|
201
|
+
ok: response.ok,
|
|
202
|
+
status: response.status,
|
|
203
|
+
statusText: response.statusText,
|
|
204
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
205
|
+
body: payload
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
} catch (error) {
|
|
209
|
+
__privateMethod(this, _BaseMessenger_instances, sendMessage_fn).call(this, {
|
|
210
|
+
type: "response",
|
|
211
|
+
nonce: data.nonce,
|
|
212
|
+
error: serializeError(error)
|
|
213
|
+
});
|
|
214
|
+
} finally {
|
|
215
|
+
__privateGet(this, _abortControllers).delete(data.nonce);
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
case "abort": {
|
|
220
|
+
const controller = __privateGet(this, _abortControllers).get(data.nonce);
|
|
221
|
+
controller?.abort(data.reason);
|
|
222
|
+
__privateGet(this, _abortControllers).delete(data.nonce);
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
default:
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
__privateSet(this, _target, config.target);
|
|
230
|
+
__privateSet(this, _targetOrigin, config.targetOrigin);
|
|
231
|
+
__privateSet(this, _handlers, config.handlers);
|
|
232
|
+
__privateSet(this, _fetch, config.fetch ?? fetch.bind(globalThis));
|
|
233
|
+
__privateSet(this, _canReceiveCommand, config.canReceiveCommand ?? DEFAULT_COMMAND_CAPABILITY);
|
|
234
|
+
}
|
|
235
|
+
connect() {
|
|
236
|
+
log("[NexvioWidget][Messenger] connect", { targetOrigin: __privateGet(this, _targetOrigin) });
|
|
237
|
+
window.addEventListener("message", __privateGet(this, _handleMessage));
|
|
238
|
+
}
|
|
239
|
+
disconnect() {
|
|
240
|
+
log("[NexvioWidget][Messenger] disconnect");
|
|
241
|
+
window.removeEventListener("message", __privateGet(this, _handleMessage));
|
|
242
|
+
__privateGet(this, _events).clear();
|
|
243
|
+
__privateGet(this, _pending).clear();
|
|
244
|
+
__privateGet(this, _abortControllers).forEach((controller) => controller.abort());
|
|
245
|
+
__privateGet(this, _abortControllers).clear();
|
|
246
|
+
}
|
|
247
|
+
on(event, listener) {
|
|
248
|
+
__privateGet(this, _events).on(event, listener);
|
|
249
|
+
}
|
|
250
|
+
off(event, listener) {
|
|
251
|
+
__privateGet(this, _events).off(event, listener);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
_target = new WeakMap();
|
|
255
|
+
_targetOrigin = new WeakMap();
|
|
256
|
+
_handlers = new WeakMap();
|
|
257
|
+
_fetch = new WeakMap();
|
|
258
|
+
_events = new WeakMap();
|
|
259
|
+
_canReceiveCommand = new WeakMap();
|
|
260
|
+
_pending = new WeakMap();
|
|
261
|
+
_abortControllers = new WeakMap();
|
|
262
|
+
_BaseMessenger_instances = new WeakSet();
|
|
263
|
+
sendMessage_fn = function(message, transfer) {
|
|
264
|
+
const target = __privateGet(this, _target).call(this);
|
|
265
|
+
if (!target) {
|
|
266
|
+
throw new Error("Widget frame not ready");
|
|
267
|
+
}
|
|
268
|
+
const payload = { ...message, [MESSAGE_TOKEN]: true };
|
|
269
|
+
try {
|
|
270
|
+
debug("[NexvioWidget][Messenger] postMessage", {
|
|
271
|
+
type: message.type,
|
|
272
|
+
command: message.command,
|
|
273
|
+
targetOrigin: __privateGet(this, _targetOrigin)
|
|
274
|
+
});
|
|
275
|
+
target.postMessage(payload, __privateGet(this, _targetOrigin), transfer);
|
|
276
|
+
} catch (error) {
|
|
277
|
+
const shouldRetryWithAnyOrigin = __privateGet(this, _targetOrigin) !== "*" && error instanceof DOMException && (error.name === "SecurityError" || /target origin provided/i.test(error.message));
|
|
278
|
+
if (shouldRetryWithAnyOrigin) {
|
|
279
|
+
warn('[NexvioWidget][Messenger] SecurityError posting to targetOrigin. Retrying with "*"');
|
|
280
|
+
target.postMessage(payload, "*", transfer);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
throw error;
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
sendCommand_fn = async function(command, payload, transfer) {
|
|
287
|
+
const nonce = crypto.randomUUID();
|
|
288
|
+
return new Promise((resolve, reject) => {
|
|
289
|
+
__privateGet(this, _pending).set(nonce, { resolve, reject, stack: new Error().stack ?? "" });
|
|
290
|
+
try {
|
|
291
|
+
__privateMethod(this, _BaseMessenger_instances, sendMessage_fn).call(this, { type: "command", command, payload, nonce }, transfer);
|
|
292
|
+
} catch (error) {
|
|
293
|
+
__privateGet(this, _pending).delete(nonce);
|
|
294
|
+
reject(error);
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
};
|
|
298
|
+
_handleMessage = new WeakMap();
|
|
299
|
+
isWidgetMessage_fn = function(event) {
|
|
300
|
+
if (!event.data || typeof event.data !== "object" || event.data[MESSAGE_TOKEN] !== true) {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
const targetWin = __privateGet(this, _target).call(this);
|
|
304
|
+
if (targetWin && event.source && event.source !== targetWin) {
|
|
305
|
+
debug("[NexvioWidget][Messenger] drop message: source mismatch");
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
if (event.origin !== __privateGet(this, _targetOrigin)) {
|
|
309
|
+
if (targetWin && event.source === targetWin) {
|
|
310
|
+
warn("[NexvioWidget][Messenger] learning targetOrigin from first message", {
|
|
311
|
+
from: __privateGet(this, _targetOrigin),
|
|
312
|
+
to: event.origin
|
|
313
|
+
});
|
|
314
|
+
__privateSet(this, _targetOrigin, event.origin);
|
|
315
|
+
} else {
|
|
316
|
+
debug("[NexvioWidget][Messenger] drop message: origin mismatch", {
|
|
317
|
+
expected: __privateGet(this, _targetOrigin),
|
|
318
|
+
got: event.origin
|
|
319
|
+
});
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return true;
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
// src/messenger/WidgetFrameMessenger.ts
|
|
327
|
+
var WidgetFrameMessenger = class extends BaseMessenger {
|
|
328
|
+
constructor(config) {
|
|
329
|
+
super({
|
|
330
|
+
target: config.target,
|
|
331
|
+
targetOrigin: config.targetOrigin,
|
|
332
|
+
handlers: config.handlers,
|
|
333
|
+
fetch: config.fetch,
|
|
334
|
+
canReceiveCommand: () => true
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
// src/utils/base64.ts
|
|
340
|
+
function toBase64(input) {
|
|
341
|
+
if (typeof globalThis.btoa === "function") {
|
|
342
|
+
return globalThis.btoa(input);
|
|
343
|
+
}
|
|
344
|
+
const buffer = globalThis.Buffer;
|
|
345
|
+
if (buffer) {
|
|
346
|
+
return buffer.from(input, "binary").toString("base64");
|
|
347
|
+
}
|
|
348
|
+
throw new Error("No base64 encoder available in this environment");
|
|
349
|
+
}
|
|
350
|
+
function encodeBase64(value) {
|
|
351
|
+
if (value === void 0) {
|
|
352
|
+
throw new TypeError("encodeBase64: `undefined` cannot be serialized. Pass null instead.");
|
|
353
|
+
}
|
|
354
|
+
const json = JSON.stringify(value);
|
|
355
|
+
const bytes = new TextEncoder().encode(json);
|
|
356
|
+
let binary = "";
|
|
357
|
+
for (const byte of bytes) {
|
|
358
|
+
binary += String.fromCharCode(byte);
|
|
359
|
+
}
|
|
360
|
+
return toBase64(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// src/utils/stripFunctions.ts
|
|
364
|
+
function stripFunctions(input, cloneMap = /* @__PURE__ */ new WeakMap()) {
|
|
365
|
+
if (typeof input !== "object" || input === null) {
|
|
366
|
+
return input;
|
|
367
|
+
}
|
|
368
|
+
if (cloneMap.has(input)) {
|
|
369
|
+
return cloneMap.get(input);
|
|
370
|
+
}
|
|
371
|
+
if (Array.isArray(input)) {
|
|
372
|
+
const arrClone = [];
|
|
373
|
+
cloneMap.set(input, arrClone);
|
|
374
|
+
for (const item of input) {
|
|
375
|
+
arrClone.push(stripFunctions(item, cloneMap));
|
|
376
|
+
}
|
|
377
|
+
return arrClone;
|
|
378
|
+
}
|
|
379
|
+
const clone = {};
|
|
380
|
+
cloneMap.set(input, clone);
|
|
381
|
+
for (const [key, value] of Object.entries(input)) {
|
|
382
|
+
if (typeof value === "function") {
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
clone[key] = stripFunctions(value, cloneMap);
|
|
386
|
+
}
|
|
387
|
+
return clone;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// src/utils/zod-to-json-schema.ts
|
|
391
|
+
function zodToJsonSchema(schema) {
|
|
392
|
+
if (!schema || !schema._def) {
|
|
393
|
+
return { type: "object", properties: {}, additionalProperties: false };
|
|
394
|
+
}
|
|
395
|
+
const def = schema._def;
|
|
396
|
+
const typeName = def.typeName;
|
|
397
|
+
if (typeName === "ZodObject") {
|
|
398
|
+
const shape = def.shape();
|
|
399
|
+
const properties = {};
|
|
400
|
+
const required = [];
|
|
401
|
+
for (const key in shape) {
|
|
402
|
+
const fieldSchema = shape[key];
|
|
403
|
+
properties[key] = zodToJsonSchema(fieldSchema);
|
|
404
|
+
if (fieldSchema._def.typeName !== "ZodOptional") {
|
|
405
|
+
required.push(key);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
type: "object",
|
|
410
|
+
properties,
|
|
411
|
+
required: required.length > 0 ? required : void 0,
|
|
412
|
+
additionalProperties: false
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
if (typeName === "ZodString") {
|
|
416
|
+
const result = { type: "string" };
|
|
417
|
+
if (def.description) {
|
|
418
|
+
result.description = def.description;
|
|
419
|
+
}
|
|
420
|
+
return result;
|
|
421
|
+
}
|
|
422
|
+
if (typeName === "ZodNumber") {
|
|
423
|
+
const result = { type: "number" };
|
|
424
|
+
if (def.description) {
|
|
425
|
+
result.description = def.description;
|
|
426
|
+
}
|
|
427
|
+
return result;
|
|
428
|
+
}
|
|
429
|
+
if (typeName === "ZodBoolean") {
|
|
430
|
+
const result = { type: "boolean" };
|
|
431
|
+
if (def.description) {
|
|
432
|
+
result.description = def.description;
|
|
433
|
+
}
|
|
434
|
+
return result;
|
|
435
|
+
}
|
|
436
|
+
if (typeName === "ZodArray") {
|
|
437
|
+
const result = {
|
|
438
|
+
type: "array",
|
|
439
|
+
items: zodToJsonSchema(def.type)
|
|
440
|
+
};
|
|
441
|
+
if (def.description) {
|
|
442
|
+
result.description = def.description;
|
|
443
|
+
}
|
|
444
|
+
return result;
|
|
445
|
+
}
|
|
446
|
+
if (typeName === "ZodEnum") {
|
|
447
|
+
const result = {
|
|
448
|
+
type: "string",
|
|
449
|
+
enum: def.values
|
|
450
|
+
};
|
|
451
|
+
if (def.description) {
|
|
452
|
+
result.description = def.description;
|
|
453
|
+
}
|
|
454
|
+
return result;
|
|
455
|
+
}
|
|
456
|
+
if (typeName === "ZodOptional") {
|
|
457
|
+
return zodToJsonSchema(def.innerType);
|
|
458
|
+
}
|
|
459
|
+
if (typeName === "ZodNullable") {
|
|
460
|
+
const innerSchema = zodToJsonSchema(def.innerType);
|
|
461
|
+
return {
|
|
462
|
+
...innerSchema,
|
|
463
|
+
nullable: true
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
if (typeName === "ZodLiteral") {
|
|
467
|
+
return {
|
|
468
|
+
type: typeof def.value,
|
|
469
|
+
enum: [def.value]
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
if (typeName === "ZodUnion") {
|
|
473
|
+
const options = def.options;
|
|
474
|
+
if (options && options.length > 0) {
|
|
475
|
+
return {
|
|
476
|
+
anyOf: options.map((opt) => zodToJsonSchema(opt))
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return { type: "object", additionalProperties: true };
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// src/NexvioWidgetElement.ts
|
|
484
|
+
var DEFAULT_WIDGET_URL = "https://chatwidget.app";
|
|
485
|
+
var WIDGET_VERSION = "0.1.0";
|
|
486
|
+
var styleContent = `
|
|
487
|
+
:host {
|
|
488
|
+
display: block;
|
|
489
|
+
position: relative;
|
|
490
|
+
width: 100%;
|
|
491
|
+
height: 100%;
|
|
492
|
+
}
|
|
493
|
+
.nx-wrapper {
|
|
494
|
+
position: absolute;
|
|
495
|
+
inset: 0;
|
|
496
|
+
width: 100%;
|
|
497
|
+
height: 100%;
|
|
498
|
+
opacity: 0;
|
|
499
|
+
transition: opacity 160ms ease-in-out;
|
|
500
|
+
}
|
|
501
|
+
:host([data-loaded='true']) .nx-wrapper {
|
|
502
|
+
opacity: 1;
|
|
503
|
+
}
|
|
504
|
+
.nx-frame {
|
|
505
|
+
border: none;
|
|
506
|
+
width: 100%;
|
|
507
|
+
height: 100%;
|
|
508
|
+
position: absolute;
|
|
509
|
+
inset: 0;
|
|
510
|
+
background: transparent;
|
|
511
|
+
}
|
|
512
|
+
`;
|
|
513
|
+
var BaseHTMLElement = typeof HTMLElement === "undefined" ? class {
|
|
514
|
+
} : HTMLElement;
|
|
515
|
+
var _shadowRootRef, _frame, _wrapper, _options, _sanitized, _messenger, _loadedResolve, _loaded, _targetOrigin2, _initialized, _frameReady, _pendingOptions, _NexvioWidgetElement_instances, sanitizeOptions_fn, ensureStructure_fn, initializeFrame_fn, _handleFrameLoad, ensureMessenger_fn, buildFrameUrl_fn, updateDataAttributes_fn, handleFrameEvent_fn, handleClientAction_fn, handleExecuteClientTool_fn, dispatchReady_fn, dispatchError_fn, dispatchEvent_fn, handleResize_fn, flushOptionsIfReady_fn;
|
|
516
|
+
var NexvioWidgetElement = class extends BaseHTMLElement {
|
|
517
|
+
constructor() {
|
|
518
|
+
super();
|
|
519
|
+
__privateAdd(this, _NexvioWidgetElement_instances);
|
|
520
|
+
__privateAdd(this, _shadowRootRef, null);
|
|
521
|
+
__privateAdd(this, _frame);
|
|
522
|
+
__privateAdd(this, _wrapper);
|
|
523
|
+
__privateAdd(this, _options);
|
|
524
|
+
__privateAdd(this, _sanitized);
|
|
525
|
+
__privateAdd(this, _messenger);
|
|
526
|
+
__privateAdd(this, _loadedResolve);
|
|
527
|
+
__privateAdd(this, _loaded);
|
|
528
|
+
__privateAdd(this, _targetOrigin2);
|
|
529
|
+
__privateAdd(this, _initialized, false);
|
|
530
|
+
__privateAdd(this, _frameReady, false);
|
|
531
|
+
__privateAdd(this, _pendingOptions);
|
|
532
|
+
__privateAdd(this, _handleFrameLoad, () => {
|
|
533
|
+
var _a;
|
|
534
|
+
debug("[NexvioWidget] frame load event");
|
|
535
|
+
this.dataset.loaded = "true";
|
|
536
|
+
(_a = __privateGet(this, _loadedResolve)) == null ? void 0 : _a.call(this);
|
|
537
|
+
__privateMethod(this, _NexvioWidgetElement_instances, flushOptionsIfReady_fn).call(this);
|
|
538
|
+
});
|
|
539
|
+
if (typeof window !== "undefined" && typeof this.attachShadow === "function") {
|
|
540
|
+
__privateSet(this, _shadowRootRef, this.attachShadow({ mode: "open" }));
|
|
541
|
+
}
|
|
542
|
+
log("[NexvioWidget] element: constructed");
|
|
543
|
+
__privateSet(this, _loaded, new Promise((resolve) => {
|
|
544
|
+
__privateSet(this, _loadedResolve, resolve);
|
|
545
|
+
}));
|
|
546
|
+
}
|
|
547
|
+
connectedCallback() {
|
|
548
|
+
log("[NexvioWidget] element: connectedCallback");
|
|
549
|
+
__privateMethod(this, _NexvioWidgetElement_instances, ensureStructure_fn).call(this);
|
|
550
|
+
if (__privateGet(this, _sanitized) && !__privateGet(this, _initialized)) {
|
|
551
|
+
__privateMethod(this, _NexvioWidgetElement_instances, initializeFrame_fn).call(this);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
disconnectedCallback() {
|
|
555
|
+
log("[NexvioWidget] element: disconnectedCallback");
|
|
556
|
+
__privateGet(this, _messenger)?.disconnect();
|
|
557
|
+
}
|
|
558
|
+
setOptions(options) {
|
|
559
|
+
log("[NexvioWidget] setOptions: received", options);
|
|
560
|
+
const sanitized = __privateMethod(this, _NexvioWidgetElement_instances, sanitizeOptions_fn).call(this, options);
|
|
561
|
+
const previous = __privateGet(this, _sanitized);
|
|
562
|
+
const baseUrl = sanitized.host?.baseUrl ?? DEFAULT_WIDGET_URL;
|
|
563
|
+
debug("[NexvioWidget] setOptions: sanitized", sanitized);
|
|
564
|
+
__privateMethod(this, _NexvioWidgetElement_instances, ensureMessenger_fn).call(this, new URL(baseUrl).origin, options.fetch);
|
|
565
|
+
__privateSet(this, _options, options);
|
|
566
|
+
__privateSet(this, _sanitized, sanitized);
|
|
567
|
+
__privateSet(this, _pendingOptions, sanitized);
|
|
568
|
+
const requiresReload = !__privateGet(this, _initialized) || !previous || previous.publicKey !== sanitized.publicKey || (previous.host?.baseUrl ?? DEFAULT_WIDGET_URL) !== (sanitized.host?.baseUrl ?? DEFAULT_WIDGET_URL) || // Reload if clientTools changed (added, removed, or modified)
|
|
569
|
+
JSON.stringify(previous.clientTools) !== JSON.stringify(sanitized.clientTools);
|
|
570
|
+
debug("[NexvioWidget] setOptions: requiresReload", {
|
|
571
|
+
requiresReload,
|
|
572
|
+
reasons: {
|
|
573
|
+
notInitialized: !__privateGet(this, _initialized),
|
|
574
|
+
noPrevious: !previous,
|
|
575
|
+
publicKeyChanged: previous && previous.publicKey !== sanitized.publicKey,
|
|
576
|
+
baseUrlChanged: previous && (previous.host?.baseUrl ?? DEFAULT_WIDGET_URL) !== (sanitized.host?.baseUrl ?? DEFAULT_WIDGET_URL),
|
|
577
|
+
clientToolsChanged: previous && JSON.stringify(previous.clientTools) !== JSON.stringify(sanitized.clientTools)
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
__privateMethod(this, _NexvioWidgetElement_instances, updateDataAttributes_fn).call(this, sanitized);
|
|
581
|
+
if (requiresReload) {
|
|
582
|
+
__privateMethod(this, _NexvioWidgetElement_instances, initializeFrame_fn).call(this, true);
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
__privateMethod(this, _NexvioWidgetElement_instances, flushOptionsIfReady_fn).call(this);
|
|
586
|
+
}
|
|
587
|
+
async focusInput() {
|
|
588
|
+
await __privateGet(this, _loaded);
|
|
589
|
+
await __privateGet(this, _messenger)?.commands.focusInput();
|
|
590
|
+
}
|
|
591
|
+
async refresh() {
|
|
592
|
+
await __privateGet(this, _loaded);
|
|
593
|
+
await __privateGet(this, _messenger)?.commands.refresh();
|
|
594
|
+
}
|
|
595
|
+
async setVisitor(visitor) {
|
|
596
|
+
await __privateGet(this, _loaded);
|
|
597
|
+
await __privateGet(this, _messenger)?.commands.updateVisitor(visitor);
|
|
598
|
+
}
|
|
599
|
+
async reload() {
|
|
600
|
+
if (!__privateGet(this, _sanitized)) return;
|
|
601
|
+
__privateSet(this, _initialized, false);
|
|
602
|
+
__privateMethod(this, _NexvioWidgetElement_instances, initializeFrame_fn).call(this, true);
|
|
603
|
+
}
|
|
604
|
+
get options() {
|
|
605
|
+
return __privateGet(this, _options);
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
_shadowRootRef = new WeakMap();
|
|
609
|
+
_frame = new WeakMap();
|
|
610
|
+
_wrapper = new WeakMap();
|
|
611
|
+
_options = new WeakMap();
|
|
612
|
+
_sanitized = new WeakMap();
|
|
613
|
+
_messenger = new WeakMap();
|
|
614
|
+
_loadedResolve = new WeakMap();
|
|
615
|
+
_loaded = new WeakMap();
|
|
616
|
+
_targetOrigin2 = new WeakMap();
|
|
617
|
+
_initialized = new WeakMap();
|
|
618
|
+
_frameReady = new WeakMap();
|
|
619
|
+
_pendingOptions = new WeakMap();
|
|
620
|
+
_NexvioWidgetElement_instances = new WeakSet();
|
|
621
|
+
sanitizeOptions_fn = function(options) {
|
|
622
|
+
if (!options || typeof options.publicKey !== "string" || options.publicKey.trim().length === 0) {
|
|
623
|
+
throw new Error("Nexvio widget requires a non-empty `publicKey`.");
|
|
624
|
+
}
|
|
625
|
+
const hostBase = options.host?.baseUrl ?? DEFAULT_WIDGET_URL;
|
|
626
|
+
let validatedHost;
|
|
627
|
+
try {
|
|
628
|
+
validatedHost = new URL(hostBase);
|
|
629
|
+
} catch (error) {
|
|
630
|
+
throw new Error(`Invalid host baseUrl provided to Nexvio widget: ${error}`);
|
|
631
|
+
}
|
|
632
|
+
const sanitized = stripFunctions({
|
|
633
|
+
publicKey: options.publicKey.trim(),
|
|
634
|
+
appearance: options.appearance,
|
|
635
|
+
messageActions: options.messageActions,
|
|
636
|
+
metadata: options.metadata,
|
|
637
|
+
context: options.context,
|
|
638
|
+
startScreen: options.startScreen,
|
|
639
|
+
host: {
|
|
640
|
+
baseUrl: validatedHost.toString().replace(/\/$/, ""),
|
|
641
|
+
query: options.host?.query
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
if (options.client?.tools && Array.isArray(options.client.tools)) {
|
|
645
|
+
log("[NexvioWidget] sanitizeOptions: converting client tools", options.client.tools);
|
|
646
|
+
sanitized.clientTools = options.client.tools.map((tool) => ({
|
|
647
|
+
name: tool.name,
|
|
648
|
+
description: tool.description,
|
|
649
|
+
parameters: zodToJsonSchema(tool.parameters)
|
|
650
|
+
}));
|
|
651
|
+
log("[NexvioWidget] sanitizeOptions: sanitized clientTools", sanitized.clientTools);
|
|
652
|
+
} else {
|
|
653
|
+
log("[NexvioWidget] sanitizeOptions: no client tools found", {
|
|
654
|
+
hasClient: !!options.client,
|
|
655
|
+
hasTools: !!options.client?.tools
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
return sanitized;
|
|
659
|
+
};
|
|
660
|
+
ensureStructure_fn = function() {
|
|
661
|
+
if (__privateGet(this, _wrapper)) return;
|
|
662
|
+
if (!__privateGet(this, _shadowRootRef)) return;
|
|
663
|
+
const style = document.createElement("style");
|
|
664
|
+
style.textContent = styleContent;
|
|
665
|
+
const wrapper = document.createElement("div");
|
|
666
|
+
wrapper.className = "nx-wrapper";
|
|
667
|
+
const frame = document.createElement("iframe");
|
|
668
|
+
frame.className = "nx-frame";
|
|
669
|
+
frame.setAttribute("allow", "clipboard-read; clipboard-write");
|
|
670
|
+
frame.setAttribute("referrerpolicy", "strict-origin-when-cross-origin");
|
|
671
|
+
frame.name = "nexvio-widget";
|
|
672
|
+
frame.tabIndex = -1;
|
|
673
|
+
wrapper.appendChild(frame);
|
|
674
|
+
__privateGet(this, _shadowRootRef).append(style, wrapper);
|
|
675
|
+
__privateSet(this, _frame, frame);
|
|
676
|
+
__privateSet(this, _wrapper, wrapper);
|
|
677
|
+
};
|
|
678
|
+
initializeFrame_fn = function(forceReload = false) {
|
|
679
|
+
if (!__privateGet(this, _frame) || !__privateGet(this, _sanitized)) return;
|
|
680
|
+
if (__privateGet(this, _initialized) && !forceReload) return;
|
|
681
|
+
__privateSet(this, _initialized, true);
|
|
682
|
+
__privateSet(this, _frameReady, false);
|
|
683
|
+
this.dataset.loaded = "false";
|
|
684
|
+
__privateSet(this, _loaded, new Promise((resolve) => {
|
|
685
|
+
__privateSet(this, _loadedResolve, resolve);
|
|
686
|
+
}));
|
|
687
|
+
const frameUrl = __privateMethod(this, _NexvioWidgetElement_instances, buildFrameUrl_fn).call(this, __privateGet(this, _sanitized));
|
|
688
|
+
debug("[NexvioWidget] initializeFrame", { forceReload, frameUrl: frameUrl.toString() });
|
|
689
|
+
__privateGet(this, _frame).addEventListener("load", __privateGet(this, _handleFrameLoad), { once: true });
|
|
690
|
+
__privateGet(this, _frame).src = frameUrl.toString();
|
|
691
|
+
__privateMethod(this, _NexvioWidgetElement_instances, updateDataAttributes_fn).call(this, __privateGet(this, _sanitized));
|
|
692
|
+
};
|
|
693
|
+
_handleFrameLoad = new WeakMap();
|
|
694
|
+
ensureMessenger_fn = function(origin, customFetch) {
|
|
695
|
+
if (__privateGet(this, _messenger) && __privateGet(this, _targetOrigin2) === origin) {
|
|
696
|
+
debug("[NexvioWidget] messenger: reuse", { origin });
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
__privateGet(this, _messenger)?.disconnect();
|
|
700
|
+
__privateSet(this, _targetOrigin2, origin);
|
|
701
|
+
log("[NexvioWidget] messenger: create", { origin });
|
|
702
|
+
__privateSet(this, _messenger, new WidgetFrameMessenger({
|
|
703
|
+
target: () => __privateGet(this, _frame)?.contentWindow ?? null,
|
|
704
|
+
targetOrigin: origin,
|
|
705
|
+
fetch: customFetch,
|
|
706
|
+
handlers: {
|
|
707
|
+
onEmitEvent: (payload) => __privateMethod(this, _NexvioWidgetElement_instances, handleFrameEvent_fn).call(this, payload),
|
|
708
|
+
onRequestClientAction: (payload) => __privateMethod(this, _NexvioWidgetElement_instances, handleClientAction_fn).call(this, payload),
|
|
709
|
+
onExecuteClientTool: (payload) => __privateMethod(this, _NexvioWidgetElement_instances, handleExecuteClientTool_fn).call(this, payload)
|
|
710
|
+
}
|
|
711
|
+
}));
|
|
712
|
+
__privateGet(this, _messenger).connect();
|
|
713
|
+
__privateGet(this, _messenger).on("widget.ready", (payload) => __privateMethod(this, _NexvioWidgetElement_instances, dispatchReady_fn).call(this, payload));
|
|
714
|
+
__privateGet(this, _messenger).on("widget.error", (payload) => __privateMethod(this, _NexvioWidgetElement_instances, dispatchError_fn).call(this, payload));
|
|
715
|
+
__privateGet(this, _messenger).on("widget.event", (payload) => __privateMethod(this, _NexvioWidgetElement_instances, dispatchEvent_fn).call(this, payload));
|
|
716
|
+
__privateGet(this, _messenger).on("widget.resize", (payload) => __privateMethod(this, _NexvioWidgetElement_instances, handleResize_fn).call(this, payload));
|
|
717
|
+
};
|
|
718
|
+
buildFrameUrl_fn = function(options) {
|
|
719
|
+
const base = options.host?.baseUrl ?? DEFAULT_WIDGET_URL;
|
|
720
|
+
const trimmedBase = base.endsWith("/") ? base.slice(0, -1) : base;
|
|
721
|
+
const url = new URL(`${trimmedBase}/${encodeURIComponent(options.publicKey)}`);
|
|
722
|
+
url.searchParams.set("embed", "1");
|
|
723
|
+
const query = options.host?.query ?? {};
|
|
724
|
+
for (const [key, value] of Object.entries(query)) {
|
|
725
|
+
if (value === void 0) continue;
|
|
726
|
+
url.searchParams.set(key, String(value));
|
|
727
|
+
}
|
|
728
|
+
const payload = stripFunctions({
|
|
729
|
+
appearance: options.appearance,
|
|
730
|
+
metadata: options.metadata,
|
|
731
|
+
context: options.context,
|
|
732
|
+
startScreen: options.startScreen,
|
|
733
|
+
version: WIDGET_VERSION,
|
|
734
|
+
clientTools: options.clientTools
|
|
735
|
+
});
|
|
736
|
+
log("[NexvioWidget] buildFrameUrl: payload with clientTools", payload);
|
|
737
|
+
if (Object.values(payload).some((value) => value !== void 0)) {
|
|
738
|
+
url.hash = encodeBase64(payload);
|
|
739
|
+
}
|
|
740
|
+
debug("[NexvioWidget] buildFrameUrl", { url: url.toString() });
|
|
741
|
+
return url;
|
|
742
|
+
};
|
|
743
|
+
updateDataAttributes_fn = function(options) {
|
|
744
|
+
const colorScheme = typeof options.appearance?.colorScheme === "string" ? options.appearance.colorScheme : void 0;
|
|
745
|
+
if (colorScheme) {
|
|
746
|
+
this.dataset.colorScheme = colorScheme;
|
|
747
|
+
} else {
|
|
748
|
+
delete this.dataset.colorScheme;
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
handleFrameEvent_fn = function({ name, detail }) {
|
|
752
|
+
log("[NexvioWidget] event", { name, detail });
|
|
753
|
+
const event = { name, detail };
|
|
754
|
+
__privateGet(this, _options)?.onEvent?.(event);
|
|
755
|
+
this.dispatchEvent(
|
|
756
|
+
new CustomEvent("nexvio.event", {
|
|
757
|
+
detail: event,
|
|
758
|
+
bubbles: true,
|
|
759
|
+
composed: true
|
|
760
|
+
})
|
|
761
|
+
);
|
|
762
|
+
this.dispatchEvent(
|
|
763
|
+
new CustomEvent(`nexvio.${name}`, {
|
|
764
|
+
detail,
|
|
765
|
+
bubbles: true,
|
|
766
|
+
composed: true
|
|
767
|
+
})
|
|
768
|
+
);
|
|
769
|
+
};
|
|
770
|
+
handleClientAction_fn = async function({
|
|
771
|
+
action,
|
|
772
|
+
data
|
|
773
|
+
}) {
|
|
774
|
+
const handler = __privateGet(this, _options)?.clientActions?.[action];
|
|
775
|
+
if (!handler) {
|
|
776
|
+
throw new Error(`No client action handler registered for "${action}"`);
|
|
777
|
+
}
|
|
778
|
+
return handler(data);
|
|
779
|
+
};
|
|
780
|
+
handleExecuteClientTool_fn = async function({
|
|
781
|
+
toolName,
|
|
782
|
+
toolArgs
|
|
783
|
+
}) {
|
|
784
|
+
log("[NexvioWidget] executeClientTool", { toolName, toolArgs });
|
|
785
|
+
const tool = __privateGet(this, _options)?.client?.tools?.find((t) => t.name === toolName);
|
|
786
|
+
if (!tool) {
|
|
787
|
+
throw new Error(`No client tool registered with name "${toolName}"`);
|
|
788
|
+
}
|
|
789
|
+
try {
|
|
790
|
+
const validated = tool.parameters.parse(toolArgs);
|
|
791
|
+
const result = await Promise.resolve(tool.execute(validated));
|
|
792
|
+
log("[NexvioWidget] executeClientTool: success", { toolName, result });
|
|
793
|
+
return result;
|
|
794
|
+
} catch (error) {
|
|
795
|
+
console.error("[NexvioWidget] executeClientTool: error", { toolName, error });
|
|
796
|
+
throw new Error(`Tool execution failed for "${toolName}": ${error.message}`);
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
dispatchReady_fn = function(payload) {
|
|
800
|
+
log("[NexvioWidget] ready", payload);
|
|
801
|
+
__privateSet(this, _frameReady, true);
|
|
802
|
+
__privateMethod(this, _NexvioWidgetElement_instances, flushOptionsIfReady_fn).call(this);
|
|
803
|
+
this.dispatchEvent(
|
|
804
|
+
new CustomEvent("nexvio.ready", {
|
|
805
|
+
detail: payload,
|
|
806
|
+
bubbles: true,
|
|
807
|
+
composed: true
|
|
808
|
+
})
|
|
809
|
+
);
|
|
810
|
+
};
|
|
811
|
+
dispatchError_fn = function(payload) {
|
|
812
|
+
const error = new Error(payload.message);
|
|
813
|
+
if (payload.stack) {
|
|
814
|
+
error.stack = payload.stack;
|
|
815
|
+
}
|
|
816
|
+
log("[NexvioWidget] error", payload);
|
|
817
|
+
this.dispatchEvent(
|
|
818
|
+
new CustomEvent("nexvio.error", {
|
|
819
|
+
detail: { error },
|
|
820
|
+
bubbles: true,
|
|
821
|
+
composed: true
|
|
822
|
+
})
|
|
823
|
+
);
|
|
824
|
+
};
|
|
825
|
+
dispatchEvent_fn = function(payload) {
|
|
826
|
+
__privateMethod(this, _NexvioWidgetElement_instances, handleFrameEvent_fn).call(this, payload);
|
|
827
|
+
};
|
|
828
|
+
handleResize_fn = function(payload) {
|
|
829
|
+
if (typeof payload?.height === "number") {
|
|
830
|
+
this.style.setProperty("--nexvio-widget-height", `${payload.height}px`);
|
|
831
|
+
}
|
|
832
|
+
};
|
|
833
|
+
flushOptionsIfReady_fn = function() {
|
|
834
|
+
if (!__privateGet(this, _frameReady)) return;
|
|
835
|
+
if (!__privateGet(this, _pendingOptions)) return;
|
|
836
|
+
const options = __privateGet(this, _pendingOptions);
|
|
837
|
+
__privateSet(this, _pendingOptions, void 0);
|
|
838
|
+
if (!__privateGet(this, _messenger)) return;
|
|
839
|
+
debug("[NexvioWidget] flushOptionsIfReady: syncing options to frame");
|
|
840
|
+
void __privateGet(this, _messenger).commands.setOptions(options).catch((error) => {
|
|
841
|
+
console.error("Failed to sync widget options:", error);
|
|
842
|
+
});
|
|
843
|
+
};
|
|
844
|
+
function registerNexvioWidget(tagName = "nexvio-chat-widget") {
|
|
845
|
+
if (typeof customElements === "undefined") return;
|
|
846
|
+
if (!customElements.get(tagName)) {
|
|
847
|
+
customElements.define(tagName, NexvioWidgetElement);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// src/NexvioChatbotElement.ts
|
|
852
|
+
var styleContent2 = `
|
|
853
|
+
:host {
|
|
854
|
+
--chatbot-button-size: 60px;
|
|
855
|
+
--chatbot-button-bg: #3B82F6;
|
|
856
|
+
--chatbot-button-color: white;
|
|
857
|
+
--chatbot-widget-width: 420px;
|
|
858
|
+
--chatbot-widget-height: 600px;
|
|
859
|
+
--chatbot-widget-gap: 20px;
|
|
860
|
+
|
|
861
|
+
position: fixed;
|
|
862
|
+
bottom: var(--chatbot-widget-gap);
|
|
863
|
+
right: var(--chatbot-widget-gap);
|
|
864
|
+
z-index: 999999;
|
|
865
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
.nx-chatbot-button {
|
|
869
|
+
width: var(--chatbot-button-size);
|
|
870
|
+
height: var(--chatbot-button-size);
|
|
871
|
+
border-radius: 50%;
|
|
872
|
+
background: var(--chatbot-button-bg);
|
|
873
|
+
color: var(--chatbot-button-color);
|
|
874
|
+
border: none;
|
|
875
|
+
cursor: pointer;
|
|
876
|
+
display: flex;
|
|
877
|
+
align-items: center;
|
|
878
|
+
justify-content: center;
|
|
879
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
880
|
+
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
881
|
+
position: relative;
|
|
882
|
+
overflow: hidden;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
.nx-chatbot-button:hover {
|
|
886
|
+
transform: scale(1.05);
|
|
887
|
+
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
.nx-chatbot-button:active {
|
|
891
|
+
transform: scale(0.95);
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
.nx-chatbot-button svg {
|
|
895
|
+
width: 28px;
|
|
896
|
+
height: 28px;
|
|
897
|
+
transition: transform 0.3s ease, opacity 0.3s ease;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
.nx-chatbot-button.open svg.icon-chat {
|
|
901
|
+
transform: rotate(90deg) scale(0);
|
|
902
|
+
opacity: 0;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
.nx-chatbot-button svg.icon-close {
|
|
906
|
+
position: absolute;
|
|
907
|
+
transform: rotate(-90deg) scale(0);
|
|
908
|
+
opacity: 0;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
.nx-chatbot-button.open svg.icon-close {
|
|
912
|
+
transform: rotate(0deg) scale(1);
|
|
913
|
+
opacity: 1;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.nx-chatbot-widget-container {
|
|
917
|
+
position: absolute;
|
|
918
|
+
bottom: calc(var(--chatbot-button-size) + 16px);
|
|
919
|
+
right: 0;
|
|
920
|
+
width: var(--chatbot-widget-width);
|
|
921
|
+
height: var(--chatbot-widget-height);
|
|
922
|
+
max-height: calc(100vh - var(--chatbot-button-size) - var(--chatbot-widget-gap) - 32px);
|
|
923
|
+
border-radius: 12px;
|
|
924
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
|
|
925
|
+
overflow: hidden;
|
|
926
|
+
transform-origin: bottom right;
|
|
927
|
+
transform: scale(0.8);
|
|
928
|
+
opacity: 0;
|
|
929
|
+
pointer-events: none;
|
|
930
|
+
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
|
|
931
|
+
opacity 0.3s ease;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
.nx-chatbot-widget-container.open {
|
|
935
|
+
transform: scale(1);
|
|
936
|
+
opacity: 1;
|
|
937
|
+
pointer-events: auto;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
.nx-chatbot-widget-container nexvio-chat-widget {
|
|
941
|
+
display: block;
|
|
942
|
+
width: 100%;
|
|
943
|
+
height: 100%;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
.nx-chatbot-badge {
|
|
947
|
+
position: absolute;
|
|
948
|
+
top: -4px;
|
|
949
|
+
right: -4px;
|
|
950
|
+
min-width: 20px;
|
|
951
|
+
height: 20px;
|
|
952
|
+
padding: 0 6px;
|
|
953
|
+
background: #EF4444;
|
|
954
|
+
color: white;
|
|
955
|
+
border-radius: 10px;
|
|
956
|
+
font-size: 11px;
|
|
957
|
+
font-weight: 600;
|
|
958
|
+
display: flex;
|
|
959
|
+
align-items: center;
|
|
960
|
+
justify-content: center;
|
|
961
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
962
|
+
transform: scale(0);
|
|
963
|
+
transition: transform 0.2s ease;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
.nx-chatbot-badge.visible {
|
|
967
|
+
transform: scale(1);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
@media (max-width: 768px) {
|
|
971
|
+
:host {
|
|
972
|
+
bottom: 16px;
|
|
973
|
+
right: 16px;
|
|
974
|
+
--chatbot-widget-gap: 16px;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
.nx-chatbot-widget-container {
|
|
978
|
+
position: fixed;
|
|
979
|
+
bottom: 0;
|
|
980
|
+
right: 0;
|
|
981
|
+
left: 0;
|
|
982
|
+
top: 0;
|
|
983
|
+
width: 100%;
|
|
984
|
+
height: 100%;
|
|
985
|
+
max-width: 100%;
|
|
986
|
+
max-height: 100%;
|
|
987
|
+
border-radius: 0;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
.nx-chatbot-widget-container.open {
|
|
991
|
+
transform: scale(1);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
`;
|
|
995
|
+
var BaseHTMLElement2 = typeof HTMLElement === "undefined" ? class {
|
|
996
|
+
} : HTMLElement;
|
|
997
|
+
var _shadowRootRef2, _button, _widgetContainer, _widget, _badge, _isOpen, _options2, _initialized2, _NexvioChatbotElement_instances, ensureStructure_fn2, initialize_fn, updateWidget_fn, updateStyles_fn, updateBadge_fn;
|
|
998
|
+
var NexvioChatbotElement = class extends BaseHTMLElement2 {
|
|
999
|
+
constructor() {
|
|
1000
|
+
super();
|
|
1001
|
+
__privateAdd(this, _NexvioChatbotElement_instances);
|
|
1002
|
+
__privateAdd(this, _shadowRootRef2, null);
|
|
1003
|
+
__privateAdd(this, _button);
|
|
1004
|
+
__privateAdd(this, _widgetContainer);
|
|
1005
|
+
__privateAdd(this, _widget);
|
|
1006
|
+
__privateAdd(this, _badge);
|
|
1007
|
+
__privateAdd(this, _isOpen, false);
|
|
1008
|
+
__privateAdd(this, _options2);
|
|
1009
|
+
__privateAdd(this, _initialized2, false);
|
|
1010
|
+
if (typeof window !== "undefined" && typeof this.attachShadow === "function") {
|
|
1011
|
+
__privateSet(this, _shadowRootRef2, this.attachShadow({ mode: "open" }));
|
|
1012
|
+
}
|
|
1013
|
+
log("[NexvioChatbot] element: constructed");
|
|
1014
|
+
}
|
|
1015
|
+
connectedCallback() {
|
|
1016
|
+
log("[NexvioChatbot] element: connectedCallback");
|
|
1017
|
+
__privateMethod(this, _NexvioChatbotElement_instances, ensureStructure_fn2).call(this);
|
|
1018
|
+
if (__privateGet(this, _options2) && !__privateGet(this, _initialized2)) {
|
|
1019
|
+
__privateMethod(this, _NexvioChatbotElement_instances, initialize_fn).call(this);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
disconnectedCallback() {
|
|
1023
|
+
log("[NexvioChatbot] element: disconnectedCallback");
|
|
1024
|
+
}
|
|
1025
|
+
setOptions(options) {
|
|
1026
|
+
log("[NexvioChatbot] setOptions:", options);
|
|
1027
|
+
__privateSet(this, _options2, options);
|
|
1028
|
+
__privateMethod(this, _NexvioChatbotElement_instances, ensureStructure_fn2).call(this);
|
|
1029
|
+
if (!__privateGet(this, _initialized2)) {
|
|
1030
|
+
__privateMethod(this, _NexvioChatbotElement_instances, initialize_fn).call(this);
|
|
1031
|
+
} else {
|
|
1032
|
+
__privateMethod(this, _NexvioChatbotElement_instances, updateWidget_fn).call(this);
|
|
1033
|
+
}
|
|
1034
|
+
__privateMethod(this, _NexvioChatbotElement_instances, updateStyles_fn).call(this);
|
|
1035
|
+
__privateMethod(this, _NexvioChatbotElement_instances, updateBadge_fn).call(this);
|
|
1036
|
+
}
|
|
1037
|
+
open() {
|
|
1038
|
+
if (__privateGet(this, _isOpen)) return;
|
|
1039
|
+
__privateSet(this, _isOpen, true);
|
|
1040
|
+
__privateGet(this, _button)?.classList.add("open");
|
|
1041
|
+
__privateGet(this, _widgetContainer)?.classList.add("open");
|
|
1042
|
+
this.dispatchEvent(new CustomEvent("chatbot.opened", { bubbles: true, composed: true }));
|
|
1043
|
+
}
|
|
1044
|
+
close() {
|
|
1045
|
+
if (!__privateGet(this, _isOpen)) return;
|
|
1046
|
+
__privateSet(this, _isOpen, false);
|
|
1047
|
+
__privateGet(this, _button)?.classList.remove("open");
|
|
1048
|
+
__privateGet(this, _widgetContainer)?.classList.remove("open");
|
|
1049
|
+
this.dispatchEvent(new CustomEvent("chatbot.closed", { bubbles: true, composed: true }));
|
|
1050
|
+
}
|
|
1051
|
+
toggle() {
|
|
1052
|
+
if (__privateGet(this, _isOpen)) {
|
|
1053
|
+
this.close();
|
|
1054
|
+
} else {
|
|
1055
|
+
this.open();
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
get isOpen() {
|
|
1059
|
+
return __privateGet(this, _isOpen);
|
|
1060
|
+
}
|
|
1061
|
+
get widget() {
|
|
1062
|
+
return __privateGet(this, _widget);
|
|
1063
|
+
}
|
|
1064
|
+
get options() {
|
|
1065
|
+
return __privateGet(this, _options2);
|
|
1066
|
+
}
|
|
1067
|
+
};
|
|
1068
|
+
_shadowRootRef2 = new WeakMap();
|
|
1069
|
+
_button = new WeakMap();
|
|
1070
|
+
_widgetContainer = new WeakMap();
|
|
1071
|
+
_widget = new WeakMap();
|
|
1072
|
+
_badge = new WeakMap();
|
|
1073
|
+
_isOpen = new WeakMap();
|
|
1074
|
+
_options2 = new WeakMap();
|
|
1075
|
+
_initialized2 = new WeakMap();
|
|
1076
|
+
_NexvioChatbotElement_instances = new WeakSet();
|
|
1077
|
+
ensureStructure_fn2 = function() {
|
|
1078
|
+
if (__privateGet(this, _button) && __privateGet(this, _widgetContainer)) return;
|
|
1079
|
+
if (!__privateGet(this, _shadowRootRef2)) return;
|
|
1080
|
+
if (typeof window !== "undefined" && typeof customElements !== "undefined") {
|
|
1081
|
+
registerNexvioWidget();
|
|
1082
|
+
}
|
|
1083
|
+
const style = document.createElement("style");
|
|
1084
|
+
style.textContent = styleContent2;
|
|
1085
|
+
const button = document.createElement("button");
|
|
1086
|
+
button.className = "nx-chatbot-button";
|
|
1087
|
+
button.setAttribute("aria-label", "Open chat");
|
|
1088
|
+
button.innerHTML = `
|
|
1089
|
+
<svg class="icon-chat" xmlns="http://www.w3.org/2000/svg"
|
|
1090
|
+
viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
1091
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
1092
|
+
<path d="M6 4h12a3 3 0 0 1 3 3v7a3 3 0 0 1-3 3H9l-4 3v-3H6a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3z"/>
|
|
1093
|
+
</svg>
|
|
1094
|
+
<svg class="icon-close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
1095
|
+
<path d="M18 6L6 18M6 6l12 12"></path>
|
|
1096
|
+
</svg>
|
|
1097
|
+
`;
|
|
1098
|
+
const badge = document.createElement("span");
|
|
1099
|
+
badge.className = "nx-chatbot-badge";
|
|
1100
|
+
button.appendChild(badge);
|
|
1101
|
+
const widgetContainer = document.createElement("div");
|
|
1102
|
+
widgetContainer.className = "nx-chatbot-widget-container";
|
|
1103
|
+
const widget = document.createElement("nexvio-chat-widget");
|
|
1104
|
+
widgetContainer.appendChild(widget);
|
|
1105
|
+
__privateGet(this, _shadowRootRef2).append(style, button, widgetContainer);
|
|
1106
|
+
__privateSet(this, _button, button);
|
|
1107
|
+
__privateSet(this, _widgetContainer, widgetContainer);
|
|
1108
|
+
__privateSet(this, _widget, widget);
|
|
1109
|
+
__privateSet(this, _badge, badge);
|
|
1110
|
+
button.addEventListener("click", () => this.toggle());
|
|
1111
|
+
widget.addEventListener("nexvio.event", ((event) => {
|
|
1112
|
+
this.dispatchEvent(
|
|
1113
|
+
new CustomEvent("nexvio.event", {
|
|
1114
|
+
detail: event.detail,
|
|
1115
|
+
bubbles: true,
|
|
1116
|
+
composed: true
|
|
1117
|
+
})
|
|
1118
|
+
);
|
|
1119
|
+
}));
|
|
1120
|
+
};
|
|
1121
|
+
initialize_fn = function() {
|
|
1122
|
+
if (__privateGet(this, _initialized2) || !__privateGet(this, _options2) || !__privateGet(this, _widget)) return;
|
|
1123
|
+
__privateSet(this, _initialized2, true);
|
|
1124
|
+
const widgetOptions = { ...__privateGet(this, _options2) };
|
|
1125
|
+
delete widgetOptions.position;
|
|
1126
|
+
delete widgetOptions.defaultOpen;
|
|
1127
|
+
delete widgetOptions.buttonColor;
|
|
1128
|
+
delete widgetOptions.badge;
|
|
1129
|
+
delete widgetOptions.buttonIcon;
|
|
1130
|
+
delete widgetOptions.gap;
|
|
1131
|
+
const setWidgetOptions = () => {
|
|
1132
|
+
if (__privateGet(this, _widget) && typeof __privateGet(this, _widget).setOptions === "function") {
|
|
1133
|
+
__privateGet(this, _widget).setOptions(widgetOptions);
|
|
1134
|
+
if (__privateGet(this, _options2)?.defaultOpen) {
|
|
1135
|
+
setTimeout(() => this.open(), 100);
|
|
1136
|
+
}
|
|
1137
|
+
debug("[NexvioChatbot] initialized");
|
|
1138
|
+
} else if (typeof window !== "undefined" && typeof customElements !== "undefined") {
|
|
1139
|
+
customElements.whenDefined("nexvio-chat-widget").then(() => {
|
|
1140
|
+
if (__privateGet(this, _widget) && typeof __privateGet(this, _widget).setOptions === "function") {
|
|
1141
|
+
__privateGet(this, _widget).setOptions(widgetOptions);
|
|
1142
|
+
if (__privateGet(this, _options2)?.defaultOpen) {
|
|
1143
|
+
setTimeout(() => this.open(), 100);
|
|
1144
|
+
}
|
|
1145
|
+
debug("[NexvioChatbot] initialized");
|
|
1146
|
+
}
|
|
1147
|
+
}).catch(() => {
|
|
1148
|
+
console.error("[NexvioChatbot] Failed to initialize widget element");
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
};
|
|
1152
|
+
setWidgetOptions();
|
|
1153
|
+
};
|
|
1154
|
+
updateWidget_fn = function() {
|
|
1155
|
+
if (!__privateGet(this, _widget) || !__privateGet(this, _options2)) return;
|
|
1156
|
+
const widgetOptions = { ...__privateGet(this, _options2) };
|
|
1157
|
+
delete widgetOptions.position;
|
|
1158
|
+
delete widgetOptions.defaultOpen;
|
|
1159
|
+
delete widgetOptions.buttonColor;
|
|
1160
|
+
delete widgetOptions.badge;
|
|
1161
|
+
delete widgetOptions.buttonIcon;
|
|
1162
|
+
delete widgetOptions.gap;
|
|
1163
|
+
if (typeof __privateGet(this, _widget).setOptions === "function") {
|
|
1164
|
+
__privateGet(this, _widget).setOptions(widgetOptions);
|
|
1165
|
+
} else if (typeof window !== "undefined" && typeof customElements !== "undefined") {
|
|
1166
|
+
customElements.whenDefined("nexvio-chat-widget").then(() => {
|
|
1167
|
+
if (__privateGet(this, _widget) && typeof __privateGet(this, _widget).setOptions === "function") {
|
|
1168
|
+
__privateGet(this, _widget).setOptions(widgetOptions);
|
|
1169
|
+
}
|
|
1170
|
+
}).catch(() => {
|
|
1171
|
+
console.error("[NexvioChatbot] Failed to update widget element");
|
|
1172
|
+
});
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
updateStyles_fn = function() {
|
|
1176
|
+
if (!__privateGet(this, _options2)) return;
|
|
1177
|
+
const host = __privateGet(this, _shadowRootRef2)?.host;
|
|
1178
|
+
if (!host) return;
|
|
1179
|
+
if (__privateGet(this, _options2).buttonColor) {
|
|
1180
|
+
host.style.setProperty("--chatbot-button-bg", __privateGet(this, _options2).buttonColor);
|
|
1181
|
+
}
|
|
1182
|
+
if (__privateGet(this, _options2).gap !== void 0) {
|
|
1183
|
+
host.style.setProperty("--chatbot-widget-gap", `${__privateGet(this, _options2).gap}px`);
|
|
1184
|
+
}
|
|
1185
|
+
if (__privateGet(this, _options2).position) {
|
|
1186
|
+
const positions = {
|
|
1187
|
+
"bottom-right": {
|
|
1188
|
+
bottom: "var(--chatbot-widget-gap)",
|
|
1189
|
+
right: "var(--chatbot-widget-gap)",
|
|
1190
|
+
top: "auto",
|
|
1191
|
+
left: "auto"
|
|
1192
|
+
},
|
|
1193
|
+
"bottom-left": {
|
|
1194
|
+
bottom: "var(--chatbot-widget-gap)",
|
|
1195
|
+
left: "var(--chatbot-widget-gap)",
|
|
1196
|
+
top: "auto",
|
|
1197
|
+
right: "auto"
|
|
1198
|
+
},
|
|
1199
|
+
"top-right": {
|
|
1200
|
+
top: "var(--chatbot-widget-gap)",
|
|
1201
|
+
right: "var(--chatbot-widget-gap)",
|
|
1202
|
+
bottom: "auto",
|
|
1203
|
+
left: "auto"
|
|
1204
|
+
},
|
|
1205
|
+
"top-left": {
|
|
1206
|
+
top: "var(--chatbot-widget-gap)",
|
|
1207
|
+
left: "var(--chatbot-widget-gap)",
|
|
1208
|
+
bottom: "auto",
|
|
1209
|
+
right: "auto"
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
const pos = positions[__privateGet(this, _options2).position];
|
|
1213
|
+
Object.entries(pos).forEach(([key, value]) => {
|
|
1214
|
+
host.style.setProperty(key, value);
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
if (__privateGet(this, _options2).buttonIcon && __privateGet(this, _button)) {
|
|
1218
|
+
const chatIcon = __privateGet(this, _button).querySelector(".icon-chat");
|
|
1219
|
+
if (chatIcon) {
|
|
1220
|
+
chatIcon.innerHTML = __privateGet(this, _options2).buttonIcon;
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
};
|
|
1224
|
+
updateBadge_fn = function() {
|
|
1225
|
+
if (!__privateGet(this, _badge) || !__privateGet(this, _options2)) return;
|
|
1226
|
+
const badgeValue = __privateGet(this, _options2).badge;
|
|
1227
|
+
if (typeof badgeValue === "number" && badgeValue > 0) {
|
|
1228
|
+
__privateGet(this, _badge).textContent = badgeValue > 99 ? "99+" : String(badgeValue);
|
|
1229
|
+
__privateGet(this, _badge).classList.add("visible");
|
|
1230
|
+
} else if (badgeValue === true) {
|
|
1231
|
+
__privateGet(this, _badge).textContent = "";
|
|
1232
|
+
__privateGet(this, _badge).classList.add("visible");
|
|
1233
|
+
} else {
|
|
1234
|
+
__privateGet(this, _badge).classList.remove("visible");
|
|
1235
|
+
}
|
|
1236
|
+
};
|
|
1237
|
+
function registerNexvioChatbot(tagName = "nexvio-chat-bot") {
|
|
1238
|
+
if (typeof customElements === "undefined") return;
|
|
1239
|
+
if (!customElements.get(tagName)) {
|
|
1240
|
+
customElements.define(tagName, NexvioChatbotElement);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
export {
|
|
1245
|
+
NexvioWidgetElement,
|
|
1246
|
+
registerNexvioWidget,
|
|
1247
|
+
NexvioChatbotElement,
|
|
1248
|
+
registerNexvioChatbot
|
|
1249
|
+
};
|
|
1250
|
+
//# sourceMappingURL=chunk-M2QGY5LN.js.map
|