@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/react.cjs
CHANGED
|
@@ -238,6 +238,9 @@ function resolveRef(ref) {
|
|
|
238
238
|
if (!entry || entry.id !== ref || entry.gen !== generation) return null;
|
|
239
239
|
return el;
|
|
240
240
|
}
|
|
241
|
+
function clearRefs() {
|
|
242
|
+
registry.clear();
|
|
243
|
+
}
|
|
241
244
|
var counter, generation, entries, registry;
|
|
242
245
|
var init_refs = __esm({
|
|
243
246
|
"src/dom/refs.ts"() {
|
|
@@ -252,6 +255,7 @@ var init_refs = __esm({
|
|
|
252
255
|
// src/dom/snapshot.ts
|
|
253
256
|
var snapshot_exports = {};
|
|
254
257
|
__export(snapshot_exports, {
|
|
258
|
+
clearRefs: () => clearRefs,
|
|
255
259
|
resolveRef: () => resolveRef,
|
|
256
260
|
snapshot: () => snapshot,
|
|
257
261
|
snapshotRegion: () => snapshotRegion
|
|
@@ -495,7 +499,6 @@ var init_snapshot = __esm({
|
|
|
495
499
|
var context_exports = {};
|
|
496
500
|
__export(context_exports, {
|
|
497
501
|
artifactIdFromPath: () => artifactIdFromPath,
|
|
498
|
-
beginAuth: () => beginAuth,
|
|
499
502
|
callTool: () => callTool,
|
|
500
503
|
grantsFromIframeSrcs: () => grantsFromIframeSrcs,
|
|
501
504
|
isPrivate: () => isPrivate,
|
|
@@ -503,7 +506,8 @@ __export(context_exports, {
|
|
|
503
506
|
redact: () => redact,
|
|
504
507
|
sendRegion: () => sendRegion,
|
|
505
508
|
sendSnapshot: () => sendSnapshot,
|
|
506
|
-
start: () => start
|
|
509
|
+
start: () => start,
|
|
510
|
+
stop: () => stop
|
|
507
511
|
});
|
|
508
512
|
function redact(text) {
|
|
509
513
|
let out = text;
|
|
@@ -673,8 +677,11 @@ function watchNavigation() {
|
|
|
673
677
|
publishContext();
|
|
674
678
|
publishArtifactGrants();
|
|
675
679
|
};
|
|
680
|
+
navFire = fire;
|
|
676
681
|
for (const name of ["pushState", "replaceState"]) {
|
|
677
682
|
const orig = history[name];
|
|
683
|
+
if (name === "pushState") origPushState = orig;
|
|
684
|
+
else origReplaceState = orig;
|
|
678
685
|
history[name] = function(...args) {
|
|
679
686
|
const r = orig.apply(this, args);
|
|
680
687
|
fire();
|
|
@@ -695,7 +702,7 @@ async function readFocus() {
|
|
|
695
702
|
}
|
|
696
703
|
const active = document.activeElement;
|
|
697
704
|
if (active && active !== document.body && !isPrivate(active) && !active.closest("[data-mf-private]")) {
|
|
698
|
-
const { snapshot: snapshot2 } = await
|
|
705
|
+
const { snapshot: snapshot2 } = await loadSnapshotModule();
|
|
699
706
|
void snapshot2;
|
|
700
707
|
focus.focused = {
|
|
701
708
|
label: redact(describeControl(active)),
|
|
@@ -710,6 +717,11 @@ async function readFocus() {
|
|
|
710
717
|
function describeControl(el) {
|
|
711
718
|
return describe(el);
|
|
712
719
|
}
|
|
720
|
+
async function loadSnapshotModule() {
|
|
721
|
+
const m = await Promise.resolve().then(() => (init_snapshot(), snapshot_exports));
|
|
722
|
+
snapshotModule = m;
|
|
723
|
+
return m;
|
|
724
|
+
}
|
|
713
725
|
function scheduleFocus() {
|
|
714
726
|
if (focusTimer) return;
|
|
715
727
|
focusTimer = setTimeout(async () => {
|
|
@@ -719,7 +731,8 @@ function scheduleFocus() {
|
|
|
719
731
|
}, 250);
|
|
720
732
|
}
|
|
721
733
|
async function sendSnapshot(emit) {
|
|
722
|
-
|
|
734
|
+
if (!pageContextOn) return;
|
|
735
|
+
const { snapshot: snapshot2 } = await loadSnapshotModule();
|
|
723
736
|
const { yaml, truncated, visibleRefs } = snapshot2();
|
|
724
737
|
emit({
|
|
725
738
|
type: "host.snapshot",
|
|
@@ -729,7 +742,8 @@ async function sendSnapshot(emit) {
|
|
|
729
742
|
emit({ type: "host.focus", focus: lastFocus });
|
|
730
743
|
}
|
|
731
744
|
async function sendRegion(ref, emit) {
|
|
732
|
-
|
|
745
|
+
if (!pageContextOn) return;
|
|
746
|
+
const { snapshotRegion: snapshotRegion2, resolveRef: resolveRef2 } = await loadSnapshotModule();
|
|
733
747
|
const el = resolveRef2(ref);
|
|
734
748
|
if (!el) {
|
|
735
749
|
emit({
|
|
@@ -750,55 +764,73 @@ async function callTool(call, emit) {
|
|
|
750
764
|
error: "Host tools are read-only in this version; no action was taken."
|
|
751
765
|
});
|
|
752
766
|
}
|
|
753
|
-
function
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
)
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
767
|
+
function stop() {
|
|
768
|
+
document.removeEventListener("click", onClick, { capture: true });
|
|
769
|
+
document.removeEventListener("submit", onSubmit, { capture: true });
|
|
770
|
+
document.removeEventListener("change", onChange, { capture: true });
|
|
771
|
+
document.removeEventListener("selectionchange", scheduleFocus);
|
|
772
|
+
document.removeEventListener("focusin", scheduleFocus, { capture: true });
|
|
773
|
+
window.removeEventListener("scroll", scheduleFocus, { capture: true });
|
|
774
|
+
if (navFire) {
|
|
775
|
+
window.removeEventListener("popstate", navFire);
|
|
776
|
+
navFire = null;
|
|
777
|
+
}
|
|
778
|
+
if (origPushState) {
|
|
779
|
+
history.pushState = origPushState;
|
|
780
|
+
origPushState = null;
|
|
781
|
+
}
|
|
782
|
+
if (origReplaceState) {
|
|
783
|
+
history.replaceState = origReplaceState;
|
|
784
|
+
origReplaceState = null;
|
|
785
|
+
}
|
|
786
|
+
if (focusTimer) {
|
|
787
|
+
clearTimeout(focusTimer);
|
|
788
|
+
focusTimer = null;
|
|
789
|
+
}
|
|
790
|
+
send = null;
|
|
791
|
+
activity.length = 0;
|
|
792
|
+
lastFocus = {};
|
|
793
|
+
widgetOrigin = "";
|
|
794
|
+
snapshotModule?.clearRefs();
|
|
795
|
+
}
|
|
796
|
+
function start(emit, origin, pageContext = true) {
|
|
797
|
+
stop();
|
|
772
798
|
send = emit;
|
|
773
799
|
widgetOrigin = origin || "";
|
|
774
800
|
lastUrl = location.pathname;
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
801
|
+
pageContextOn = pageContext;
|
|
802
|
+
if (pageContextOn) {
|
|
803
|
+
publishContext();
|
|
804
|
+
publishArtifactGrants();
|
|
805
|
+
watchNavigation();
|
|
806
|
+
document.addEventListener("click", onClick, {
|
|
807
|
+
capture: true,
|
|
808
|
+
passive: true
|
|
809
|
+
});
|
|
810
|
+
document.addEventListener("submit", onSubmit, {
|
|
811
|
+
capture: true,
|
|
812
|
+
passive: true
|
|
813
|
+
});
|
|
814
|
+
document.addEventListener("change", onChange, {
|
|
815
|
+
capture: true,
|
|
816
|
+
passive: true
|
|
817
|
+
});
|
|
818
|
+
document.addEventListener("selectionchange", scheduleFocus, {
|
|
819
|
+
passive: true
|
|
820
|
+
});
|
|
821
|
+
document.addEventListener("focusin", scheduleFocus, {
|
|
822
|
+
capture: true,
|
|
823
|
+
passive: true
|
|
824
|
+
});
|
|
825
|
+
window.addEventListener("scroll", scheduleFocus, {
|
|
826
|
+
capture: true,
|
|
827
|
+
passive: true
|
|
828
|
+
});
|
|
829
|
+
}
|
|
798
830
|
const theme = matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
799
831
|
emit({ type: "host.theme", mode: theme });
|
|
800
832
|
}
|
|
801
|
-
var widgetOrigin, MAX_ACTIVITY, send, activitySeq, activity, lastUrl, PII, FORM_CONTROLS, ACTIONABLE, lastFocus, focusTimer, snapshotSeq;
|
|
833
|
+
var widgetOrigin, MAX_ACTIVITY, send, activitySeq, activity, lastUrl, pageContextOn, navFire, origPushState, origReplaceState, snapshotModule, PII, FORM_CONTROLS, ACTIONABLE, lastFocus, focusTimer, snapshotSeq;
|
|
802
834
|
var init_context = __esm({
|
|
803
835
|
"src/context.ts"() {
|
|
804
836
|
"use strict";
|
|
@@ -808,6 +840,11 @@ var init_context = __esm({
|
|
|
808
840
|
activitySeq = 0;
|
|
809
841
|
activity = [];
|
|
810
842
|
lastUrl = "";
|
|
843
|
+
pageContextOn = true;
|
|
844
|
+
navFire = null;
|
|
845
|
+
origPushState = null;
|
|
846
|
+
origReplaceState = null;
|
|
847
|
+
snapshotModule = null;
|
|
811
848
|
PII = [
|
|
812
849
|
/\b[\w.+-]+@[\w-]+\.[\w.]{2,}\b/g,
|
|
813
850
|
// email
|
|
@@ -1027,7 +1064,9 @@ var EmbedHost = class {
|
|
|
1027
1064
|
iframe.setAttribute("allow", "microphone");
|
|
1028
1065
|
iframe.src = `${this.config.origin}/embed/chat?k=${encodeURIComponent(
|
|
1029
1066
|
this.config.publishableKey
|
|
1030
|
-
)}&o=${encodeURIComponent(location.origin)}` + (this.config.surface ? `&s=${encodeURIComponent(this.config.surface)}` : "") +
|
|
1067
|
+
)}&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
|
|
1068
|
+
// programmatic `dev` (the React prop). See both doc comments above.
|
|
1069
|
+
(devRequested() || this.config.dev ? "&dev=1" : "") + (this.inline ? "&inline=1" : "");
|
|
1031
1070
|
this.iframe = iframe;
|
|
1032
1071
|
this.shadow.appendChild(iframe);
|
|
1033
1072
|
window.addEventListener("message", this.onMessage);
|
|
@@ -1097,27 +1136,26 @@ var EmbedHost = class {
|
|
|
1097
1136
|
* window.matterfact = { getEmbedAuthToken: () => getIdToken(user) };
|
|
1098
1137
|
*
|
|
1099
1138
|
* Read fresh at call time (not at readConfig), so a global set after the loader booted
|
|
1100
|
-
* — e.g. once the host's auth is ready — is still picked up.
|
|
1101
|
-
*
|
|
1102
|
-
*
|
|
1139
|
+
* — e.g. once the host's auth is ready — is still picked up. `expiresAt: 0`: the widget
|
|
1140
|
+
* doesn't cache it, it exchanges the token for a rotating embed session anyway.
|
|
1141
|
+
*
|
|
1142
|
+
* No provider ⇒ this does nothing. The loader never opens a sign-in popup — the widget
|
|
1143
|
+
* owns interactive sign-in (inline Firebase/email, and Microsoft's own MSAL login popup
|
|
1144
|
+
* for Entra, then the PKCE token exchange), so the loader must not also fire its stale
|
|
1145
|
+
* `/embed/authorize?k=&o=` popup, which the deployed authorize page no longer accepts.
|
|
1103
1146
|
*/
|
|
1104
1147
|
async provideAuth() {
|
|
1105
1148
|
const provider = this.config.authTokenProvider ?? globalThis.matterfact?.getEmbedAuthToken;
|
|
1106
|
-
if (provider)
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
return;
|
|
1112
|
-
}
|
|
1113
|
-
} catch {
|
|
1114
|
-
}
|
|
1149
|
+
if (!provider) return;
|
|
1150
|
+
try {
|
|
1151
|
+
const token = await provider();
|
|
1152
|
+
if (token) this.send({ type: "host.auth", token, expiresAt: 0 });
|
|
1153
|
+
} catch {
|
|
1115
1154
|
}
|
|
1116
|
-
void this.loadContext().then((m) => m.beginAuth(this.config, this.send));
|
|
1117
1155
|
}
|
|
1118
1156
|
loadContext() {
|
|
1119
1157
|
this.context ?? (this.context = Promise.resolve().then(() => (init_context(), context_exports)).then((m) => {
|
|
1120
|
-
m.start(this.send, this.config.origin);
|
|
1158
|
+
m.start(this.send, this.config.origin, this.config.pageContext);
|
|
1121
1159
|
if (this.config.theme !== "auto") {
|
|
1122
1160
|
this.send({ type: "host.theme", mode: this.config.theme });
|
|
1123
1161
|
}
|
|
@@ -1140,6 +1178,7 @@ var EmbedHost = class {
|
|
|
1140
1178
|
this.iframe = null;
|
|
1141
1179
|
this.shadow = null;
|
|
1142
1180
|
this.ready = false;
|
|
1181
|
+
void this.context?.then((m) => m.stop());
|
|
1143
1182
|
}
|
|
1144
1183
|
};
|
|
1145
1184
|
function mount(config) {
|
|
@@ -1159,7 +1198,9 @@ function MatterfactAgent({
|
|
|
1159
1198
|
getAuthToken,
|
|
1160
1199
|
inline = false,
|
|
1161
1200
|
className,
|
|
1162
|
-
style
|
|
1201
|
+
style,
|
|
1202
|
+
pageContext,
|
|
1203
|
+
dev
|
|
1163
1204
|
}) {
|
|
1164
1205
|
const authRef = (0, import_react.useRef)(getAuthToken);
|
|
1165
1206
|
authRef.current = getAuthToken;
|
|
@@ -1175,7 +1216,9 @@ function MatterfactAgent({
|
|
|
1175
1216
|
// Always present; a null return (no getAuthToken supplied) makes the core fall
|
|
1176
1217
|
// back to the popup/inline sign-in, so this is safe either way.
|
|
1177
1218
|
authTokenProvider: async () => await authRef.current?.() ?? null,
|
|
1178
|
-
container: inline ? slot.current : null
|
|
1219
|
+
container: inline ? slot.current : null,
|
|
1220
|
+
pageContext,
|
|
1221
|
+
dev
|
|
1179
1222
|
};
|
|
1180
1223
|
let host = null;
|
|
1181
1224
|
try {
|
|
@@ -1184,7 +1227,7 @@ function MatterfactAgent({
|
|
|
1184
1227
|
console.error("[matterfact] failed to mount the embed widget", e);
|
|
1185
1228
|
}
|
|
1186
1229
|
return () => host?.destroy();
|
|
1187
|
-
}, [publishableKey, widgetOrigin2, surface, theme, inline]);
|
|
1230
|
+
}, [publishableKey, widgetOrigin2, surface, theme, inline, pageContext, dev]);
|
|
1188
1231
|
if (!inline) return null;
|
|
1189
1232
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1190
1233
|
"div",
|