@syntrologie/adapt-chatbot 2.41.3 → 2.43.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/dist/AdaptiveChatBar.js +1 -1
- package/dist/AdaptiveChatTrail.d.ts +19 -0
- package/dist/AdaptiveChatTrail.d.ts.map +1 -1
- package/dist/AdaptiveChatTrail.js +1 -1
- package/dist/AdaptiveChipsStrip.d.ts +12 -12
- package/dist/AdaptiveChipsStrip.d.ts.map +1 -1
- package/dist/AdaptiveChipsStrip.js +2 -2
- package/dist/ChatAssistantLit.js +2 -2
- package/dist/ChatTransport.d.ts +26 -0
- package/dist/ChatTransport.d.ts.map +1 -1
- package/dist/LeaveAMessage.leadconnector.integration.test.d.ts +2 -0
- package/dist/LeaveAMessage.leadconnector.integration.test.d.ts.map +1 -0
- package/dist/{chunk-KBU4BUOE.js → chunk-3JCJDTHS.js} +2 -2
- package/dist/{chunk-3Z52KSYZ.js → chunk-EKGGGUI2.js} +82 -33
- package/dist/chunk-EKGGGUI2.js.map +7 -0
- package/dist/{chunk-X7N6ZRAX.js → chunk-NWVTKK75.js} +2 -2
- package/dist/{chunk-5TFBPUYA.js → chunk-Q6K4TUQO.js} +141 -5
- package/dist/chunk-Q6K4TUQO.js.map +7 -0
- package/dist/observer/__tests__/detector-observation-contract.test.d.ts +25 -0
- package/dist/observer/__tests__/detector-observation-contract.test.d.ts.map +1 -0
- package/dist/observer/allowlist.d.ts +2 -0
- package/dist/observer/allowlist.d.ts.map +1 -1
- package/dist/runtime.js +411 -159
- package/dist/runtime.js.map +4 -4
- package/dist/schema.d.ts +66 -40
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +106 -6
- package/dist/schema.js.map +3 -3
- package/dist/support-chat/__tests__/lc-fetch-stub.d.ts +27 -0
- package/dist/support-chat/__tests__/lc-fetch-stub.d.ts.map +1 -0
- package/dist/support-chat/boot.d.ts +3 -0
- package/dist/support-chat/boot.d.ts.map +1 -1
- package/dist/support-chat/leadconnector.d.ts +13 -0
- package/dist/support-chat/leadconnector.d.ts.map +1 -0
- package/dist/support-chat/leadconnector.test.d.ts +2 -0
- package/dist/support-chat/leadconnector.test.d.ts.map +1 -0
- package/dist/support-chat/schema-widgetid.test.d.ts +2 -0
- package/dist/support-chat/schema-widgetid.test.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-3Z52KSYZ.js.map +0 -7
- package/dist/chunk-5TFBPUYA.js.map +0 -7
- /package/dist/{chunk-KBU4BUOE.js.map → chunk-3JCJDTHS.js.map} +0 -0
- /package/dist/{chunk-X7N6ZRAX.js.map → chunk-NWVTKK75.js.map} +0 -0
package/dist/runtime.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
decodeMutationEnvelope,
|
|
10
10
|
fetchMountedElements,
|
|
11
11
|
renderFallbackHtml
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-3JCJDTHS.js";
|
|
13
13
|
import {
|
|
14
14
|
pickPersona
|
|
15
15
|
} from "./chunk-FXHYE6FY.js";
|
|
@@ -17,15 +17,16 @@ import {
|
|
|
17
17
|
getElementInstanceStore,
|
|
18
18
|
setElementInstanceStore
|
|
19
19
|
} from "./chunk-EWPPVPJ4.js";
|
|
20
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-EKGGGUI2.js";
|
|
21
21
|
import "./chunk-VZIUXXAM.js";
|
|
22
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-NWVTKK75.js";
|
|
23
23
|
import {
|
|
24
24
|
DIVE_DEEPER_EVENT,
|
|
25
25
|
TILE_MOUNTED_EVENT,
|
|
26
26
|
TILE_UNMOUNTED_EVENT,
|
|
27
|
+
isCanonicalBusEvent,
|
|
27
28
|
stripMountPlumbing
|
|
28
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-Q6K4TUQO.js";
|
|
29
30
|
import "./chunk-UVKRO5ER.js";
|
|
30
31
|
|
|
31
32
|
// src/ChatSession.ts
|
|
@@ -694,11 +695,11 @@ var ChatTransport = class {
|
|
|
694
695
|
this._sessionStreamAbort = abort;
|
|
695
696
|
const baseUrl = this._config.backendUrl.replace(/\/$/, "");
|
|
696
697
|
const url = `${baseUrl}/api/adaptive/session`;
|
|
697
|
-
const
|
|
698
|
+
const headers2 = {};
|
|
698
699
|
const token = readRuntimeToken(this._config?.runtime);
|
|
699
|
-
if (token)
|
|
700
|
+
if (token) headers2.Authorization = `Bearer ${token}`;
|
|
700
701
|
const cft = await this._acquireTurnstileWithChallenge();
|
|
701
|
-
if (cft)
|
|
702
|
+
if (cft) headers2["CF-Turnstile-Token"] = cft;
|
|
702
703
|
if (abort.signal.aborted) return;
|
|
703
704
|
const readIds = () => {
|
|
704
705
|
try {
|
|
@@ -727,8 +728,8 @@ var ChatTransport = class {
|
|
|
727
728
|
ids = readIds();
|
|
728
729
|
}
|
|
729
730
|
if (abort.signal.aborted) return;
|
|
730
|
-
if (ids.did)
|
|
731
|
-
if (ids.sid)
|
|
731
|
+
if (ids.did) headers2["X-Distinct-Id"] = ids.did;
|
|
732
|
+
if (ids.sid) headers2["X-Syntro-Session"] = ids.sid;
|
|
732
733
|
const runReader = async () => {
|
|
733
734
|
const connAbort = new AbortController();
|
|
734
735
|
const onOuterAbort = () => connAbort.abort();
|
|
@@ -744,7 +745,7 @@ var ChatTransport = class {
|
|
|
744
745
|
});
|
|
745
746
|
try {
|
|
746
747
|
const response = await fetch(url, {
|
|
747
|
-
headers,
|
|
748
|
+
headers: headers2,
|
|
748
749
|
credentials: "include",
|
|
749
750
|
signal: connAbort.signal
|
|
750
751
|
});
|
|
@@ -800,8 +801,8 @@ var ChatTransport = class {
|
|
|
800
801
|
await new Promise((r) => setTimeout(r, this._sessionStreamBackoffMs));
|
|
801
802
|
this._sessionStreamBackoffMs = Math.min(this._sessionStreamBackoffMs * 2, 3e4);
|
|
802
803
|
const fresh = readIds();
|
|
803
|
-
if (fresh.did)
|
|
804
|
-
if (fresh.sid)
|
|
804
|
+
if (fresh.did) headers2["X-Distinct-Id"] = fresh.did;
|
|
805
|
+
if (fresh.sid) headers2["X-Syntro-Session"] = fresh.sid;
|
|
805
806
|
}
|
|
806
807
|
})();
|
|
807
808
|
await Promise.resolve();
|
|
@@ -1374,6 +1375,120 @@ function renderCustomEvent(raw) {
|
|
|
1374
1375
|
}
|
|
1375
1376
|
return fields.length > 0 ? `${raw.event} (${fields.join(", ")})` : raw.event;
|
|
1376
1377
|
}
|
|
1378
|
+
function seconds(ms) {
|
|
1379
|
+
return typeof ms === "number" && Number.isFinite(ms) ? Math.round(ms / 1e3) : null;
|
|
1380
|
+
}
|
|
1381
|
+
function describeBusElement(el) {
|
|
1382
|
+
if (!el) return null;
|
|
1383
|
+
const text = typeof el.text === "string" ? el.text.trim() : "";
|
|
1384
|
+
if (text) return text;
|
|
1385
|
+
const aria = el["attr__aria-label"];
|
|
1386
|
+
if (typeof aria === "string" && aria.trim()) return aria.trim();
|
|
1387
|
+
const id = el.attr__id;
|
|
1388
|
+
if (typeof id === "string" && id.trim()) return `#${id.trim()}`;
|
|
1389
|
+
return null;
|
|
1390
|
+
}
|
|
1391
|
+
var CANONICAL_SUMMARIES = {
|
|
1392
|
+
"ui.hover": {
|
|
1393
|
+
requires: ["element"],
|
|
1394
|
+
render: (p, ts) => {
|
|
1395
|
+
const label = describeBusElement(p.element);
|
|
1396
|
+
if (!label) return null;
|
|
1397
|
+
return { ts, kind: "hover", text: truncate(`hovered on '${label}'`) };
|
|
1398
|
+
}
|
|
1399
|
+
},
|
|
1400
|
+
"ui.idle": {
|
|
1401
|
+
requires: ["duration_ms"],
|
|
1402
|
+
render: (p, ts) => {
|
|
1403
|
+
const secs = seconds(p.duration_ms);
|
|
1404
|
+
if (secs === null) return null;
|
|
1405
|
+
return { ts, kind: "idle", text: `idle for ${secs}s` };
|
|
1406
|
+
}
|
|
1407
|
+
},
|
|
1408
|
+
"ui.hesitate": {
|
|
1409
|
+
requires: ["duration_ms"],
|
|
1410
|
+
render: (p, ts) => {
|
|
1411
|
+
const secs = seconds(p.duration_ms);
|
|
1412
|
+
if (secs === null) return null;
|
|
1413
|
+
return { ts, kind: "hesitation", text: `hesitated in place for ${secs}s` };
|
|
1414
|
+
}
|
|
1415
|
+
},
|
|
1416
|
+
"ui.rage_click": {
|
|
1417
|
+
// Previously had NO case at all: the rrweb rage-click detector emits
|
|
1418
|
+
// `ui.rage_click`, the summarizer only knew PostHog's `$rageclick`, so
|
|
1419
|
+
// every detector-sourced rage click was dropped on the floor.
|
|
1420
|
+
requires: ["click_count"],
|
|
1421
|
+
render: (p, ts) => {
|
|
1422
|
+
const count = p.click_count;
|
|
1423
|
+
if (typeof count !== "number") return null;
|
|
1424
|
+
return { ts, kind: "rage", text: `clicked the same spot ${count} times in a row` };
|
|
1425
|
+
}
|
|
1426
|
+
},
|
|
1427
|
+
"ui.scroll_thrash": {
|
|
1428
|
+
requires: ["reversals"],
|
|
1429
|
+
render: (p, ts) => {
|
|
1430
|
+
const reversals = p.reversals;
|
|
1431
|
+
if (typeof reversals !== "number") return null;
|
|
1432
|
+
return {
|
|
1433
|
+
ts,
|
|
1434
|
+
kind: "scroll",
|
|
1435
|
+
text: `changed scroll direction ${reversals} times (looking for something)`
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
},
|
|
1439
|
+
"ui.focus_bounce": {
|
|
1440
|
+
// The rrweb detector has an rrweb node id and a duration — no element
|
|
1441
|
+
// chain, no text, and no way to get one. Say what we actually know
|
|
1442
|
+
// instead of rendering `focused '' but didn't fill it`.
|
|
1443
|
+
requires: ["duration_ms"],
|
|
1444
|
+
render: (p, ts) => {
|
|
1445
|
+
const secs = seconds(p.duration_ms);
|
|
1446
|
+
if (secs === null) return null;
|
|
1447
|
+
return {
|
|
1448
|
+
ts,
|
|
1449
|
+
kind: "form",
|
|
1450
|
+
text: secs >= 1 ? `focused a form field for ${secs}s without filling it` : "focused a form field without filling it"
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
},
|
|
1454
|
+
"nav.section_viewed": {
|
|
1455
|
+
requires: ["section"],
|
|
1456
|
+
render: (p, ts) => {
|
|
1457
|
+
const section = typeof p.section === "string" ? p.section : "";
|
|
1458
|
+
if (!section) return null;
|
|
1459
|
+
return {
|
|
1460
|
+
ts,
|
|
1461
|
+
kind: "view",
|
|
1462
|
+
text: truncate(`viewed the '${section}' section`),
|
|
1463
|
+
ref: truncate(section)
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
},
|
|
1467
|
+
"nav.scroll_depth": {
|
|
1468
|
+
requires: ["percent"],
|
|
1469
|
+
render: (p, ts) => {
|
|
1470
|
+
const pct = p.percent;
|
|
1471
|
+
if (typeof pct !== "number") return null;
|
|
1472
|
+
return { ts, kind: "scroll", text: truncate(`scrolled to ${pct}% of the page`) };
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
};
|
|
1476
|
+
var warnedDrift = /* @__PURE__ */ new Set();
|
|
1477
|
+
function renderCanonicalBusEvent(name, props, ts) {
|
|
1478
|
+
const summary = CANONICAL_SUMMARIES[name];
|
|
1479
|
+
const missing = summary.requires.filter((key) => props[key] === void 0);
|
|
1480
|
+
if (missing.length > 0) {
|
|
1481
|
+
const dedupKey = `${name}|${missing.join(",")}`;
|
|
1482
|
+
if (!warnedDrift.has(dedupKey)) {
|
|
1483
|
+
warnedDrift.add(dedupKey);
|
|
1484
|
+
console.warn(
|
|
1485
|
+
`observer.canonical_props_drift: '${name}' arrived without [${missing.join(", ")}]; got keys [${Object.keys(props).join(", ")}]. Producer disagrees with @syntrologie/sdk-contracts CanonicalBusEventProps \u2014 observation dropped. (warned once per event/missing-key shape)`
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
return null;
|
|
1489
|
+
}
|
|
1490
|
+
return summary.render(props, ts);
|
|
1491
|
+
}
|
|
1377
1492
|
function matchEvent(raw, opts = {}) {
|
|
1378
1493
|
const props = raw.properties;
|
|
1379
1494
|
switch (raw.event) {
|
|
@@ -1422,77 +1537,10 @@ function matchEvent(raw, opts = {}) {
|
|
|
1422
1537
|
text: truncate(`clicked '${text}' (no response)`)
|
|
1423
1538
|
};
|
|
1424
1539
|
}
|
|
1425
|
-
// ── Canonical runtime-bus events (sources: `'canvas'` instrumentation
|
|
1426
|
-
// or the event-processor's rrweb detectors). These don't go through
|
|
1427
|
-
// PostHog; the chat-bar's bus translator forwards them as-is with
|
|
1428
|
-
// the canonical event name, and matchEvent picks the right slot
|
|
1429
|
-
// here. Keeps a single allowlist as the source of truth for what
|
|
1430
|
-
// the agent's observation tail can carry.
|
|
1431
|
-
case "nav.section_viewed": {
|
|
1432
|
-
const section = typeof props.section === "string" ? props.section : "";
|
|
1433
|
-
if (!section) return null;
|
|
1434
|
-
return {
|
|
1435
|
-
ts: raw.timestamp,
|
|
1436
|
-
kind: "view",
|
|
1437
|
-
text: truncate(`viewed the '${section}' section`),
|
|
1438
|
-
ref: truncate(section)
|
|
1439
|
-
};
|
|
1440
|
-
}
|
|
1441
|
-
case "nav.scroll_depth": {
|
|
1442
|
-
const pct = typeof props.percent === "number" ? props.percent : null;
|
|
1443
|
-
if (pct === null) return null;
|
|
1444
|
-
return {
|
|
1445
|
-
ts: raw.timestamp,
|
|
1446
|
-
kind: "scroll",
|
|
1447
|
-
text: truncate(`scrolled to ${pct}% of the page`)
|
|
1448
|
-
};
|
|
1449
|
-
}
|
|
1450
|
-
case "ui.scroll_thrash": {
|
|
1451
|
-
return {
|
|
1452
|
-
ts: raw.timestamp,
|
|
1453
|
-
kind: "scroll",
|
|
1454
|
-
text: "scrolled up and down repeatedly (looking for something)"
|
|
1455
|
-
};
|
|
1456
|
-
}
|
|
1457
|
-
case "ui.idle": {
|
|
1458
|
-
const ms = typeof props.durationMs === "number" ? props.durationMs : null;
|
|
1459
|
-
const secs = ms !== null ? Math.round(ms / 1e3) : null;
|
|
1460
|
-
return {
|
|
1461
|
-
ts: raw.timestamp,
|
|
1462
|
-
kind: "idle",
|
|
1463
|
-
text: secs !== null ? `idle for ${secs}s` : "idle"
|
|
1464
|
-
};
|
|
1465
|
-
}
|
|
1466
|
-
case "ui.hover": {
|
|
1467
|
-
const text = elementText(props) || elementTag(props);
|
|
1468
|
-
return {
|
|
1469
|
-
ts: raw.timestamp,
|
|
1470
|
-
kind: "hover",
|
|
1471
|
-
text: truncate(`hovered on '${text}'`)
|
|
1472
|
-
};
|
|
1473
|
-
}
|
|
1474
|
-
// Canonical name is 'ui.hesitate' (StandardEvents.UI_HESITATE) — the rrweb
|
|
1475
|
-
// hesitation detector emits coordinates + duration_ms, no element chain, so
|
|
1476
|
-
// the summary is duration-based. (BUG-1784146789: this case was spelled
|
|
1477
|
-
// 'ui.hesitation', a name nothing emits, so the signal never arrived.)
|
|
1478
|
-
case "ui.hesitate": {
|
|
1479
|
-
const ms = typeof props.duration_ms === "number" ? props.duration_ms : null;
|
|
1480
|
-
const secs = ms !== null ? Math.round(ms / 1e3) : null;
|
|
1481
|
-
return {
|
|
1482
|
-
ts: raw.timestamp,
|
|
1483
|
-
kind: "hesitation",
|
|
1484
|
-
text: secs !== null ? `hesitated in place for ${secs}s` : "hesitated in place"
|
|
1485
|
-
};
|
|
1486
|
-
}
|
|
1487
|
-
case "ui.focus_bounce": {
|
|
1488
|
-
const text = elementText(props) || elementTag(props);
|
|
1489
|
-
return {
|
|
1490
|
-
ts: raw.timestamp,
|
|
1491
|
-
kind: "form",
|
|
1492
|
-
text: truncate(`focused '${text}' but didn't fill it`)
|
|
1493
|
-
};
|
|
1494
|
-
}
|
|
1495
1540
|
default: {
|
|
1541
|
+
if (isCanonicalBusEvent(raw.event)) {
|
|
1542
|
+
return renderCanonicalBusEvent(raw.event, props, raw.timestamp);
|
|
1543
|
+
}
|
|
1496
1544
|
const allow = opts.observableEvents ?? [];
|
|
1497
1545
|
if (allow.includes(raw.event)) {
|
|
1498
1546
|
return {
|
|
@@ -1546,7 +1594,7 @@ var ObserverQueue = class {
|
|
|
1546
1594
|
* Returns false when the sender rejected delivery and restores the batch so
|
|
1547
1595
|
* the caller can fall back to fetch({ keepalive: true }).
|
|
1548
1596
|
*/
|
|
1549
|
-
flushOnPageHide(
|
|
1597
|
+
flushOnPageHide(send2) {
|
|
1550
1598
|
if (this._disabled || this._buffer.length === 0) return true;
|
|
1551
1599
|
this._clearInterval();
|
|
1552
1600
|
const overflow = Math.max(0, this._buffer.length - 50);
|
|
@@ -1555,7 +1603,7 @@ var ObserverQueue = class {
|
|
|
1555
1603
|
this._dropped += overflow;
|
|
1556
1604
|
}
|
|
1557
1605
|
const batch = this._buffer.splice(0, 50);
|
|
1558
|
-
if (!
|
|
1606
|
+
if (!send2(batch)) {
|
|
1559
1607
|
this._buffer.unshift(...batch);
|
|
1560
1608
|
return false;
|
|
1561
1609
|
}
|
|
@@ -1848,18 +1896,222 @@ function registerCrispBridge() {
|
|
|
1848
1896
|
}
|
|
1849
1897
|
registerCrispBridge();
|
|
1850
1898
|
|
|
1899
|
+
// src/support-chat/leadconnector.ts
|
|
1900
|
+
var LC_SERVICES = "https://services.leadconnectorhq.com";
|
|
1901
|
+
var LC_POLL_MS = 1e4;
|
|
1902
|
+
var LC_PAGE_LIMIT = 20;
|
|
1903
|
+
function lcStorageKey(widgetId) {
|
|
1904
|
+
return `syntro:supportchat:leadconnector:${widgetId}`;
|
|
1905
|
+
}
|
|
1906
|
+
var cfg;
|
|
1907
|
+
var locationIdCache;
|
|
1908
|
+
function warn(what, detail) {
|
|
1909
|
+
console.warn(`supportChat.bridge: leadconnector ${what}`, detail);
|
|
1910
|
+
}
|
|
1911
|
+
function load() {
|
|
1912
|
+
if (!cfg) return void 0;
|
|
1913
|
+
try {
|
|
1914
|
+
const raw = sessionStorage.getItem(lcStorageKey(cfg.widgetId));
|
|
1915
|
+
return raw ? JSON.parse(raw) : void 0;
|
|
1916
|
+
} catch (err) {
|
|
1917
|
+
warn("state read failed", err);
|
|
1918
|
+
return void 0;
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
function save(id) {
|
|
1922
|
+
if (!cfg) return;
|
|
1923
|
+
try {
|
|
1924
|
+
sessionStorage.setItem(lcStorageKey(cfg.widgetId), JSON.stringify(id));
|
|
1925
|
+
} catch (err) {
|
|
1926
|
+
warn("state write failed", err);
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
async function resolveLocationId() {
|
|
1930
|
+
const persisted = load();
|
|
1931
|
+
if (persisted?.locationId) return persisted.locationId;
|
|
1932
|
+
if (!cfg) return void 0;
|
|
1933
|
+
const widgetId = cfg.widgetId;
|
|
1934
|
+
locationIdCache ?? (locationIdCache = (async () => {
|
|
1935
|
+
try {
|
|
1936
|
+
const r = await fetch(`${LC_SERVICES}/chat-widget/public/config/${widgetId}`);
|
|
1937
|
+
if (!r.ok) {
|
|
1938
|
+
warn("public config fetch failed", r.status);
|
|
1939
|
+
return void 0;
|
|
1940
|
+
}
|
|
1941
|
+
const j = await r.json();
|
|
1942
|
+
const loc = j?.config?.["location-id"];
|
|
1943
|
+
return typeof loc === "string" && loc ? loc : void 0;
|
|
1944
|
+
} catch (err) {
|
|
1945
|
+
warn("public config fetch threw", err);
|
|
1946
|
+
return void 0;
|
|
1947
|
+
}
|
|
1948
|
+
})());
|
|
1949
|
+
return locationIdCache;
|
|
1950
|
+
}
|
|
1951
|
+
function headers(token) {
|
|
1952
|
+
const h = { "Content-Type": "application/json" };
|
|
1953
|
+
if (token) h.Authorization = `Bearer ${token}`;
|
|
1954
|
+
return h;
|
|
1955
|
+
}
|
|
1956
|
+
async function doSend(text) {
|
|
1957
|
+
if (!cfg) return;
|
|
1958
|
+
const locationId = await resolveLocationId();
|
|
1959
|
+
if (!locationId) {
|
|
1960
|
+
warn("no locationId \u2014 send dropped", cfg.widgetId);
|
|
1961
|
+
return;
|
|
1962
|
+
}
|
|
1963
|
+
const prior = load();
|
|
1964
|
+
const body = {
|
|
1965
|
+
locationId,
|
|
1966
|
+
widgetId: cfg.widgetId,
|
|
1967
|
+
defaultWidget: true,
|
|
1968
|
+
message: text,
|
|
1969
|
+
subType: "liveChat"
|
|
1970
|
+
};
|
|
1971
|
+
if (prior?.conversationId) body.conversationId = prior.conversationId;
|
|
1972
|
+
try {
|
|
1973
|
+
const r = await fetch(`${LC_SERVICES}/conversations/providers/live-chat/messages`, {
|
|
1974
|
+
method: "POST",
|
|
1975
|
+
headers: headers(prior?.token),
|
|
1976
|
+
body: JSON.stringify(body)
|
|
1977
|
+
});
|
|
1978
|
+
if (!r.ok) {
|
|
1979
|
+
warn("send rejected", r.status);
|
|
1980
|
+
return;
|
|
1981
|
+
}
|
|
1982
|
+
const j = await r.json();
|
|
1983
|
+
const fresh = load();
|
|
1984
|
+
save({
|
|
1985
|
+
...fresh,
|
|
1986
|
+
locationId,
|
|
1987
|
+
visitorId: j.visitorId ?? fresh?.visitorId ?? prior?.visitorId,
|
|
1988
|
+
conversationId: j.conversationId ?? fresh?.conversationId ?? prior?.conversationId,
|
|
1989
|
+
contactId: j.contactId ?? fresh?.contactId ?? prior?.contactId,
|
|
1990
|
+
token: j.token ?? fresh?.token ?? prior?.token
|
|
1991
|
+
});
|
|
1992
|
+
} catch (err) {
|
|
1993
|
+
warn("send threw", err);
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
var sendChain = Promise.resolve();
|
|
1997
|
+
function send(text) {
|
|
1998
|
+
const result = sendChain.then(() => doSend(text));
|
|
1999
|
+
sendChain = result;
|
|
2000
|
+
return result;
|
|
2001
|
+
}
|
|
2002
|
+
var pollWarned = false;
|
|
2003
|
+
var pollInFlight = false;
|
|
2004
|
+
async function pollOnce(cb, isActive) {
|
|
2005
|
+
const id = load();
|
|
2006
|
+
if (!id?.conversationId || !id.token) return;
|
|
2007
|
+
if (pollInFlight) return;
|
|
2008
|
+
pollInFlight = true;
|
|
2009
|
+
try {
|
|
2010
|
+
const qs = new URLSearchParams({
|
|
2011
|
+
conversationId: id.conversationId,
|
|
2012
|
+
locationId: id.locationId,
|
|
2013
|
+
lastMessageId: id.lastMessageId ?? "",
|
|
2014
|
+
pageLimit: String(LC_PAGE_LIMIT)
|
|
2015
|
+
});
|
|
2016
|
+
try {
|
|
2017
|
+
const r = await fetch(
|
|
2018
|
+
`${LC_SERVICES}/conversations/providers/live-chat/messages/search?${qs}`,
|
|
2019
|
+
{
|
|
2020
|
+
headers: headers(id.token)
|
|
2021
|
+
}
|
|
2022
|
+
);
|
|
2023
|
+
if (!r.ok) {
|
|
2024
|
+
if (!pollWarned) {
|
|
2025
|
+
warn("poll rejected", r.status);
|
|
2026
|
+
pollWarned = true;
|
|
2027
|
+
}
|
|
2028
|
+
return;
|
|
2029
|
+
}
|
|
2030
|
+
const j = await r.json();
|
|
2031
|
+
if (!isActive()) return;
|
|
2032
|
+
const messages = j.messages ?? [];
|
|
2033
|
+
for (const m of messages) {
|
|
2034
|
+
if (m.direction === "outbound" && typeof m.body === "string") cb(m.body);
|
|
2035
|
+
}
|
|
2036
|
+
const lastMessage = messages[messages.length - 1];
|
|
2037
|
+
const nextLastMessageId = typeof j.lastMessageId === "string" && j.lastMessageId ? j.lastMessageId : typeof lastMessage?.id === "string" && lastMessage.id ? lastMessage.id : void 0;
|
|
2038
|
+
if (nextLastMessageId) {
|
|
2039
|
+
const current = load();
|
|
2040
|
+
save({ ...id, ...current, lastMessageId: nextLastMessageId });
|
|
2041
|
+
}
|
|
2042
|
+
pollWarned = false;
|
|
2043
|
+
} catch (err) {
|
|
2044
|
+
if (!pollWarned) {
|
|
2045
|
+
warn("poll threw", err);
|
|
2046
|
+
pollWarned = true;
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
} finally {
|
|
2050
|
+
pollInFlight = false;
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
var leadConnectorBridge = {
|
|
2054
|
+
vendor: "leadconnector",
|
|
2055
|
+
configure(c) {
|
|
2056
|
+
cfg = c;
|
|
2057
|
+
locationIdCache = void 0;
|
|
2058
|
+
},
|
|
2059
|
+
detect: () => Boolean(cfg?.widgetId),
|
|
2060
|
+
hideNative: () => {
|
|
2061
|
+
try {
|
|
2062
|
+
window.leadConnector?.chatWidget?.closeWidget?.();
|
|
2063
|
+
} catch (err) {
|
|
2064
|
+
warn("closeWidget failed", err);
|
|
2065
|
+
}
|
|
2066
|
+
},
|
|
2067
|
+
setVisitorEmail: (email) => {
|
|
2068
|
+
const trimmed = email.trim();
|
|
2069
|
+
if (!trimmed) return;
|
|
2070
|
+
void send(`[Visitor email: ${trimmed}]`);
|
|
2071
|
+
},
|
|
2072
|
+
sendMessage: (text) => send(text),
|
|
2073
|
+
onOperatorReply: (cb) => {
|
|
2074
|
+
let active = true;
|
|
2075
|
+
pollWarned = false;
|
|
2076
|
+
const isActive = () => active;
|
|
2077
|
+
const tick = async () => {
|
|
2078
|
+
if (!active) return;
|
|
2079
|
+
await pollOnce(cb, isActive);
|
|
2080
|
+
};
|
|
2081
|
+
const timer = setInterval(() => void tick(), LC_POLL_MS);
|
|
2082
|
+
return () => {
|
|
2083
|
+
active = false;
|
|
2084
|
+
clearInterval(timer);
|
|
2085
|
+
};
|
|
2086
|
+
}
|
|
2087
|
+
};
|
|
2088
|
+
function registerLeadConnectorBridge() {
|
|
2089
|
+
registerSupportChatBridge(leadConnectorBridge);
|
|
2090
|
+
}
|
|
2091
|
+
registerLeadConnectorBridge();
|
|
2092
|
+
|
|
1851
2093
|
// src/support-chat/boot.ts
|
|
1852
|
-
function bootSupportChat(
|
|
1853
|
-
if (!
|
|
2094
|
+
function bootSupportChat(cfg2) {
|
|
2095
|
+
if (!cfg2?.vendor) return void 0;
|
|
1854
2096
|
registerCrispBridge();
|
|
1855
|
-
|
|
2097
|
+
registerLeadConnectorBridge();
|
|
2098
|
+
if (cfg2.vendor === "leadconnector") {
|
|
2099
|
+
if (!cfg2.widgetId) {
|
|
2100
|
+
console.warn(
|
|
2101
|
+
"supportChat.bridge: leadconnector needs supportChat.widgetId \u2014 handoff disabled"
|
|
2102
|
+
);
|
|
2103
|
+
return void 0;
|
|
2104
|
+
}
|
|
2105
|
+
leadConnectorBridge.configure({ widgetId: cfg2.widgetId });
|
|
2106
|
+
}
|
|
2107
|
+
const bridge = getSupportChatBridge(cfg2.vendor);
|
|
1856
2108
|
if (!bridge || !bridge.detect()) {
|
|
1857
2109
|
console.warn(
|
|
1858
|
-
`supportChat.bridge: vendor '${
|
|
2110
|
+
`supportChat.bridge: vendor '${cfg2.vendor}' not detected on this page \u2014 handoff disabled`
|
|
1859
2111
|
);
|
|
1860
2112
|
return void 0;
|
|
1861
2113
|
}
|
|
1862
|
-
if (
|
|
2114
|
+
if (cfg2.suppressNative) bridge.hideNative();
|
|
1863
2115
|
return bridge;
|
|
1864
2116
|
}
|
|
1865
2117
|
|
|
@@ -1871,16 +2123,16 @@ function getState(container) {
|
|
|
1871
2123
|
function setState(container, state) {
|
|
1872
2124
|
container[STATE_KEY] = state;
|
|
1873
2125
|
}
|
|
1874
|
-
function applyPlaceholder(bar,
|
|
1875
|
-
if (
|
|
1876
|
-
if (
|
|
1877
|
-
if (
|
|
1878
|
-
if (
|
|
1879
|
-
if (
|
|
1880
|
-
bar.introSuggestion =
|
|
1881
|
-
bar.forceExpanded =
|
|
1882
|
-
if (typeof
|
|
1883
|
-
bar.maximized =
|
|
2126
|
+
function applyPlaceholder(bar, cfg2) {
|
|
2127
|
+
if (cfg2.placeholder !== void 0) bar.placeholder = cfg2.placeholder;
|
|
2128
|
+
if (cfg2.assistantName !== void 0) bar.assistantName = cfg2.assistantName;
|
|
2129
|
+
if (cfg2.personas !== void 0) bar.personas = cfg2.personas;
|
|
2130
|
+
if (cfg2.greeting !== void 0) bar.greeting = cfg2.greeting;
|
|
2131
|
+
if (cfg2.voiceInput !== void 0) bar.voiceInput = cfg2.voiceInput;
|
|
2132
|
+
bar.introSuggestion = cfg2.introSuggestion;
|
|
2133
|
+
bar.forceExpanded = cfg2.forceExpanded === true;
|
|
2134
|
+
if (typeof cfg2.maximized === "boolean") {
|
|
2135
|
+
bar.maximized = cfg2.maximized;
|
|
1884
2136
|
}
|
|
1885
2137
|
}
|
|
1886
2138
|
var _elementStore = null;
|
|
@@ -2011,49 +2263,49 @@ function wireNudgeSurface(runtime2, backendUrl) {
|
|
|
2011
2263
|
};
|
|
2012
2264
|
document.addEventListener("syntro:nudge", _nudgeListener);
|
|
2013
2265
|
}
|
|
2014
|
-
function configureTransportIfPossible(
|
|
2015
|
-
if (!
|
|
2016
|
-
const backendUrl =
|
|
2266
|
+
function configureTransportIfPossible(cfg2) {
|
|
2267
|
+
if (!cfg2.runtime) return;
|
|
2268
|
+
const backendUrl = cfg2.runtime.backendUrl;
|
|
2017
2269
|
if (!backendUrl) return;
|
|
2018
|
-
const elementsActive =
|
|
2019
|
-
refreshTemplateWidgetMap(elementsActive ?
|
|
2020
|
-
const forwardedProps = elementsActive ? { elementsEnabled: true, uiTemplates:
|
|
2021
|
-
if (elementsActive) publishTemplatesIfPossible(backendUrl,
|
|
2022
|
-
const runtime2 =
|
|
2270
|
+
const elementsActive = cfg2.elementsEnabled === true && cfg2.uiTemplates != null;
|
|
2271
|
+
refreshTemplateWidgetMap(elementsActive ? cfg2.uiTemplates : void 0);
|
|
2272
|
+
const forwardedProps = elementsActive ? { elementsEnabled: true, uiTemplates: cfg2.uiTemplates } : void 0;
|
|
2273
|
+
if (elementsActive) publishTemplatesIfPossible(backendUrl, cfg2.uiTemplates, cfg2.runtime?.token);
|
|
2274
|
+
const runtime2 = cfg2.runtime;
|
|
2023
2275
|
const onElementMutation = elementsActive ? (mutations) => {
|
|
2024
2276
|
void getOrCreateElementStore(runtime2).apply(mutations);
|
|
2025
2277
|
} : void 0;
|
|
2026
2278
|
if (elementsActive) {
|
|
2027
2279
|
hydrateOnce(runtime2, backendUrl);
|
|
2028
2280
|
}
|
|
2029
|
-
const persona = pickPersona(
|
|
2281
|
+
const persona = pickPersona(cfg2.personas ?? null);
|
|
2030
2282
|
chatTransport.configure({
|
|
2031
|
-
...
|
|
2283
|
+
...cfg2,
|
|
2032
2284
|
backendUrl,
|
|
2033
2285
|
forwardedProps,
|
|
2034
2286
|
onElementMutation,
|
|
2035
|
-
activeLidSlot:
|
|
2287
|
+
activeLidSlot: cfg2._syntroSlotName,
|
|
2036
2288
|
personaId: persona?.id,
|
|
2037
2289
|
personaName: persona?.name,
|
|
2038
2290
|
personaRole: persona?.role_title
|
|
2039
2291
|
});
|
|
2040
2292
|
void chatTransport.startSessionStream();
|
|
2041
2293
|
wireNudgeSurface(runtime2, backendUrl);
|
|
2042
|
-
startObserverIfPossible(
|
|
2294
|
+
startObserverIfPossible(cfg2);
|
|
2043
2295
|
}
|
|
2044
2296
|
var _templatesPublished = false;
|
|
2045
2297
|
function publishTemplatesIfPossible(backendUrl, uiTemplates, token) {
|
|
2046
2298
|
if (_templatesPublished || typeof window === "undefined") return;
|
|
2047
2299
|
if (!uiTemplates || typeof uiTemplates !== "object") return;
|
|
2048
2300
|
_templatesPublished = true;
|
|
2049
|
-
const
|
|
2050
|
-
if (token)
|
|
2301
|
+
const headers2 = { "Content-Type": "application/json" };
|
|
2302
|
+
if (token) headers2.Authorization = `Bearer ${token}`;
|
|
2051
2303
|
const editorToken = readEditorToken();
|
|
2052
|
-
if (editorToken)
|
|
2304
|
+
if (editorToken) headers2["X-Syntro-Editor-Token"] = editorToken;
|
|
2053
2305
|
const trimmed = backendUrl.replace(/\/$/, "");
|
|
2054
2306
|
void fetch(`${trimmed}/api/adaptive/templates`, {
|
|
2055
2307
|
method: "POST",
|
|
2056
|
-
headers,
|
|
2308
|
+
headers: headers2,
|
|
2057
2309
|
credentials: "include",
|
|
2058
2310
|
body: JSON.stringify({ ui_templates: uiTemplates })
|
|
2059
2311
|
}).catch(() => {
|
|
@@ -2080,9 +2332,9 @@ var _observerStarted = false;
|
|
|
2080
2332
|
var _observerRuntime = null;
|
|
2081
2333
|
var _observerHandle = null;
|
|
2082
2334
|
var _observerBusUnsubscribe = null;
|
|
2083
|
-
function startObserverIfPossible(
|
|
2335
|
+
function startObserverIfPossible(cfg2) {
|
|
2084
2336
|
if (typeof window === "undefined") return;
|
|
2085
|
-
const runtimeRef =
|
|
2337
|
+
const runtimeRef = cfg2.runtime;
|
|
2086
2338
|
if (!runtimeRef?.events?.subscribe) return;
|
|
2087
2339
|
if (_observerStarted && _observerRuntime === runtimeRef) return;
|
|
2088
2340
|
if (_observerStarted) {
|
|
@@ -2151,13 +2403,13 @@ function wireListeners(bar, state) {
|
|
|
2151
2403
|
}
|
|
2152
2404
|
var AdaptiveChatBarMountable = {
|
|
2153
2405
|
mount(container, mountConfig) {
|
|
2154
|
-
const
|
|
2155
|
-
configureTransportIfPossible(
|
|
2156
|
-
bootSupportChat(
|
|
2406
|
+
const cfg2 = mountConfig ?? {};
|
|
2407
|
+
configureTransportIfPossible(cfg2);
|
|
2408
|
+
bootSupportChat(cfg2.supportChat);
|
|
2157
2409
|
wireDiveDeeperListener();
|
|
2158
2410
|
const bar = document.createElement("adaptive-chat-bar");
|
|
2159
|
-
applyPlaceholder(bar,
|
|
2160
|
-
const widgets =
|
|
2411
|
+
applyPlaceholder(bar, cfg2);
|
|
2412
|
+
const widgets = cfg2.runtime?.widgets;
|
|
2161
2413
|
if (widgets) {
|
|
2162
2414
|
bar.mountInlineWidget = (widgetId, container2, props) => {
|
|
2163
2415
|
if (!widgets.has(widgetId)) return null;
|
|
@@ -2175,7 +2427,7 @@ var AdaptiveChatBarMountable = {
|
|
|
2175
2427
|
bar.inFlight = s.inFlight;
|
|
2176
2428
|
bar.thinkingText = s.thinkingText;
|
|
2177
2429
|
});
|
|
2178
|
-
const runtimeEvents =
|
|
2430
|
+
const runtimeEvents = cfg2.runtime ? cfg2.runtime.events : void 0;
|
|
2179
2431
|
const refreshReceipts = () => {
|
|
2180
2432
|
const store = _elementStore;
|
|
2181
2433
|
if (store) {
|
|
@@ -2192,7 +2444,7 @@ var AdaptiveChatBarMountable = {
|
|
|
2192
2444
|
}
|
|
2193
2445
|
refreshReceipts();
|
|
2194
2446
|
const state = { bar, cleanup: () => {
|
|
2195
|
-
}, cfg };
|
|
2447
|
+
}, cfg: cfg2 };
|
|
2196
2448
|
const unwireListeners = wireListeners(bar, state);
|
|
2197
2449
|
container.appendChild(bar);
|
|
2198
2450
|
const unsubFallback = chatTransport.onFallback(() => {
|
|
@@ -2213,10 +2465,10 @@ var AdaptiveChatBarMountable = {
|
|
|
2213
2465
|
update(container, mountConfig) {
|
|
2214
2466
|
const state = getState(container);
|
|
2215
2467
|
if (!state) return;
|
|
2216
|
-
const
|
|
2217
|
-
configureTransportIfPossible(
|
|
2218
|
-
applyPlaceholder(state.bar,
|
|
2219
|
-
state.cfg =
|
|
2468
|
+
const cfg2 = mountConfig ?? {};
|
|
2469
|
+
configureTransportIfPossible(cfg2);
|
|
2470
|
+
applyPlaceholder(state.bar, cfg2);
|
|
2471
|
+
state.cfg = cfg2;
|
|
2220
2472
|
}
|
|
2221
2473
|
};
|
|
2222
2474
|
|
|
@@ -2228,23 +2480,23 @@ function getState2(container) {
|
|
|
2228
2480
|
function setState2(container, state) {
|
|
2229
2481
|
container[STATE_KEY2] = state;
|
|
2230
2482
|
}
|
|
2231
|
-
function applyProps(strip,
|
|
2232
|
-
if (
|
|
2233
|
-
if (
|
|
2234
|
-
strip.runtimeRef =
|
|
2483
|
+
function applyProps(strip, cfg2) {
|
|
2484
|
+
if (cfg2.chips !== void 0) strip.chips = cfg2.chips;
|
|
2485
|
+
if (cfg2.runtime !== void 0) {
|
|
2486
|
+
strip.runtimeRef = cfg2.runtime;
|
|
2235
2487
|
}
|
|
2236
|
-
if (
|
|
2488
|
+
if (cfg2.chromeless !== void 0) strip.chromeless = cfg2.chromeless;
|
|
2237
2489
|
}
|
|
2238
2490
|
var AdaptiveChipsStripMountable = {
|
|
2239
2491
|
mount(container, mountConfig) {
|
|
2240
|
-
const
|
|
2492
|
+
const cfg2 = mountConfig ?? {};
|
|
2241
2493
|
const strip = document.createElement("adaptive-chips-strip");
|
|
2242
|
-
applyProps(strip,
|
|
2494
|
+
applyProps(strip, cfg2);
|
|
2243
2495
|
const state = {
|
|
2244
2496
|
strip,
|
|
2245
2497
|
listeners: {
|
|
2246
2498
|
revealed: (e) => {
|
|
2247
|
-
const cb =
|
|
2499
|
+
const cb = cfg2.onChipRevealed;
|
|
2248
2500
|
if (cb) {
|
|
2249
2501
|
cb(
|
|
2250
2502
|
e.detail
|
|
@@ -2252,7 +2504,7 @@ var AdaptiveChipsStripMountable = {
|
|
|
2252
2504
|
}
|
|
2253
2505
|
},
|
|
2254
2506
|
dismissed: (e) => {
|
|
2255
|
-
const cb =
|
|
2507
|
+
const cb = cfg2.onChipDismissed;
|
|
2256
2508
|
if (cb) cb(e.detail);
|
|
2257
2509
|
}
|
|
2258
2510
|
}
|
|
@@ -2271,18 +2523,18 @@ var AdaptiveChipsStripMountable = {
|
|
|
2271
2523
|
update(container, mountConfig) {
|
|
2272
2524
|
const state = getState2(container);
|
|
2273
2525
|
if (!state) return;
|
|
2274
|
-
const
|
|
2275
|
-
applyProps(state.strip,
|
|
2526
|
+
const cfg2 = mountConfig ?? {};
|
|
2527
|
+
applyProps(state.strip, cfg2);
|
|
2276
2528
|
state.strip.removeEventListener("chip-revealed", state.listeners.revealed);
|
|
2277
2529
|
state.strip.removeEventListener("chip-dismissed", state.listeners.dismissed);
|
|
2278
2530
|
state.listeners.revealed = (e) => {
|
|
2279
|
-
const cb =
|
|
2531
|
+
const cb = cfg2.onChipRevealed;
|
|
2280
2532
|
if (cb) {
|
|
2281
2533
|
cb(e.detail);
|
|
2282
2534
|
}
|
|
2283
2535
|
};
|
|
2284
2536
|
state.listeners.dismissed = (e) => {
|
|
2285
|
-
const cb =
|
|
2537
|
+
const cb = cfg2.onChipDismissed;
|
|
2286
2538
|
if (cb) cb(e.detail);
|
|
2287
2539
|
};
|
|
2288
2540
|
state.strip.addEventListener("chip-revealed", state.listeners.revealed);
|
|
@@ -2811,7 +3063,7 @@ function navigateTo(rawUrl) {
|
|
|
2811
3063
|
window.history.pushState(null, "", resolved.toString());
|
|
2812
3064
|
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
2813
3065
|
}
|
|
2814
|
-
function buildButton(
|
|
3066
|
+
function buildButton(cfg2) {
|
|
2815
3067
|
const button = document.createElement("button");
|
|
2816
3068
|
button.type = "button";
|
|
2817
3069
|
button.dataset.syntroNavLink = "";
|
|
@@ -2827,26 +3079,26 @@ function buildButton(cfg) {
|
|
|
2827
3079
|
button.style.color = "var(--sc-accent-foreground, currentColor)";
|
|
2828
3080
|
button.style.background = "hsl(var(--sc-accent-color) / 0.85)";
|
|
2829
3081
|
button.style.border = "1px solid hsl(var(--sc-accent-color) / 0.30)";
|
|
2830
|
-
applyLabel(button,
|
|
3082
|
+
applyLabel(button, cfg2);
|
|
2831
3083
|
return button;
|
|
2832
3084
|
}
|
|
2833
|
-
function applyLabel(button,
|
|
2834
|
-
const url = String(
|
|
2835
|
-
const label =
|
|
3085
|
+
function applyLabel(button, cfg2) {
|
|
3086
|
+
const url = String(cfg2.url ?? "");
|
|
3087
|
+
const label = cfg2.label ?? (url ? `Go to ${url}` : "Go");
|
|
2836
3088
|
button.textContent = label;
|
|
2837
3089
|
}
|
|
2838
3090
|
var NavLinkMountable = {
|
|
2839
3091
|
mount(container, mountConfig) {
|
|
2840
|
-
const
|
|
2841
|
-
const button = buildButton(
|
|
3092
|
+
const cfg2 = mountConfig ?? {};
|
|
3093
|
+
const button = buildButton(cfg2);
|
|
2842
3094
|
const onClick = (_e) => {
|
|
2843
3095
|
const current = getState3(container);
|
|
2844
|
-
const url = current?.cfg.url ??
|
|
3096
|
+
const url = current?.cfg.url ?? cfg2.url;
|
|
2845
3097
|
navigateTo(String(url ?? ""));
|
|
2846
3098
|
};
|
|
2847
3099
|
button.addEventListener("click", onClick);
|
|
2848
3100
|
container.appendChild(button);
|
|
2849
|
-
setState3(container, { button, cfg, onClick });
|
|
3101
|
+
setState3(container, { button, cfg: cfg2, onClick });
|
|
2850
3102
|
return () => {
|
|
2851
3103
|
button.removeEventListener("click", onClick);
|
|
2852
3104
|
button.remove();
|
|
@@ -2856,9 +3108,9 @@ var NavLinkMountable = {
|
|
|
2856
3108
|
update(container, mountConfig) {
|
|
2857
3109
|
const state = getState3(container);
|
|
2858
3110
|
if (!state) return;
|
|
2859
|
-
const
|
|
2860
|
-
applyLabel(state.button,
|
|
2861
|
-
state.cfg =
|
|
3111
|
+
const cfg2 = mountConfig ?? {};
|
|
3112
|
+
applyLabel(state.button, cfg2);
|
|
3113
|
+
state.cfg = cfg2;
|
|
2862
3114
|
}
|
|
2863
3115
|
};
|
|
2864
3116
|
|
|
@@ -2875,16 +3127,16 @@ function applyText(p, text) {
|
|
|
2875
3127
|
}
|
|
2876
3128
|
var TextAnswerMountable = {
|
|
2877
3129
|
mount(container, mountConfig) {
|
|
2878
|
-
const
|
|
3130
|
+
const cfg2 = mountConfig ?? {};
|
|
2879
3131
|
const paragraph = document.createElement("p");
|
|
2880
3132
|
paragraph.dataset.syntroTextAnswer = "";
|
|
2881
3133
|
paragraph.style.margin = "0";
|
|
2882
3134
|
paragraph.style.fontSize = "12px";
|
|
2883
3135
|
paragraph.style.lineHeight = "1.55";
|
|
2884
3136
|
paragraph.style.color = "var(--sc-tile-text-color, currentColor)";
|
|
2885
|
-
applyText(paragraph, String(
|
|
3137
|
+
applyText(paragraph, String(cfg2.text ?? ""));
|
|
2886
3138
|
container.appendChild(paragraph);
|
|
2887
|
-
setState4(container, { paragraph, cfg });
|
|
3139
|
+
setState4(container, { paragraph, cfg: cfg2 });
|
|
2888
3140
|
return () => {
|
|
2889
3141
|
paragraph.remove();
|
|
2890
3142
|
setState4(container, null);
|
|
@@ -2893,9 +3145,9 @@ var TextAnswerMountable = {
|
|
|
2893
3145
|
update(container, mountConfig) {
|
|
2894
3146
|
const state = getState4(container);
|
|
2895
3147
|
if (!state) return;
|
|
2896
|
-
const
|
|
2897
|
-
applyText(state.paragraph, String(
|
|
2898
|
-
state.cfg =
|
|
3148
|
+
const cfg2 = mountConfig ?? {};
|
|
3149
|
+
applyText(state.paragraph, String(cfg2.text ?? ""));
|
|
3150
|
+
state.cfg = cfg2;
|
|
2899
3151
|
}
|
|
2900
3152
|
};
|
|
2901
3153
|
|