@matterfact/embed 0.4.0 → 0.6.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.
Files changed (54) hide show
  1. package/README.md +62 -6
  2. package/dist/{chunk-523BCS2Z.js → chunk-4Q2ROXLR.js} +2 -2
  3. package/dist/chunk-7I37ZFAJ.js +2 -0
  4. package/dist/{chunk-Z4WT3TIZ.js → chunk-AXKXNYRT.js} +39 -38
  5. package/dist/chunk-AXKXNYRT.js.map +1 -0
  6. package/dist/chunk-D7R6WVHG.js +2 -0
  7. package/dist/chunk-D7R6WVHG.js.map +7 -0
  8. package/dist/{chunk-SBNMM3ZV.js → chunk-RS6RMZ77.js} +39 -37
  9. package/dist/chunk-RS6RMZ77.js.map +1 -0
  10. package/dist/{context-432WQST4.js → context-WU2F5CBC.js} +6 -4
  11. package/dist/context-YX2KXFLI.js +3 -0
  12. package/dist/{context-KZAUOIR6.js.map → context-YX2KXFLI.js.map} +1 -1
  13. package/dist/embed.js +1 -1
  14. package/dist/embed.js.map +2 -2
  15. package/dist/index.cjs +58 -50
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +37 -3
  18. package/dist/index.d.ts +37 -3
  19. package/dist/index.js +22 -15
  20. package/dist/index.js.map +1 -1
  21. package/dist/react.cjs +64 -50
  22. package/dist/react.cjs.map +1 -1
  23. package/dist/react.d.cts +35 -1
  24. package/dist/react.d.ts +35 -1
  25. package/dist/react.js +28 -15
  26. package/dist/react.js.map +1 -1
  27. package/dist/{snapshot-SOMSG2OF.js → snapshot-JOGZWESK.js} +2 -2
  28. package/dist/{snapshot-Q3CALMHD.js → snapshot-MUXE7KXX.js} +3 -3
  29. package/dist/{snapshot-Q3CALMHD.js.map → snapshot-MUXE7KXX.js.map} +1 -1
  30. package/examples/README.md +46 -0
  31. package/examples/demo-host/index.html +163 -0
  32. package/examples/demo-host/serve.mjs +62 -0
  33. package/examples/embed-demo/.env.example +24 -0
  34. package/examples/embed-demo/README.md +72 -0
  35. package/examples/embed-demo/index.html +12 -0
  36. package/examples/embed-demo/package.json +25 -0
  37. package/examples/embed-demo/src/App.tsx +239 -0
  38. package/examples/embed-demo/src/config.ts +43 -0
  39. package/examples/embed-demo/src/main.tsx +10 -0
  40. package/examples/embed-demo/src/styles.css +354 -0
  41. package/examples/embed-demo/tsconfig.json +16 -0
  42. package/examples/embed-demo/vite.config.ts +11 -0
  43. package/examples/host-panel.html +259 -0
  44. package/package.json +3 -2
  45. package/dist/chunk-SBNMM3ZV.js.map +0 -1
  46. package/dist/chunk-URIBHOOQ.js +0 -2
  47. package/dist/chunk-XLQ36ZMV.js +0 -2
  48. package/dist/chunk-XLQ36ZMV.js.map +0 -7
  49. package/dist/chunk-Z4WT3TIZ.js.map +0 -1
  50. package/dist/context-KZAUOIR6.js +0 -3
  51. /package/dist/{chunk-523BCS2Z.js.map → chunk-4Q2ROXLR.js.map} +0 -0
  52. /package/dist/{chunk-URIBHOOQ.js.map → chunk-7I37ZFAJ.js.map} +0 -0
  53. /package/dist/{context-432WQST4.js.map → context-WU2F5CBC.js.map} +0 -0
  54. /package/dist/{snapshot-SOMSG2OF.js.map → snapshot-JOGZWESK.js.map} +0 -0
package/dist/react.cjs CHANGED
@@ -499,10 +499,11 @@ var init_snapshot = __esm({
499
499
  var context_exports = {};
500
500
  __export(context_exports, {
501
501
  artifactIdFromPath: () => artifactIdFromPath,
502
- beginAuth: () => beginAuth,
502
+ buildPageContext: () => buildPageContext,
503
503
  callTool: () => callTool,
504
504
  grantsFromIframeSrcs: () => grantsFromIframeSrcs,
505
505
  isPrivate: () => isPrivate,
506
+ provideContext: () => provideContext,
506
507
  readPageContext: () => readPageContext,
507
508
  redact: () => redact,
508
509
  sendRegion: () => sendRegion,
@@ -560,8 +561,7 @@ function opaqueFrameCount() {
560
561
  }
561
562
  }).length;
562
563
  }
563
- function readPageContext() {
564
- const declared = window.matterfact?.context ?? {};
564
+ function buildPageContext(declared) {
565
565
  const found = embeddedMatterfactEntities();
566
566
  const opaque = opaqueFrameCount();
567
567
  return {
@@ -582,8 +582,30 @@ function readPageContext() {
582
582
  }
583
583
  };
584
584
  }
585
- function publishContext() {
586
- send?.({ type: "host.context", context: readPageContext() });
585
+ function readPageContext() {
586
+ return buildPageContext(
587
+ window.matterfact?.context ?? {}
588
+ );
589
+ }
590
+ async function resolveDeclaredContext() {
591
+ const mf = window.matterfact;
592
+ if (contextProvider) {
593
+ const c = await contextProvider();
594
+ if (c) return c;
595
+ }
596
+ if (mf?.getPageContext) {
597
+ const c = await mf.getPageContext();
598
+ if (c) return c;
599
+ }
600
+ return mf?.context ?? {};
601
+ }
602
+ async function publishContext() {
603
+ if (!pageContextOn) return;
604
+ const declared = await resolveDeclaredContext();
605
+ send?.({ type: "host.context", context: buildPageContext(declared) });
606
+ }
607
+ function provideContext() {
608
+ void publishContext();
587
609
  }
588
610
  function grantsFromIframeSrcs(srcs, origin) {
589
611
  const out = [];
@@ -675,7 +697,7 @@ function watchNavigation() {
675
697
  if (url === lastUrl) return;
676
698
  lastUrl = url;
677
699
  pushActivity({ type: "nav", summary: `navigated to ${url}` });
678
- publishContext();
700
+ void publishContext();
679
701
  publishArtifactGrants();
680
702
  };
681
703
  navFire = fire;
@@ -765,27 +787,6 @@ async function callTool(call, emit) {
765
787
  error: "Host tools are read-only in this version; no action was taken."
766
788
  });
767
789
  }
768
- function beginAuth(config, emit) {
769
- const w = window.open(
770
- `${config.origin}/embed/authorize?k=${encodeURIComponent(
771
- config.publishableKey
772
- )}&o=${encodeURIComponent(location.origin)}`,
773
- "mf_auth",
774
- "width=460,height=640"
775
- );
776
- if (!w) return;
777
- if (pendingAuthListener) window.removeEventListener("message", pendingAuthListener);
778
- const onMsg = (event) => {
779
- if (event.origin !== config.origin) return;
780
- const d = event.data;
781
- if (d?.type !== "mf:embed:auth") return;
782
- window.removeEventListener("message", onMsg);
783
- pendingAuthListener = null;
784
- emit({ type: "host.auth", token: d.token, expiresAt: d.expiresAt });
785
- };
786
- pendingAuthListener = onMsg;
787
- window.addEventListener("message", onMsg);
788
- }
789
790
  function stop() {
790
791
  document.removeEventListener("click", onClick, { capture: true });
791
792
  document.removeEventListener("submit", onSubmit, { capture: true });
@@ -805,31 +806,32 @@ function stop() {
805
806
  history.replaceState = origReplaceState;
806
807
  origReplaceState = null;
807
808
  }
808
- if (pendingAuthListener) {
809
- window.removeEventListener("message", pendingAuthListener);
810
- pendingAuthListener = null;
811
- }
812
809
  if (focusTimer) {
813
810
  clearTimeout(focusTimer);
814
811
  focusTimer = null;
815
812
  }
816
813
  send = null;
814
+ contextProvider = void 0;
817
815
  activity.length = 0;
818
816
  lastFocus = {};
819
817
  widgetOrigin = "";
820
818
  snapshotModule?.clearRefs();
821
819
  }
822
- function start(emit, origin, pageContext = true) {
820
+ function start(emit, origin, pageContext = true, provider) {
823
821
  stop();
824
822
  send = emit;
825
823
  widgetOrigin = origin || "";
826
824
  lastUrl = location.pathname;
827
825
  pageContextOn = pageContext;
826
+ contextProvider = provider;
828
827
  if (pageContextOn) {
829
- publishContext();
828
+ void publishContext();
830
829
  publishArtifactGrants();
831
830
  watchNavigation();
832
- document.addEventListener("click", onClick, { capture: true, passive: true });
831
+ document.addEventListener("click", onClick, {
832
+ capture: true,
833
+ passive: true
834
+ });
833
835
  document.addEventListener("submit", onSubmit, {
834
836
  capture: true,
835
837
  passive: true
@@ -853,7 +855,7 @@ function start(emit, origin, pageContext = true) {
853
855
  const theme = matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
854
856
  emit({ type: "host.theme", mode: theme });
855
857
  }
856
- var widgetOrigin, MAX_ACTIVITY, send, activitySeq, activity, lastUrl, pageContextOn, navFire, origPushState, origReplaceState, pendingAuthListener, snapshotModule, PII, FORM_CONTROLS, ACTIONABLE, lastFocus, focusTimer, snapshotSeq;
858
+ var widgetOrigin, MAX_ACTIVITY, send, activitySeq, activity, lastUrl, pageContextOn, contextProvider, navFire, origPushState, origReplaceState, snapshotModule, PII, FORM_CONTROLS, ACTIONABLE, lastFocus, focusTimer, snapshotSeq;
857
859
  var init_context = __esm({
858
860
  "src/context.ts"() {
859
861
  "use strict";
@@ -867,7 +869,6 @@ var init_context = __esm({
867
869
  navFire = null;
868
870
  origPushState = null;
869
871
  origReplaceState = null;
870
- pendingAuthListener = null;
871
872
  snapshotModule = null;
872
873
  PII = [
873
874
  /\b[\w.+-]+@[\w-]+\.[\w.]{2,}\b/g,
@@ -989,6 +990,9 @@ var EmbedHost = class {
989
990
  this.iframe.style.height = `${Math.min(msg.height, window.innerHeight - 40)}px`;
990
991
  }
991
992
  break;
993
+ case "widget.requestContext":
994
+ void this.loadContext().then((m) => m.provideContext());
995
+ break;
992
996
  case "widget.requestSnapshot":
993
997
  void this.loadContext().then((m) => m.sendSnapshot(this.send));
994
998
  break;
@@ -1160,27 +1164,31 @@ var EmbedHost = class {
1160
1164
  * window.matterfact = { getEmbedAuthToken: () => getIdToken(user) };
1161
1165
  *
1162
1166
  * Read fresh at call time (not at readConfig), so a global set after the loader booted
1163
- * — e.g. once the host's auth is ready — is still picked up. Otherwise fall back to the
1164
- * hosted-login popup. `expiresAt: 0`: the widget doesn't cache it, it exchanges the
1165
- * token for a rotating embed session anyway.
1167
+ * — e.g. once the host's auth is ready — is still picked up. `expiresAt: 0`: the widget
1168
+ * doesn't cache it, it exchanges the token for a rotating embed session anyway.
1169
+ *
1170
+ * No provider ⇒ this does nothing. The loader never opens a sign-in popup — the widget
1171
+ * owns interactive sign-in (inline Firebase/email, and Microsoft's own MSAL login popup
1172
+ * for Entra, then the PKCE token exchange), so the loader must not also fire its stale
1173
+ * `/embed/authorize?k=&o=` popup, which the deployed authorize page no longer accepts.
1166
1174
  */
1167
1175
  async provideAuth() {
1168
1176
  const provider = this.config.authTokenProvider ?? globalThis.matterfact?.getEmbedAuthToken;
1169
- if (provider) {
1170
- try {
1171
- const token = await provider();
1172
- if (token) {
1173
- this.send({ type: "host.auth", token, expiresAt: 0 });
1174
- return;
1175
- }
1176
- } catch {
1177
- }
1177
+ if (!provider) return;
1178
+ try {
1179
+ const token = await provider();
1180
+ if (token) this.send({ type: "host.auth", token, expiresAt: 0 });
1181
+ } catch {
1178
1182
  }
1179
- void this.loadContext().then((m) => m.beginAuth(this.config, this.send));
1180
1183
  }
1181
1184
  loadContext() {
1182
1185
  this.context ?? (this.context = Promise.resolve().then(() => (init_context(), context_exports)).then((m) => {
1183
- m.start(this.send, this.config.origin, this.config.pageContext);
1186
+ m.start(
1187
+ this.send,
1188
+ this.config.origin,
1189
+ this.config.pageContext,
1190
+ this.config.pageContextProvider
1191
+ );
1184
1192
  if (this.config.theme !== "auto") {
1185
1193
  this.send({ type: "host.theme", mode: this.config.theme });
1186
1194
  }
@@ -1221,6 +1229,7 @@ function MatterfactAgent({
1221
1229
  surface = "",
1222
1230
  theme = "auto",
1223
1231
  getAuthToken,
1232
+ getPageContext,
1224
1233
  inline = false,
1225
1234
  className,
1226
1235
  style,
@@ -1229,6 +1238,8 @@ function MatterfactAgent({
1229
1238
  }) {
1230
1239
  const authRef = (0, import_react.useRef)(getAuthToken);
1231
1240
  authRef.current = getAuthToken;
1241
+ const pageContextRef = (0, import_react.useRef)(getPageContext);
1242
+ pageContextRef.current = getPageContext;
1232
1243
  const slot = (0, import_react.useRef)(null);
1233
1244
  (0, import_react.useEffect)(() => {
1234
1245
  if (typeof window === "undefined") return;
@@ -1241,6 +1252,9 @@ function MatterfactAgent({
1241
1252
  // Always present; a null return (no getAuthToken supplied) makes the core fall
1242
1253
  // back to the popup/inline sign-in, so this is safe either way.
1243
1254
  authTokenProvider: async () => await authRef.current?.() ?? null,
1255
+ // Always present; a null return (no getPageContext supplied) makes the core fall
1256
+ // back to window.matterfact.getPageContext / window.matterfact.context.
1257
+ pageContextProvider: async () => await pageContextRef.current?.() ?? null,
1244
1258
  container: inline ? slot.current : null,
1245
1259
  pageContext,
1246
1260
  dev