@matterfact/embed 0.3.0 → 0.5.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/README.md +45 -5
- package/dist/{chunk-33LPVL2R.js → chunk-GZZYR6YF.js} +3 -3
- package/dist/{chunk-33LPVL2R.js.map → chunk-GZZYR6YF.js.map} +3 -3
- package/dist/chunk-JN3ZMONO.js +2 -0
- package/dist/chunk-JN3ZMONO.js.map +7 -0
- package/dist/{chunk-CHPADW72.js → chunk-JSH3BRYP.js} +80 -47
- package/dist/chunk-JSH3BRYP.js.map +1 -0
- package/dist/{chunk-SQJX27LT.js → chunk-NZIN3LK7.js} +79 -46
- package/dist/chunk-NZIN3LK7.js.map +1 -0
- package/dist/chunk-Z53V2P4B.js +2 -0
- package/dist/context-AQY2LJWK.js +3 -0
- package/dist/{context-BFNFFHC2.js.map → context-AQY2LJWK.js.map} +1 -1
- package/dist/{context-MORDASRH.js → context-UBTZEEWS.js} +6 -6
- package/dist/embed.js +1 -1
- package/dist/embed.js.map +3 -3
- package/dist/index.cjs +106 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.js +23 -17
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +109 -66
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +14 -1
- package/dist/react.d.ts +14 -1
- package/dist/react.js +25 -19
- package/dist/react.js.map +1 -1
- package/dist/{snapshot-IWVXLE4G.js → snapshot-HYMRZTZC.js} +6 -2
- package/dist/snapshot-HYMRZTZC.js.map +1 -0
- package/dist/{snapshot-QBV7DTJP.js → snapshot-XFCV2MYR.js} +7 -4
- package/dist/snapshot-XFCV2MYR.js.map +1 -0
- package/examples/README.md +46 -0
- package/examples/demo-host/index.html +163 -0
- package/examples/demo-host/serve.mjs +62 -0
- package/examples/embed-demo/.env.example +24 -0
- package/examples/embed-demo/README.md +72 -0
- package/examples/embed-demo/index.html +12 -0
- package/examples/embed-demo/package.json +25 -0
- package/examples/embed-demo/src/App.tsx +189 -0
- package/examples/embed-demo/src/config.ts +43 -0
- package/examples/embed-demo/src/main.tsx +10 -0
- package/examples/embed-demo/src/styles.css +354 -0
- package/examples/embed-demo/tsconfig.json +16 -0
- package/examples/embed-demo/vite.config.ts +11 -0
- package/examples/host-panel.html +237 -0
- package/package.json +3 -2
- package/dist/chunk-CHPADW72.js.map +0 -1
- package/dist/chunk-F7DLOR7F.js +0 -2
- package/dist/chunk-F7DLOR7F.js.map +0 -7
- package/dist/chunk-FBIJZJGL.js +0 -2
- package/dist/chunk-SQJX27LT.js.map +0 -1
- package/dist/context-BFNFFHC2.js +0 -3
- package/dist/snapshot-IWVXLE4G.js.map +0 -1
- package/dist/snapshot-QBV7DTJP.js.map +0 -1
- /package/dist/{chunk-FBIJZJGL.js.map → chunk-Z53V2P4B.js.map} +0 -0
- /package/dist/{context-MORDASRH.js.map → context-UBTZEEWS.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -224,6 +224,9 @@ function resolveRef(ref) {
|
|
|
224
224
|
if (!entry || entry.id !== ref || entry.gen !== generation) return null;
|
|
225
225
|
return el;
|
|
226
226
|
}
|
|
227
|
+
function clearRefs() {
|
|
228
|
+
registry.clear();
|
|
229
|
+
}
|
|
227
230
|
var counter, generation, entries, registry;
|
|
228
231
|
var init_refs = __esm({
|
|
229
232
|
"src/dom/refs.ts"() {
|
|
@@ -237,6 +240,7 @@ var init_refs = __esm({
|
|
|
237
240
|
// src/dom/snapshot.ts
|
|
238
241
|
var snapshot_exports = {};
|
|
239
242
|
__export(snapshot_exports, {
|
|
243
|
+
clearRefs: () => clearRefs,
|
|
240
244
|
resolveRef: () => resolveRef,
|
|
241
245
|
snapshot: () => snapshot,
|
|
242
246
|
snapshotRegion: () => snapshotRegion
|
|
@@ -478,7 +482,6 @@ var init_snapshot = __esm({
|
|
|
478
482
|
var context_exports = {};
|
|
479
483
|
__export(context_exports, {
|
|
480
484
|
artifactIdFromPath: () => artifactIdFromPath,
|
|
481
|
-
beginAuth: () => beginAuth,
|
|
482
485
|
callTool: () => callTool,
|
|
483
486
|
grantsFromIframeSrcs: () => grantsFromIframeSrcs,
|
|
484
487
|
isPrivate: () => isPrivate,
|
|
@@ -486,7 +489,8 @@ __export(context_exports, {
|
|
|
486
489
|
redact: () => redact,
|
|
487
490
|
sendRegion: () => sendRegion,
|
|
488
491
|
sendSnapshot: () => sendSnapshot,
|
|
489
|
-
start: () => start
|
|
492
|
+
start: () => start,
|
|
493
|
+
stop: () => stop
|
|
490
494
|
});
|
|
491
495
|
function redact(text) {
|
|
492
496
|
let out = text;
|
|
@@ -656,8 +660,11 @@ function watchNavigation() {
|
|
|
656
660
|
publishContext();
|
|
657
661
|
publishArtifactGrants();
|
|
658
662
|
};
|
|
663
|
+
navFire = fire;
|
|
659
664
|
for (const name of ["pushState", "replaceState"]) {
|
|
660
665
|
const orig = history[name];
|
|
666
|
+
if (name === "pushState") origPushState = orig;
|
|
667
|
+
else origReplaceState = orig;
|
|
661
668
|
history[name] = function(...args) {
|
|
662
669
|
const r = orig.apply(this, args);
|
|
663
670
|
fire();
|
|
@@ -678,7 +685,7 @@ async function readFocus() {
|
|
|
678
685
|
}
|
|
679
686
|
const active = document.activeElement;
|
|
680
687
|
if (active && active !== document.body && !isPrivate(active) && !active.closest("[data-mf-private]")) {
|
|
681
|
-
const { snapshot: snapshot2 } = await
|
|
688
|
+
const { snapshot: snapshot2 } = await loadSnapshotModule();
|
|
682
689
|
focus.focused = {
|
|
683
690
|
label: redact(describeControl(active)),
|
|
684
691
|
role: active.getAttribute("role") || active.tagName.toLowerCase()
|
|
@@ -692,6 +699,11 @@ async function readFocus() {
|
|
|
692
699
|
function describeControl(el) {
|
|
693
700
|
return describe(el);
|
|
694
701
|
}
|
|
702
|
+
async function loadSnapshotModule() {
|
|
703
|
+
const m = await Promise.resolve().then(() => (init_snapshot(), snapshot_exports));
|
|
704
|
+
snapshotModule = m;
|
|
705
|
+
return m;
|
|
706
|
+
}
|
|
695
707
|
function scheduleFocus() {
|
|
696
708
|
if (focusTimer) return;
|
|
697
709
|
focusTimer = setTimeout(async () => {
|
|
@@ -701,7 +713,8 @@ function scheduleFocus() {
|
|
|
701
713
|
}, 250);
|
|
702
714
|
}
|
|
703
715
|
async function sendSnapshot(emit) {
|
|
704
|
-
|
|
716
|
+
if (!pageContextOn) return;
|
|
717
|
+
const { snapshot: snapshot2 } = await loadSnapshotModule();
|
|
705
718
|
const { yaml, truncated, visibleRefs } = snapshot2();
|
|
706
719
|
emit({
|
|
707
720
|
type: "host.snapshot",
|
|
@@ -711,7 +724,8 @@ async function sendSnapshot(emit) {
|
|
|
711
724
|
emit({ type: "host.focus", focus: lastFocus });
|
|
712
725
|
}
|
|
713
726
|
async function sendRegion(ref, emit) {
|
|
714
|
-
|
|
727
|
+
if (!pageContextOn) return;
|
|
728
|
+
const { snapshotRegion: snapshotRegion2, resolveRef: resolveRef2 } = await loadSnapshotModule();
|
|
715
729
|
const el = resolveRef2(ref);
|
|
716
730
|
if (!el) {
|
|
717
731
|
emit({
|
|
@@ -732,55 +746,73 @@ async function callTool(call, emit) {
|
|
|
732
746
|
error: "Host tools are read-only in this version; no action was taken."
|
|
733
747
|
});
|
|
734
748
|
}
|
|
735
|
-
function
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
)
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
749
|
+
function stop() {
|
|
750
|
+
document.removeEventListener("click", onClick, { capture: true });
|
|
751
|
+
document.removeEventListener("submit", onSubmit, { capture: true });
|
|
752
|
+
document.removeEventListener("change", onChange, { capture: true });
|
|
753
|
+
document.removeEventListener("selectionchange", scheduleFocus);
|
|
754
|
+
document.removeEventListener("focusin", scheduleFocus, { capture: true });
|
|
755
|
+
window.removeEventListener("scroll", scheduleFocus, { capture: true });
|
|
756
|
+
if (navFire) {
|
|
757
|
+
window.removeEventListener("popstate", navFire);
|
|
758
|
+
navFire = null;
|
|
759
|
+
}
|
|
760
|
+
if (origPushState) {
|
|
761
|
+
history.pushState = origPushState;
|
|
762
|
+
origPushState = null;
|
|
763
|
+
}
|
|
764
|
+
if (origReplaceState) {
|
|
765
|
+
history.replaceState = origReplaceState;
|
|
766
|
+
origReplaceState = null;
|
|
767
|
+
}
|
|
768
|
+
if (focusTimer) {
|
|
769
|
+
clearTimeout(focusTimer);
|
|
770
|
+
focusTimer = null;
|
|
771
|
+
}
|
|
772
|
+
send = null;
|
|
773
|
+
activity.length = 0;
|
|
774
|
+
lastFocus = {};
|
|
775
|
+
widgetOrigin = "";
|
|
776
|
+
snapshotModule?.clearRefs();
|
|
752
777
|
}
|
|
753
|
-
function start(emit, origin) {
|
|
778
|
+
function start(emit, origin, pageContext = true) {
|
|
779
|
+
stop();
|
|
754
780
|
send = emit;
|
|
755
781
|
widgetOrigin = origin || "";
|
|
756
782
|
lastUrl = location.pathname;
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
783
|
+
pageContextOn = pageContext;
|
|
784
|
+
if (pageContextOn) {
|
|
785
|
+
publishContext();
|
|
786
|
+
publishArtifactGrants();
|
|
787
|
+
watchNavigation();
|
|
788
|
+
document.addEventListener("click", onClick, {
|
|
789
|
+
capture: true,
|
|
790
|
+
passive: true
|
|
791
|
+
});
|
|
792
|
+
document.addEventListener("submit", onSubmit, {
|
|
793
|
+
capture: true,
|
|
794
|
+
passive: true
|
|
795
|
+
});
|
|
796
|
+
document.addEventListener("change", onChange, {
|
|
797
|
+
capture: true,
|
|
798
|
+
passive: true
|
|
799
|
+
});
|
|
800
|
+
document.addEventListener("selectionchange", scheduleFocus, {
|
|
801
|
+
passive: true
|
|
802
|
+
});
|
|
803
|
+
document.addEventListener("focusin", scheduleFocus, {
|
|
804
|
+
capture: true,
|
|
805
|
+
passive: true
|
|
806
|
+
});
|
|
807
|
+
window.addEventListener("scroll", scheduleFocus, {
|
|
808
|
+
capture: true,
|
|
809
|
+
passive: true
|
|
810
|
+
});
|
|
811
|
+
}
|
|
780
812
|
const theme = matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
781
813
|
emit({ type: "host.theme", mode: theme });
|
|
782
814
|
}
|
|
783
|
-
var widgetOrigin, MAX_ACTIVITY, send, activitySeq, activity, lastUrl, PII, FORM_CONTROLS, ACTIONABLE, lastFocus, focusTimer, snapshotSeq;
|
|
815
|
+
var widgetOrigin, MAX_ACTIVITY, send, activitySeq, activity, lastUrl, pageContextOn, navFire, origPushState, origReplaceState, snapshotModule, PII, FORM_CONTROLS, ACTIONABLE, lastFocus, focusTimer, snapshotSeq;
|
|
784
816
|
var init_context = __esm({
|
|
785
817
|
"src/context.ts"() {
|
|
786
818
|
widgetOrigin = "";
|
|
@@ -789,6 +821,11 @@ var init_context = __esm({
|
|
|
789
821
|
activitySeq = 0;
|
|
790
822
|
activity = [];
|
|
791
823
|
lastUrl = "";
|
|
824
|
+
pageContextOn = true;
|
|
825
|
+
navFire = null;
|
|
826
|
+
origPushState = null;
|
|
827
|
+
origReplaceState = null;
|
|
828
|
+
snapshotModule = null;
|
|
792
829
|
PII = [
|
|
793
830
|
/\b[\w.+-]+@[\w-]+\.[\w.]{2,}\b/g,
|
|
794
831
|
// email
|
|
@@ -851,12 +888,16 @@ function readConfig() {
|
|
|
851
888
|
`[matterfact] data-container="${sel}" matched nothing; falling back to the corner`
|
|
852
889
|
);
|
|
853
890
|
}
|
|
891
|
+
const pageContextAttr = el?.dataset.pageContext?.toLowerCase();
|
|
854
892
|
return {
|
|
855
893
|
publishableKey,
|
|
856
894
|
origin: el?.dataset.origin || DEFAULT_ORIGIN,
|
|
857
895
|
theme: el?.dataset.theme || "auto",
|
|
858
896
|
surface: el?.dataset.surface || "",
|
|
859
|
-
container
|
|
897
|
+
container,
|
|
898
|
+
pageContext: pageContextAttr !== "off" && pageContextAttr !== "false" && pageContextAttr !== "0"
|
|
899
|
+
// No `data-dev` — see the `dev` field's doc comment: the URL trigger is the
|
|
900
|
+
// point for the script-tag path, so there is deliberately no script-tag knob here.
|
|
860
901
|
};
|
|
861
902
|
}
|
|
862
903
|
var POS_KEY = "mf.embed.pos";
|
|
@@ -1022,7 +1063,9 @@ var EmbedHost = class {
|
|
|
1022
1063
|
iframe.setAttribute("allow", "microphone");
|
|
1023
1064
|
iframe.src = `${this.config.origin}/embed/chat?k=${encodeURIComponent(
|
|
1024
1065
|
this.config.publishableKey
|
|
1025
|
-
)}&o=${encodeURIComponent(location.origin)}` + (this.config.surface ? `&s=${encodeURIComponent(this.config.surface)}` : "") +
|
|
1066
|
+
)}&o=${encodeURIComponent(location.origin)}` + (this.config.surface ? `&s=${encodeURIComponent(this.config.surface)}` : "") + // Either trigger works: the URL param (no redeploy needed) OR the config's
|
|
1067
|
+
// programmatic `dev` (the React prop). See both doc comments above.
|
|
1068
|
+
(devRequested() || this.config.dev ? "&dev=1" : "") + (this.inline ? "&inline=1" : "");
|
|
1026
1069
|
this.iframe = iframe;
|
|
1027
1070
|
this.shadow.appendChild(iframe);
|
|
1028
1071
|
window.addEventListener("message", this.onMessage);
|
|
@@ -1092,27 +1135,26 @@ var EmbedHost = class {
|
|
|
1092
1135
|
* window.matterfact = { getEmbedAuthToken: () => getIdToken(user) };
|
|
1093
1136
|
*
|
|
1094
1137
|
* Read fresh at call time (not at readConfig), so a global set after the loader booted
|
|
1095
|
-
* — e.g. once the host's auth is ready — is still picked up.
|
|
1096
|
-
*
|
|
1097
|
-
*
|
|
1138
|
+
* — e.g. once the host's auth is ready — is still picked up. `expiresAt: 0`: the widget
|
|
1139
|
+
* doesn't cache it, it exchanges the token for a rotating embed session anyway.
|
|
1140
|
+
*
|
|
1141
|
+
* No provider ⇒ this does nothing. The loader never opens a sign-in popup — the widget
|
|
1142
|
+
* owns interactive sign-in (inline Firebase/email, and Microsoft's own MSAL login popup
|
|
1143
|
+
* for Entra, then the PKCE token exchange), so the loader must not also fire its stale
|
|
1144
|
+
* `/embed/authorize?k=&o=` popup, which the deployed authorize page no longer accepts.
|
|
1098
1145
|
*/
|
|
1099
1146
|
async provideAuth() {
|
|
1100
1147
|
const provider = this.config.authTokenProvider ?? globalThis.matterfact?.getEmbedAuthToken;
|
|
1101
|
-
if (provider)
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
return;
|
|
1107
|
-
}
|
|
1108
|
-
} catch {
|
|
1109
|
-
}
|
|
1148
|
+
if (!provider) return;
|
|
1149
|
+
try {
|
|
1150
|
+
const token = await provider();
|
|
1151
|
+
if (token) this.send({ type: "host.auth", token, expiresAt: 0 });
|
|
1152
|
+
} catch {
|
|
1110
1153
|
}
|
|
1111
|
-
void this.loadContext().then((m) => m.beginAuth(this.config, this.send));
|
|
1112
1154
|
}
|
|
1113
1155
|
loadContext() {
|
|
1114
1156
|
this.context ?? (this.context = Promise.resolve().then(() => (init_context(), context_exports)).then((m) => {
|
|
1115
|
-
m.start(this.send, this.config.origin);
|
|
1157
|
+
m.start(this.send, this.config.origin, this.config.pageContext);
|
|
1116
1158
|
if (this.config.theme !== "auto") {
|
|
1117
1159
|
this.send({ type: "host.theme", mode: this.config.theme });
|
|
1118
1160
|
}
|
|
@@ -1135,6 +1177,7 @@ var EmbedHost = class {
|
|
|
1135
1177
|
this.iframe = null;
|
|
1136
1178
|
this.shadow = null;
|
|
1137
1179
|
this.ready = false;
|
|
1180
|
+
void this.context?.then((m) => m.stop());
|
|
1138
1181
|
}
|
|
1139
1182
|
};
|
|
1140
1183
|
function mount(config) {
|