@helpai/elements 0.29.0 → 0.30.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/elements-web-component.esm.js +24 -24
- package/elements-web-component.esm.js.map +4 -4
- package/elements.cjs.js +24 -24
- package/elements.cjs.js.map +3 -3
- package/elements.esm.js +24 -24
- package/elements.esm.js.map +3 -3
- package/elements.js +24 -24
- package/elements.js.map +3 -3
- package/index.d.ts +13 -5
- package/index.mjs +59 -10
- package/package.json +1 -1
- package/schema.d.ts +49 -49
- package/web-component.mjs +222 -13
package/web-component.mjs
CHANGED
|
@@ -509,8 +509,9 @@ function resolveOptions(rawOpts) {
|
|
|
509
509
|
const header = opts.header ?? {};
|
|
510
510
|
const { themeMode, themeOverrides } = parseTheme(opts.theme);
|
|
511
511
|
const mode = presentation.mode ?? "floating";
|
|
512
|
-
const
|
|
513
|
-
const availableLocales = i18n.availableLocales ?? [locale];
|
|
512
|
+
const defaultLocale = resolveDefaultLocale(i18n.defaultLocale);
|
|
513
|
+
const availableLocales = i18n.availableLocales ?? [i18n.locale ?? defaultLocale];
|
|
514
|
+
const locale = clampLocale(i18n.locale ?? defaultLocale, availableLocales, defaultLocale);
|
|
514
515
|
const baseUrl = (opts.baseUrl ?? BRAND.defaultBaseUrl).replace(/\/$/, "");
|
|
515
516
|
const agentApiBaseUrl = (opts.agentApiBaseUrl ?? `${baseUrl}/api/agent`).replace(/\/$/, "");
|
|
516
517
|
const dataApiBaseUrl = (opts.dataApiBaseUrl ?? `${baseUrl}/api/data`).replace(/\/$/, "");
|
|
@@ -552,6 +553,7 @@ function resolveOptions(rawOpts) {
|
|
|
552
553
|
maxCount: opts.composer?.attachments?.maxCount ?? DEFAULT_ATTACHMENTS.maxCount
|
|
553
554
|
},
|
|
554
555
|
locale,
|
|
556
|
+
defaultLocale,
|
|
555
557
|
availableLocales,
|
|
556
558
|
startMinimized: behavior.startMinimized ?? true,
|
|
557
559
|
actions: resolveActions(mode, header.actions),
|
|
@@ -582,6 +584,11 @@ function resolveDefaultLocale(input) {
|
|
|
582
584
|
if (input && input !== "auto") return input;
|
|
583
585
|
return typeof navigator !== "undefined" && navigator.language ? navigator.language : "en";
|
|
584
586
|
}
|
|
587
|
+
function clampLocale(desired, availableLocales, defaultLocale) {
|
|
588
|
+
if (availableLocales.length <= 1 || availableLocales.includes(desired)) return desired;
|
|
589
|
+
if (availableLocales.includes(defaultLocale)) return defaultLocale;
|
|
590
|
+
return availableLocales[0] ?? desired;
|
|
591
|
+
}
|
|
585
592
|
function resolveActions(mode, overrides) {
|
|
586
593
|
return overrides ?? DEFAULT_ACTIONS_BY_MODE[mode];
|
|
587
594
|
}
|
|
@@ -730,13 +737,14 @@ function resolveLauncher(overrides) {
|
|
|
730
737
|
|
|
731
738
|
// src/core/config/overrides.ts
|
|
732
739
|
function applyOptionOverrides(options, activeLocale, activeThemeMode, activeTextSize) {
|
|
733
|
-
|
|
740
|
+
const locale = clampLocale(activeLocale, options.availableLocales, options.defaultLocale);
|
|
741
|
+
if (locale === options.locale && activeThemeMode === options.themeMode && activeTextSize === options.textSize) {
|
|
734
742
|
return options;
|
|
735
743
|
}
|
|
736
744
|
const next = { ...options };
|
|
737
|
-
if (
|
|
738
|
-
next.locale =
|
|
739
|
-
next.strings = resolveStrings(
|
|
745
|
+
if (locale !== options.locale) {
|
|
746
|
+
next.locale = locale;
|
|
747
|
+
next.strings = resolveStrings(locale, options.stringsOverride);
|
|
740
748
|
}
|
|
741
749
|
if (activeThemeMode !== options.themeMode) next.themeMode = activeThemeMode;
|
|
742
750
|
if (activeTextSize !== options.textSize) next.textSize = activeTextSize;
|
|
@@ -782,6 +790,8 @@ function mergeServerConfig(user, server) {
|
|
|
782
790
|
serverI18n ?? {},
|
|
783
791
|
userI18n
|
|
784
792
|
);
|
|
793
|
+
if (serverI18n?.availableLocales !== void 0) merged.availableLocales = serverI18n.availableLocales;
|
|
794
|
+
if (serverI18n?.defaultLocale !== void 0) merged.defaultLocale = serverI18n.defaultLocale;
|
|
785
795
|
const userStrings = userI18n?.strings;
|
|
786
796
|
const serverStrings = serverI18n?.strings;
|
|
787
797
|
if (userStrings || serverStrings) {
|
|
@@ -1477,6 +1487,12 @@ var AgentTransport = class {
|
|
|
1477
1487
|
// always sees the visitor's latest context as they navigate.
|
|
1478
1488
|
__publicField(this, "userContext");
|
|
1479
1489
|
__publicField(this, "pageContext");
|
|
1490
|
+
// Active BCP-47 locale, carried as the envelope's `locale` on EVERY request
|
|
1491
|
+
// so the backend can localize replies AND the data module can return
|
|
1492
|
+
// localized content + forms. Refreshed via `setLocale` whenever the visitor
|
|
1493
|
+
// switches (no re-handshake needed). Resolved + clamped to the deployment's
|
|
1494
|
+
// availableLocales by `resolveOptions` before it reaches here.
|
|
1495
|
+
__publicField(this, "locale");
|
|
1480
1496
|
// ---- Data API (content / forms — module-help-ai-data-api) --------------
|
|
1481
1497
|
//
|
|
1482
1498
|
// The DATA surfaces live on `dataApiBaseUrl` (default `${baseUrl}/api/data`)
|
|
@@ -1502,6 +1518,15 @@ var AgentTransport = class {
|
|
|
1502
1518
|
this.userContext = userContext;
|
|
1503
1519
|
this.pageContext = pageContext;
|
|
1504
1520
|
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Update the active locale carried on every subsequent request. Call on
|
|
1523
|
+
* mount (before the first handshake) and whenever the user picks a new
|
|
1524
|
+
* locale — the next content / forms / message request reflects it with no
|
|
1525
|
+
* extra round-trip.
|
|
1526
|
+
*/
|
|
1527
|
+
setLocale(locale) {
|
|
1528
|
+
this.locale = locale;
|
|
1529
|
+
}
|
|
1505
1530
|
/**
|
|
1506
1531
|
* Seed the visitor + conversation identity from persistence BEFORE the first
|
|
1507
1532
|
* `handshake` resolves. A mount-time `resumeStream()` runs in parallel
|
|
@@ -1518,6 +1543,7 @@ var AgentTransport = class {
|
|
|
1518
1543
|
const out = {};
|
|
1519
1544
|
if (this.visitorId) out.visitorId = this.visitorId;
|
|
1520
1545
|
if (this.conversationId) out.conversationId = this.conversationId;
|
|
1546
|
+
if (this.locale) out.locale = this.locale;
|
|
1521
1547
|
const context = encodeContext(this.userContext, this.pageContext);
|
|
1522
1548
|
if (context) out[CONTEXT_PARAM] = context;
|
|
1523
1549
|
return out;
|
|
@@ -6280,7 +6306,7 @@ function ContentView({ id, title, transport, strings, onBack, actions }) {
|
|
|
6280
6306
|
return /* @__PURE__ */ jsxs28("article", { class: `${p29}-content`, "data-testid": TID.contentView, children: [
|
|
6281
6307
|
item.image ? /* @__PURE__ */ jsx33("img", { class: `${p29}-content-hero`, src: item.image, alt: "", loading: "lazy" }) : null,
|
|
6282
6308
|
item.description ? /* @__PURE__ */ jsx33("p", { class: `${p29}-content-subtitle`, children: item.description }) : null,
|
|
6283
|
-
item.tags
|
|
6309
|
+
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
6310
|
/* @__PURE__ */ jsx33(StaticMarkdown, { text: item.content ?? "" })
|
|
6285
6311
|
] });
|
|
6286
6312
|
}
|
|
@@ -6725,7 +6751,10 @@ function App({ options, hostElement, bus }) {
|
|
|
6725
6751
|
visitorId,
|
|
6726
6752
|
conversationId,
|
|
6727
6753
|
userPrefs: persistence.loadUserPrefs(),
|
|
6728
|
-
locale
|
|
6754
|
+
// The visitor's ACTIVE locale (persisted pick, else auto-detected) —
|
|
6755
|
+
// not the config baseline — so the handshake learns what the visitor
|
|
6756
|
+
// wants. The response's availableLocales then clamps it for the rest.
|
|
6757
|
+
locale: activeLocale
|
|
6729
6758
|
});
|
|
6730
6759
|
} catch (err) {
|
|
6731
6760
|
if (isStale()) return;
|
|
@@ -6787,7 +6816,18 @@ function App({ options, hostElement, bus }) {
|
|
|
6787
6816
|
setConversationReady(true);
|
|
6788
6817
|
}
|
|
6789
6818
|
},
|
|
6790
|
-
[
|
|
6819
|
+
[
|
|
6820
|
+
transport,
|
|
6821
|
+
visitorId,
|
|
6822
|
+
persistence,
|
|
6823
|
+
options,
|
|
6824
|
+
bus,
|
|
6825
|
+
conversationIdSig,
|
|
6826
|
+
feedback,
|
|
6827
|
+
playWelcome,
|
|
6828
|
+
loadThread,
|
|
6829
|
+
activeLocale
|
|
6830
|
+
]
|
|
6791
6831
|
);
|
|
6792
6832
|
const userSig = JSON.stringify(options.userContext ?? null);
|
|
6793
6833
|
const pageSig = JSON.stringify(options.pageContext ?? null);
|
|
@@ -6796,6 +6836,13 @@ function App({ options, hostElement, bus }) {
|
|
|
6796
6836
|
const merged = Object.keys(formContext).length ? { ...formContext, ...options.userContext } : options.userContext;
|
|
6797
6837
|
transport.setContext(merged, toWirePageContext(options.pageContext));
|
|
6798
6838
|
}, [transport, userSig, pageSig, formCtxSig]);
|
|
6839
|
+
const effectiveLocale = clampLocale(activeLocale, options.availableLocales, options.defaultLocale);
|
|
6840
|
+
useEffect17(() => {
|
|
6841
|
+
transport.setLocale(effectiveLocale);
|
|
6842
|
+
}, [transport, effectiveLocale]);
|
|
6843
|
+
useEffect17(() => {
|
|
6844
|
+
if (effectiveLocale !== activeLocale) setActiveLocale(effectiveLocale);
|
|
6845
|
+
}, [effectiveLocale, activeLocale]);
|
|
6799
6846
|
const runResume = useCallback6(
|
|
6800
6847
|
async (handle) => {
|
|
6801
6848
|
let bubble = null;
|
|
@@ -7446,12 +7493,26 @@ function emitMessage(bus, options, role, text) {
|
|
|
7446
7493
|
options.onMessage?.(payload);
|
|
7447
7494
|
}
|
|
7448
7495
|
|
|
7449
|
-
// src/index.ts
|
|
7450
|
-
import { h, render } from "preact";
|
|
7451
|
-
|
|
7452
7496
|
// src/ui/error-boundary.tsx
|
|
7453
7497
|
import { Component } from "preact";
|
|
7454
7498
|
var log17 = logger.scope("error-boundary");
|
|
7499
|
+
var ErrorBoundary = class extends Component {
|
|
7500
|
+
constructor() {
|
|
7501
|
+
super(...arguments);
|
|
7502
|
+
__publicField(this, "state", { crashed: false });
|
|
7503
|
+
}
|
|
7504
|
+
componentDidCatch(error, info) {
|
|
7505
|
+
log17.error("widget render crashed", { error, componentStack: info?.componentStack });
|
|
7506
|
+
this.setState({ crashed: true });
|
|
7507
|
+
this.props.onError(error, info?.componentStack);
|
|
7508
|
+
}
|
|
7509
|
+
render() {
|
|
7510
|
+
return this.state.crashed ? this.props.fallback : this.props.children;
|
|
7511
|
+
}
|
|
7512
|
+
};
|
|
7513
|
+
|
|
7514
|
+
// src/index.ts
|
|
7515
|
+
import { h, render } from "preact";
|
|
7455
7516
|
|
|
7456
7517
|
// src/shadow/iframe-mount.ts
|
|
7457
7518
|
var log18 = logger.scope("iframe");
|
|
@@ -7494,6 +7555,121 @@ var EventBus = class {
|
|
|
7494
7555
|
}
|
|
7495
7556
|
};
|
|
7496
7557
|
|
|
7558
|
+
// src/core/tracking.ts
|
|
7559
|
+
var PROTOCOL_VERSION = "1";
|
|
7560
|
+
var MAX_HITS_PER_MINUTE = 60;
|
|
7561
|
+
var MAX_URL_LENGTH = 2e3;
|
|
7562
|
+
var TRACKED = {
|
|
7563
|
+
// Panel lifecycle — the owner's "is the widget used at all" funnel.
|
|
7564
|
+
open: () => void 0,
|
|
7565
|
+
close: () => void 0,
|
|
7566
|
+
expand: (on) => ({ on }),
|
|
7567
|
+
fullscreen: (on) => ({ on }),
|
|
7568
|
+
popOut: () => void 0,
|
|
7569
|
+
// Conversation funnel. `send` is the key conversion; text never rides.
|
|
7570
|
+
send: (p33) => ({ attachments: p33.attachmentCount }),
|
|
7571
|
+
message: (p33) => ({ role: p33.role }),
|
|
7572
|
+
stop: () => void 0,
|
|
7573
|
+
clear: () => void 0,
|
|
7574
|
+
suggestion: () => void 0,
|
|
7575
|
+
toggleHistory: (p33) => ({ view: p33.view }),
|
|
7576
|
+
handshake: () => void 0,
|
|
7577
|
+
// Forms + human-in-the-loop — ids and outcomes, never values.
|
|
7578
|
+
formSubmit: (p33) => ({ formId: p33.formId, skipped: p33.skipped }),
|
|
7579
|
+
toolResult: () => void 0,
|
|
7580
|
+
toolDecision: (p33) => ({ approved: p33.approved }),
|
|
7581
|
+
// Composer / attachments / voice.
|
|
7582
|
+
attach: (p33) => ({ count: p33.count, bytes: p33.totalBytes }),
|
|
7583
|
+
voiceStart: () => void 0,
|
|
7584
|
+
voiceStop: (p33) => ({ ms: p33.durationMs }),
|
|
7585
|
+
voiceCancel: () => void 0,
|
|
7586
|
+
// Preferences — how visitors tune the surface.
|
|
7587
|
+
localeChange: (locale) => ({ locale }),
|
|
7588
|
+
themeChange: (theme) => ({ theme }),
|
|
7589
|
+
textSizeChange: (size) => ({ size }),
|
|
7590
|
+
soundToggle: (p33) => ({ muted: p33.muted }),
|
|
7591
|
+
sidebarToggle: (p33) => ({ collapsed: p33.collapsed }),
|
|
7592
|
+
calloutDismiss: () => void 0,
|
|
7593
|
+
// Health signal only — the error object itself never leaves the page.
|
|
7594
|
+
error: () => void 0
|
|
7595
|
+
};
|
|
7596
|
+
function privacySignalsOff() {
|
|
7597
|
+
const nav = navigator;
|
|
7598
|
+
return nav.globalPrivacyControl === true || nav.doNotTrack === "1";
|
|
7599
|
+
}
|
|
7600
|
+
function pageUrl() {
|
|
7601
|
+
return location.origin + location.pathname;
|
|
7602
|
+
}
|
|
7603
|
+
function referrerOrigin() {
|
|
7604
|
+
try {
|
|
7605
|
+
return document.referrer ? new URL(document.referrer).origin : "";
|
|
7606
|
+
} catch {
|
|
7607
|
+
return "";
|
|
7608
|
+
}
|
|
7609
|
+
}
|
|
7610
|
+
function createTracker(bus, deps) {
|
|
7611
|
+
const sampleRoll = Math.random();
|
|
7612
|
+
let windowStart = 0;
|
|
7613
|
+
let windowHits = 0;
|
|
7614
|
+
const inflight = /* @__PURE__ */ new Set();
|
|
7615
|
+
const hit = (event, dims) => {
|
|
7616
|
+
const { tracking, publicKey, aiAgentDeploymentId, mode, themeMode } = deps.getOptions();
|
|
7617
|
+
if (!tracking.enabled || privacySignalsOff()) return;
|
|
7618
|
+
if (sampleRoll >= tracking.sampleRate) return;
|
|
7619
|
+
const now = performance.now();
|
|
7620
|
+
if (now - windowStart > 6e4) {
|
|
7621
|
+
windowStart = now;
|
|
7622
|
+
windowHits = 0;
|
|
7623
|
+
}
|
|
7624
|
+
if (++windowHits > MAX_HITS_PER_MINUTE) return;
|
|
7625
|
+
const params = new URLSearchParams();
|
|
7626
|
+
params.set("v", PROTOCOL_VERSION);
|
|
7627
|
+
params.set("e", event);
|
|
7628
|
+
if (tracking.token) params.set("tk", tracking.token);
|
|
7629
|
+
if (publicKey) params.set("pk", publicKey);
|
|
7630
|
+
if (aiAgentDeploymentId) params.set("dep", aiAgentDeploymentId);
|
|
7631
|
+
params.set("vid", deps.getVisitorId());
|
|
7632
|
+
const cid = deps.getConversationId();
|
|
7633
|
+
if (cid) params.set("cid", cid);
|
|
7634
|
+
params.set("url", pageUrl());
|
|
7635
|
+
const ref = referrerOrigin();
|
|
7636
|
+
if (ref) params.set("ref", ref);
|
|
7637
|
+
params.set("sw", String(screen.width));
|
|
7638
|
+
params.set("sh", String(screen.height));
|
|
7639
|
+
params.set("vw", String(innerWidth));
|
|
7640
|
+
params.set("vh", String(innerHeight));
|
|
7641
|
+
params.set("dpr", String(devicePixelRatio));
|
|
7642
|
+
params.set("lang", navigator.language);
|
|
7643
|
+
try {
|
|
7644
|
+
params.set("tz", Intl.DateTimeFormat().resolvedOptions().timeZone);
|
|
7645
|
+
} catch {
|
|
7646
|
+
}
|
|
7647
|
+
params.set("m", mode);
|
|
7648
|
+
params.set("th", themeMode);
|
|
7649
|
+
if (dims) {
|
|
7650
|
+
for (const [k, val] of Object.entries(dims)) {
|
|
7651
|
+
if (val !== void 0) params.set(k, String(val));
|
|
7652
|
+
}
|
|
7653
|
+
}
|
|
7654
|
+
params.set("ts", String(Date.now()));
|
|
7655
|
+
const url = `${tracking.endpoint}?${params}`;
|
|
7656
|
+
if (url.length > MAX_URL_LENGTH) return;
|
|
7657
|
+
const img = new Image(1, 1);
|
|
7658
|
+
inflight.add(img);
|
|
7659
|
+
const settle = () => inflight.delete(img);
|
|
7660
|
+
img.addEventListener("load", settle, { once: true });
|
|
7661
|
+
img.addEventListener("error", settle, { once: true });
|
|
7662
|
+
img.src = url;
|
|
7663
|
+
};
|
|
7664
|
+
const offs = Object.keys(TRACKED).map(
|
|
7665
|
+
(event) => bus.on(event, (payload) => hit(event, TRACKED[event]?.(payload)))
|
|
7666
|
+
);
|
|
7667
|
+
return () => {
|
|
7668
|
+
for (const off of offs) off();
|
|
7669
|
+
inflight.clear();
|
|
7670
|
+
};
|
|
7671
|
+
}
|
|
7672
|
+
|
|
7497
7673
|
// src/core/hooks.ts
|
|
7498
7674
|
var log19 = logger.scope("hooks");
|
|
7499
7675
|
|
|
@@ -7527,6 +7703,23 @@ var ChatElement = class extends HTMLElement {
|
|
|
7527
7703
|
* same user-wins-per-field merge policy.
|
|
7528
7704
|
*/
|
|
7529
7705
|
__publicField(this, "rawOptions", {});
|
|
7706
|
+
/**
|
|
7707
|
+
* Latest resolved options — refreshed every `renderApp()` so the usage
|
|
7708
|
+
* tracker (created once in `boot`) reads live, post-handshake-merge
|
|
7709
|
+
* values (`tracking.enabled` / `endpoint` / `token`).
|
|
7710
|
+
*
|
|
7711
|
+
* This path is independent of `mount()` (it supports N elements per page
|
|
7712
|
+
* without a shared `widgetId` registry), so everything `mount()` composes
|
|
7713
|
+
* around `<App>` must be mirrored here: the handshake-config merge, the
|
|
7714
|
+
* usage tracker, and the ErrorBoundary wrapper. This has drifted three
|
|
7715
|
+
* times now (mode-merge, tracker, ErrorBoundary). The proper fix is to
|
|
7716
|
+
* extract the shared `<App>` composition into one `bootWidget(opts,
|
|
7717
|
+
* { hostElement })` helper both entry points call — tracked as a
|
|
7718
|
+
* follow-up; until then, keep these two boot paths in lockstep.
|
|
7719
|
+
*/
|
|
7720
|
+
__publicField(this, "resolved", null);
|
|
7721
|
+
/** Tracker unsubscribe — released on disconnect. */
|
|
7722
|
+
__publicField(this, "untrack", null);
|
|
7530
7723
|
}
|
|
7531
7724
|
static get observedAttributes() {
|
|
7532
7725
|
return REACTIVE_ATTRS;
|
|
@@ -7536,6 +7729,8 @@ var ChatElement = class extends HTMLElement {
|
|
|
7536
7729
|
}
|
|
7537
7730
|
disconnectedCallback() {
|
|
7538
7731
|
if (!this.mountResult) return;
|
|
7732
|
+
this.untrack?.();
|
|
7733
|
+
this.untrack = null;
|
|
7539
7734
|
render2(null, this.mountResult.appRoot);
|
|
7540
7735
|
this.bus.clear();
|
|
7541
7736
|
}
|
|
@@ -7555,6 +7750,12 @@ var ChatElement = class extends HTMLElement {
|
|
|
7555
7750
|
this.rawOptions = mergeServerConfig(this.rawOptions, response.config);
|
|
7556
7751
|
this.renderApp();
|
|
7557
7752
|
});
|
|
7753
|
+
const persistence = createPersistence(resolved.widgetId, resolved.storage);
|
|
7754
|
+
this.untrack = createTracker(this.bus, {
|
|
7755
|
+
getOptions: () => this.resolved ?? resolved,
|
|
7756
|
+
getVisitorId: () => persistence.getVisitorId(),
|
|
7757
|
+
getConversationId: () => persistence.loadConversationId()
|
|
7758
|
+
});
|
|
7558
7759
|
}
|
|
7559
7760
|
this.renderApp();
|
|
7560
7761
|
}
|
|
@@ -7565,12 +7766,20 @@ var ChatElement = class extends HTMLElement {
|
|
|
7565
7766
|
renderApp() {
|
|
7566
7767
|
if (!this.mountResult) return;
|
|
7567
7768
|
const resolved = resolveOptions(this.rawOptions);
|
|
7769
|
+
this.resolved = resolved;
|
|
7568
7770
|
const host = this.mountResult.hostElement;
|
|
7569
7771
|
applyHostPosition(host, hostPositionForMode(resolved.mode));
|
|
7570
7772
|
const cachedThemeMode = createPersistence(resolved.widgetId, resolved.storage).loadUserPrefs().themeMode;
|
|
7571
7773
|
applyHostAttributes(host, cachedThemeMode ? { ...resolved, themeMode: cachedThemeMode } : resolved);
|
|
7572
7774
|
applyMode(host, resolveInitialHostMode(resolved));
|
|
7573
|
-
render2(
|
|
7775
|
+
render2(
|
|
7776
|
+
h2(
|
|
7777
|
+
ErrorBoundary,
|
|
7778
|
+
{ onError: (error) => this.bus.emit("error", error) },
|
|
7779
|
+
h2(App, { bus: this.bus, hostElement: host, options: resolved })
|
|
7780
|
+
),
|
|
7781
|
+
this.mountResult.appRoot
|
|
7782
|
+
);
|
|
7574
7783
|
}
|
|
7575
7784
|
};
|
|
7576
7785
|
var registered = false;
|