@helpai/elements 0.29.0 → 0.29.1
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/elements-web-component.esm.js +16 -16
- package/elements-web-component.esm.js.map +4 -4
- package/elements.cjs.js +3 -3
- package/elements.cjs.js.map +3 -3
- package/elements.esm.js +3 -3
- package/elements.esm.js.map +3 -3
- package/elements.js +17 -17
- package/elements.js.map +3 -3
- package/index.mjs +4 -2
- package/package.json +1 -1
- package/web-component.mjs +138 -1
package/index.mjs
CHANGED
|
@@ -6225,7 +6225,7 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
|
|
|
6225
6225
|
return /* @__PURE__ */ jsxs28("article", { class: `${p29}-content`, "data-testid": TID.contentView, children: [
|
|
6226
6226
|
item.image ? /* @__PURE__ */ jsx33("img", { class: `${p29}-content-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
|
|
6227
6227
|
item.description ? /* @__PURE__ */ jsx33("p", { class: `${p29}-content-subtitle`, children: item.description }) : null,
|
|
6228
|
-
item.tags
|
|
6228
|
+
item.tags?.length ? /* @__PURE__ */ jsx33("span", { class: `${p29}-news-tags`, children: item.tags.map((t) => /* @__PURE__ */ jsx33("span", { class: `${p29}-news-tag`, children: t }, t)) }) : null,
|
|
6229
6229
|
/* @__PURE__ */ jsx33(StaticMarkdown, { text: item.content ?? "" })
|
|
6230
6230
|
] });
|
|
6231
6231
|
}
|
|
@@ -7606,7 +7606,9 @@ function createTracker(bus, deps) {
|
|
|
7606
7606
|
if (url.length > MAX_URL_LENGTH) return;
|
|
7607
7607
|
const img = new Image(1, 1);
|
|
7608
7608
|
inflight.add(img);
|
|
7609
|
-
|
|
7609
|
+
const settle = () => inflight.delete(img);
|
|
7610
|
+
img.addEventListener("load", settle, { once: true });
|
|
7611
|
+
img.addEventListener("error", settle, { once: true });
|
|
7610
7612
|
img.src = url;
|
|
7611
7613
|
};
|
|
7612
7614
|
const offs = Object.keys(TRACKED).map(
|
package/package.json
CHANGED
package/web-component.mjs
CHANGED
|
@@ -6280,7 +6280,7 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
|
|
|
6280
6280
|
return /* @__PURE__ */ jsxs28("article", { class: `${p29}-content`, "data-testid": TID.contentView, children: [
|
|
6281
6281
|
item.image ? /* @__PURE__ */ jsx33("img", { class: `${p29}-content-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
|
|
6282
6282
|
item.description ? /* @__PURE__ */ jsx33("p", { class: `${p29}-content-subtitle`, children: item.description }) : null,
|
|
6283
|
-
item.tags
|
|
6283
|
+
item.tags?.length ? /* @__PURE__ */ jsx33("span", { class: `${p29}-news-tags`, children: item.tags.map((t) => /* @__PURE__ */ jsx33("span", { class: `${p29}-news-tag`, children: t }, t)) }) : null,
|
|
6284
6284
|
/* @__PURE__ */ jsx33(StaticMarkdown, { text: item.content ?? "" })
|
|
6285
6285
|
] });
|
|
6286
6286
|
}
|
|
@@ -7494,6 +7494,121 @@ var EventBus = class {
|
|
|
7494
7494
|
}
|
|
7495
7495
|
};
|
|
7496
7496
|
|
|
7497
|
+
// src/core/tracking.ts
|
|
7498
|
+
var PROTOCOL_VERSION = "1";
|
|
7499
|
+
var MAX_HITS_PER_MINUTE = 60;
|
|
7500
|
+
var MAX_URL_LENGTH = 2e3;
|
|
7501
|
+
var TRACKED = {
|
|
7502
|
+
// Panel lifecycle — the owner's "is the widget used at all" funnel.
|
|
7503
|
+
open: () => void 0,
|
|
7504
|
+
close: () => void 0,
|
|
7505
|
+
expand: (on) => ({ on }),
|
|
7506
|
+
fullscreen: (on) => ({ on }),
|
|
7507
|
+
popOut: () => void 0,
|
|
7508
|
+
// Conversation funnel. `send` is the key conversion; text never rides.
|
|
7509
|
+
send: (p33) => ({ attachments: p33.attachmentCount }),
|
|
7510
|
+
message: (p33) => ({ role: p33.role }),
|
|
7511
|
+
stop: () => void 0,
|
|
7512
|
+
clear: () => void 0,
|
|
7513
|
+
suggestion: () => void 0,
|
|
7514
|
+
toggleHistory: (p33) => ({ view: p33.view }),
|
|
7515
|
+
handshake: () => void 0,
|
|
7516
|
+
// Forms + human-in-the-loop — ids and outcomes, never values.
|
|
7517
|
+
formSubmit: (p33) => ({ formId: p33.formId, skipped: p33.skipped }),
|
|
7518
|
+
toolResult: () => void 0,
|
|
7519
|
+
toolDecision: (p33) => ({ approved: p33.approved }),
|
|
7520
|
+
// Composer / attachments / voice.
|
|
7521
|
+
attach: (p33) => ({ count: p33.count, bytes: p33.totalBytes }),
|
|
7522
|
+
voiceStart: () => void 0,
|
|
7523
|
+
voiceStop: (p33) => ({ ms: p33.durationMs }),
|
|
7524
|
+
voiceCancel: () => void 0,
|
|
7525
|
+
// Preferences — how visitors tune the surface.
|
|
7526
|
+
localeChange: (locale) => ({ locale }),
|
|
7527
|
+
themeChange: (theme) => ({ theme }),
|
|
7528
|
+
textSizeChange: (size) => ({ size }),
|
|
7529
|
+
soundToggle: (p33) => ({ muted: p33.muted }),
|
|
7530
|
+
sidebarToggle: (p33) => ({ collapsed: p33.collapsed }),
|
|
7531
|
+
calloutDismiss: () => void 0,
|
|
7532
|
+
// Health signal only — the error object itself never leaves the page.
|
|
7533
|
+
error: () => void 0
|
|
7534
|
+
};
|
|
7535
|
+
function privacySignalsOff() {
|
|
7536
|
+
const nav = navigator;
|
|
7537
|
+
return nav.globalPrivacyControl === true || nav.doNotTrack === "1";
|
|
7538
|
+
}
|
|
7539
|
+
function pageUrl() {
|
|
7540
|
+
return location.origin + location.pathname;
|
|
7541
|
+
}
|
|
7542
|
+
function referrerOrigin() {
|
|
7543
|
+
try {
|
|
7544
|
+
return document.referrer ? new URL(document.referrer).origin : "";
|
|
7545
|
+
} catch {
|
|
7546
|
+
return "";
|
|
7547
|
+
}
|
|
7548
|
+
}
|
|
7549
|
+
function createTracker(bus, deps) {
|
|
7550
|
+
const sampleRoll = Math.random();
|
|
7551
|
+
let windowStart = 0;
|
|
7552
|
+
let windowHits = 0;
|
|
7553
|
+
const inflight = /* @__PURE__ */ new Set();
|
|
7554
|
+
const hit = (event, dims) => {
|
|
7555
|
+
const { tracking, publicKey, aiAgentDeploymentId, mode, themeMode } = deps.getOptions();
|
|
7556
|
+
if (!tracking.enabled || privacySignalsOff()) return;
|
|
7557
|
+
if (sampleRoll >= tracking.sampleRate) return;
|
|
7558
|
+
const now = performance.now();
|
|
7559
|
+
if (now - windowStart > 6e4) {
|
|
7560
|
+
windowStart = now;
|
|
7561
|
+
windowHits = 0;
|
|
7562
|
+
}
|
|
7563
|
+
if (++windowHits > MAX_HITS_PER_MINUTE) return;
|
|
7564
|
+
const params = new URLSearchParams();
|
|
7565
|
+
params.set("v", PROTOCOL_VERSION);
|
|
7566
|
+
params.set("e", event);
|
|
7567
|
+
if (tracking.token) params.set("tk", tracking.token);
|
|
7568
|
+
if (publicKey) params.set("pk", publicKey);
|
|
7569
|
+
if (aiAgentDeploymentId) params.set("dep", aiAgentDeploymentId);
|
|
7570
|
+
params.set("vid", deps.getVisitorId());
|
|
7571
|
+
const cid = deps.getConversationId();
|
|
7572
|
+
if (cid) params.set("cid", cid);
|
|
7573
|
+
params.set("url", pageUrl());
|
|
7574
|
+
const ref = referrerOrigin();
|
|
7575
|
+
if (ref) params.set("ref", ref);
|
|
7576
|
+
params.set("sw", String(screen.width));
|
|
7577
|
+
params.set("sh", String(screen.height));
|
|
7578
|
+
params.set("vw", String(innerWidth));
|
|
7579
|
+
params.set("vh", String(innerHeight));
|
|
7580
|
+
params.set("dpr", String(devicePixelRatio));
|
|
7581
|
+
params.set("lang", navigator.language);
|
|
7582
|
+
try {
|
|
7583
|
+
params.set("tz", Intl.DateTimeFormat().resolvedOptions().timeZone);
|
|
7584
|
+
} catch {
|
|
7585
|
+
}
|
|
7586
|
+
params.set("m", mode);
|
|
7587
|
+
params.set("th", themeMode);
|
|
7588
|
+
if (dims) {
|
|
7589
|
+
for (const [k, val] of Object.entries(dims)) {
|
|
7590
|
+
if (val !== void 0) params.set(k, String(val));
|
|
7591
|
+
}
|
|
7592
|
+
}
|
|
7593
|
+
params.set("ts", String(Date.now()));
|
|
7594
|
+
const url = `${tracking.endpoint}?${params}`;
|
|
7595
|
+
if (url.length > MAX_URL_LENGTH) return;
|
|
7596
|
+
const img = new Image(1, 1);
|
|
7597
|
+
inflight.add(img);
|
|
7598
|
+
const settle = () => inflight.delete(img);
|
|
7599
|
+
img.addEventListener("load", settle, { once: true });
|
|
7600
|
+
img.addEventListener("error", settle, { once: true });
|
|
7601
|
+
img.src = url;
|
|
7602
|
+
};
|
|
7603
|
+
const offs = Object.keys(TRACKED).map(
|
|
7604
|
+
(event) => bus.on(event, (payload) => hit(event, TRACKED[event]?.(payload)))
|
|
7605
|
+
);
|
|
7606
|
+
return () => {
|
|
7607
|
+
for (const off of offs) off();
|
|
7608
|
+
inflight.clear();
|
|
7609
|
+
};
|
|
7610
|
+
}
|
|
7611
|
+
|
|
7497
7612
|
// src/core/hooks.ts
|
|
7498
7613
|
var log19 = logger.scope("hooks");
|
|
7499
7614
|
|
|
@@ -7527,6 +7642,19 @@ var ChatElement = class extends HTMLElement {
|
|
|
7527
7642
|
* same user-wins-per-field merge policy.
|
|
7528
7643
|
*/
|
|
7529
7644
|
__publicField(this, "rawOptions", {});
|
|
7645
|
+
/**
|
|
7646
|
+
* Latest resolved options — refreshed every `renderApp()` so the usage
|
|
7647
|
+
* tracker (created once in `boot`) reads live, post-handshake-merge
|
|
7648
|
+
* values (`tracking.enabled` / `endpoint` / `token`).
|
|
7649
|
+
*
|
|
7650
|
+
* This path is independent of `mount()` (it supports N elements per page
|
|
7651
|
+
* without a shared `widgetId` registry), so anything `mount()` wires onto
|
|
7652
|
+
* the bus must be wired here too — the tracker is the current example;
|
|
7653
|
+
* keep them in lockstep.
|
|
7654
|
+
*/
|
|
7655
|
+
__publicField(this, "resolved", null);
|
|
7656
|
+
/** Tracker unsubscribe — released on disconnect. */
|
|
7657
|
+
__publicField(this, "untrack", null);
|
|
7530
7658
|
}
|
|
7531
7659
|
static get observedAttributes() {
|
|
7532
7660
|
return REACTIVE_ATTRS;
|
|
@@ -7536,6 +7664,8 @@ var ChatElement = class extends HTMLElement {
|
|
|
7536
7664
|
}
|
|
7537
7665
|
disconnectedCallback() {
|
|
7538
7666
|
if (!this.mountResult) return;
|
|
7667
|
+
this.untrack?.();
|
|
7668
|
+
this.untrack = null;
|
|
7539
7669
|
render2(null, this.mountResult.appRoot);
|
|
7540
7670
|
this.bus.clear();
|
|
7541
7671
|
}
|
|
@@ -7555,6 +7685,12 @@ var ChatElement = class extends HTMLElement {
|
|
|
7555
7685
|
this.rawOptions = mergeServerConfig(this.rawOptions, response.config);
|
|
7556
7686
|
this.renderApp();
|
|
7557
7687
|
});
|
|
7688
|
+
const persistence = createPersistence(resolved.widgetId, resolved.storage);
|
|
7689
|
+
this.untrack = createTracker(this.bus, {
|
|
7690
|
+
getOptions: () => this.resolved ?? resolved,
|
|
7691
|
+
getVisitorId: () => persistence.getVisitorId(),
|
|
7692
|
+
getConversationId: () => persistence.loadConversationId()
|
|
7693
|
+
});
|
|
7558
7694
|
}
|
|
7559
7695
|
this.renderApp();
|
|
7560
7696
|
}
|
|
@@ -7565,6 +7701,7 @@ var ChatElement = class extends HTMLElement {
|
|
|
7565
7701
|
renderApp() {
|
|
7566
7702
|
if (!this.mountResult) return;
|
|
7567
7703
|
const resolved = resolveOptions(this.rawOptions);
|
|
7704
|
+
this.resolved = resolved;
|
|
7568
7705
|
const host = this.mountResult.hostElement;
|
|
7569
7706
|
applyHostPosition(host, hostPositionForMode(resolved.mode));
|
|
7570
7707
|
const cachedThemeMode = createPersistence(resolved.widgetId, resolved.storage).loadUserPrefs().themeMode;
|