@matterfact/embed 0.3.0 → 0.4.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 (42) hide show
  1. package/README.md +20 -0
  2. package/dist/{chunk-33LPVL2R.js → chunk-523BCS2Z.js} +3 -3
  3. package/dist/{chunk-33LPVL2R.js.map → chunk-523BCS2Z.js.map} +3 -3
  4. package/dist/{chunk-SQJX27LT.js → chunk-SBNMM3ZV.js} +85 -28
  5. package/dist/chunk-SBNMM3ZV.js.map +1 -0
  6. package/dist/chunk-URIBHOOQ.js +2 -0
  7. package/dist/chunk-XLQ36ZMV.js +2 -0
  8. package/dist/chunk-XLQ36ZMV.js.map +7 -0
  9. package/dist/{chunk-CHPADW72.js → chunk-Z4WT3TIZ.js} +86 -30
  10. package/dist/chunk-Z4WT3TIZ.js.map +1 -0
  11. package/dist/{context-MORDASRH.js → context-432WQST4.js} +6 -4
  12. package/dist/context-KZAUOIR6.js +3 -0
  13. package/dist/{context-BFNFFHC2.js.map → context-KZAUOIR6.js.map} +1 -1
  14. package/dist/embed.js +1 -1
  15. package/dist/embed.js.map +3 -3
  16. package/dist/index.cjs +100 -32
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +16 -0
  19. package/dist/index.d.ts +16 -0
  20. package/dist/index.js +11 -4
  21. package/dist/index.js.map +1 -1
  22. package/dist/react.cjs +102 -34
  23. package/dist/react.cjs.map +1 -1
  24. package/dist/react.d.cts +14 -1
  25. package/dist/react.d.ts +14 -1
  26. package/dist/react.js +13 -6
  27. package/dist/react.js.map +1 -1
  28. package/dist/{snapshot-QBV7DTJP.js → snapshot-Q3CALMHD.js} +7 -4
  29. package/dist/snapshot-Q3CALMHD.js.map +1 -0
  30. package/dist/{snapshot-IWVXLE4G.js → snapshot-SOMSG2OF.js} +6 -2
  31. package/dist/snapshot-SOMSG2OF.js.map +1 -0
  32. package/package.json +1 -1
  33. package/dist/chunk-CHPADW72.js.map +0 -1
  34. package/dist/chunk-F7DLOR7F.js +0 -2
  35. package/dist/chunk-F7DLOR7F.js.map +0 -7
  36. package/dist/chunk-FBIJZJGL.js +0 -2
  37. package/dist/chunk-SQJX27LT.js.map +0 -1
  38. package/dist/context-BFNFFHC2.js +0 -3
  39. package/dist/snapshot-IWVXLE4G.js.map +0 -1
  40. package/dist/snapshot-QBV7DTJP.js.map +0 -1
  41. /package/dist/{chunk-FBIJZJGL.js.map → chunk-URIBHOOQ.js.map} +0 -0
  42. /package/dist/{context-MORDASRH.js.map → context-432WQST4.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
@@ -486,7 +490,8 @@ __export(context_exports, {
486
490
  redact: () => redact,
487
491
  sendRegion: () => sendRegion,
488
492
  sendSnapshot: () => sendSnapshot,
489
- start: () => start
493
+ start: () => start,
494
+ stop: () => stop
490
495
  });
491
496
  function redact(text) {
492
497
  let out = text;
@@ -656,8 +661,11 @@ function watchNavigation() {
656
661
  publishContext();
657
662
  publishArtifactGrants();
658
663
  };
664
+ navFire = fire;
659
665
  for (const name of ["pushState", "replaceState"]) {
660
666
  const orig = history[name];
667
+ if (name === "pushState") origPushState = orig;
668
+ else origReplaceState = orig;
661
669
  history[name] = function(...args) {
662
670
  const r = orig.apply(this, args);
663
671
  fire();
@@ -678,7 +686,7 @@ async function readFocus() {
678
686
  }
679
687
  const active = document.activeElement;
680
688
  if (active && active !== document.body && !isPrivate(active) && !active.closest("[data-mf-private]")) {
681
- const { snapshot: snapshot2 } = await Promise.resolve().then(() => (init_snapshot(), snapshot_exports));
689
+ const { snapshot: snapshot2 } = await loadSnapshotModule();
682
690
  focus.focused = {
683
691
  label: redact(describeControl(active)),
684
692
  role: active.getAttribute("role") || active.tagName.toLowerCase()
@@ -692,6 +700,11 @@ async function readFocus() {
692
700
  function describeControl(el) {
693
701
  return describe(el);
694
702
  }
703
+ async function loadSnapshotModule() {
704
+ const m = await Promise.resolve().then(() => (init_snapshot(), snapshot_exports));
705
+ snapshotModule = m;
706
+ return m;
707
+ }
695
708
  function scheduleFocus() {
696
709
  if (focusTimer) return;
697
710
  focusTimer = setTimeout(async () => {
@@ -701,7 +714,8 @@ function scheduleFocus() {
701
714
  }, 250);
702
715
  }
703
716
  async function sendSnapshot(emit) {
704
- const { snapshot: snapshot2 } = await Promise.resolve().then(() => (init_snapshot(), snapshot_exports));
717
+ if (!pageContextOn) return;
718
+ const { snapshot: snapshot2 } = await loadSnapshotModule();
705
719
  const { yaml, truncated, visibleRefs } = snapshot2();
706
720
  emit({
707
721
  type: "host.snapshot",
@@ -711,7 +725,8 @@ async function sendSnapshot(emit) {
711
725
  emit({ type: "host.focus", focus: lastFocus });
712
726
  }
713
727
  async function sendRegion(ref, emit) {
714
- const { snapshotRegion: snapshotRegion2, resolveRef: resolveRef2 } = await Promise.resolve().then(() => (init_snapshot(), snapshot_exports));
728
+ if (!pageContextOn) return;
729
+ const { snapshotRegion: snapshotRegion2, resolveRef: resolveRef2 } = await loadSnapshotModule();
715
730
  const el = resolveRef2(ref);
716
731
  if (!el) {
717
732
  emit({
@@ -741,46 +756,86 @@ function beginAuth(config, emit) {
741
756
  "width=460,height=640"
742
757
  );
743
758
  if (!w) return;
759
+ if (pendingAuthListener) window.removeEventListener("message", pendingAuthListener);
744
760
  const onMsg = (event) => {
745
761
  if (event.origin !== config.origin) return;
746
762
  const d = event.data;
747
763
  if (d?.type !== "mf:embed:auth") return;
748
764
  window.removeEventListener("message", onMsg);
765
+ pendingAuthListener = null;
749
766
  emit({ type: "host.auth", token: d.token, expiresAt: d.expiresAt });
750
767
  };
768
+ pendingAuthListener = onMsg;
751
769
  window.addEventListener("message", onMsg);
752
770
  }
753
- function start(emit, origin) {
771
+ function stop() {
772
+ document.removeEventListener("click", onClick, { capture: true });
773
+ document.removeEventListener("submit", onSubmit, { capture: true });
774
+ document.removeEventListener("change", onChange, { capture: true });
775
+ document.removeEventListener("selectionchange", scheduleFocus);
776
+ document.removeEventListener("focusin", scheduleFocus, { capture: true });
777
+ window.removeEventListener("scroll", scheduleFocus, { capture: true });
778
+ if (navFire) {
779
+ window.removeEventListener("popstate", navFire);
780
+ navFire = null;
781
+ }
782
+ if (origPushState) {
783
+ history.pushState = origPushState;
784
+ origPushState = null;
785
+ }
786
+ if (origReplaceState) {
787
+ history.replaceState = origReplaceState;
788
+ origReplaceState = null;
789
+ }
790
+ if (pendingAuthListener) {
791
+ window.removeEventListener("message", pendingAuthListener);
792
+ pendingAuthListener = null;
793
+ }
794
+ if (focusTimer) {
795
+ clearTimeout(focusTimer);
796
+ focusTimer = null;
797
+ }
798
+ send = null;
799
+ activity.length = 0;
800
+ lastFocus = {};
801
+ widgetOrigin = "";
802
+ snapshotModule?.clearRefs();
803
+ }
804
+ function start(emit, origin, pageContext = true) {
805
+ stop();
754
806
  send = emit;
755
807
  widgetOrigin = origin || "";
756
808
  lastUrl = location.pathname;
757
- publishContext();
758
- publishArtifactGrants();
759
- watchNavigation();
760
- document.addEventListener("click", onClick, { capture: true, passive: true });
761
- document.addEventListener("submit", onSubmit, {
762
- capture: true,
763
- passive: true
764
- });
765
- document.addEventListener("change", onChange, {
766
- capture: true,
767
- passive: true
768
- });
769
- document.addEventListener("selectionchange", scheduleFocus, {
770
- passive: true
771
- });
772
- document.addEventListener("focusin", scheduleFocus, {
773
- capture: true,
774
- passive: true
775
- });
776
- window.addEventListener("scroll", scheduleFocus, {
777
- capture: true,
778
- passive: true
779
- });
809
+ pageContextOn = pageContext;
810
+ if (pageContextOn) {
811
+ publishContext();
812
+ publishArtifactGrants();
813
+ watchNavigation();
814
+ document.addEventListener("click", onClick, { capture: true, passive: true });
815
+ document.addEventListener("submit", onSubmit, {
816
+ capture: true,
817
+ passive: true
818
+ });
819
+ document.addEventListener("change", onChange, {
820
+ capture: true,
821
+ passive: true
822
+ });
823
+ document.addEventListener("selectionchange", scheduleFocus, {
824
+ passive: true
825
+ });
826
+ document.addEventListener("focusin", scheduleFocus, {
827
+ capture: true,
828
+ passive: true
829
+ });
830
+ window.addEventListener("scroll", scheduleFocus, {
831
+ capture: true,
832
+ passive: true
833
+ });
834
+ }
780
835
  const theme = matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
781
836
  emit({ type: "host.theme", mode: theme });
782
837
  }
783
- var widgetOrigin, MAX_ACTIVITY, send, activitySeq, activity, lastUrl, PII, FORM_CONTROLS, ACTIONABLE, lastFocus, focusTimer, snapshotSeq;
838
+ var widgetOrigin, MAX_ACTIVITY, send, activitySeq, activity, lastUrl, pageContextOn, navFire, origPushState, origReplaceState, pendingAuthListener, snapshotModule, PII, FORM_CONTROLS, ACTIONABLE, lastFocus, focusTimer, snapshotSeq;
784
839
  var init_context = __esm({
785
840
  "src/context.ts"() {
786
841
  widgetOrigin = "";
@@ -789,6 +844,12 @@ var init_context = __esm({
789
844
  activitySeq = 0;
790
845
  activity = [];
791
846
  lastUrl = "";
847
+ pageContextOn = true;
848
+ navFire = null;
849
+ origPushState = null;
850
+ origReplaceState = null;
851
+ pendingAuthListener = null;
852
+ snapshotModule = null;
792
853
  PII = [
793
854
  /\b[\w.+-]+@[\w-]+\.[\w.]{2,}\b/g,
794
855
  // email
@@ -851,12 +912,16 @@ function readConfig() {
851
912
  `[matterfact] data-container="${sel}" matched nothing; falling back to the corner`
852
913
  );
853
914
  }
915
+ const pageContextAttr = el?.dataset.pageContext?.toLowerCase();
854
916
  return {
855
917
  publishableKey,
856
918
  origin: el?.dataset.origin || DEFAULT_ORIGIN,
857
919
  theme: el?.dataset.theme || "auto",
858
920
  surface: el?.dataset.surface || "",
859
- container
921
+ container,
922
+ pageContext: pageContextAttr !== "off" && pageContextAttr !== "false" && pageContextAttr !== "0"
923
+ // No `data-dev` — see the `dev` field's doc comment: the URL trigger is the
924
+ // point for the script-tag path, so there is deliberately no script-tag knob here.
860
925
  };
861
926
  }
862
927
  var POS_KEY = "mf.embed.pos";
@@ -1022,7 +1087,9 @@ var EmbedHost = class {
1022
1087
  iframe.setAttribute("allow", "microphone");
1023
1088
  iframe.src = `${this.config.origin}/embed/chat?k=${encodeURIComponent(
1024
1089
  this.config.publishableKey
1025
- )}&o=${encodeURIComponent(location.origin)}` + (this.config.surface ? `&s=${encodeURIComponent(this.config.surface)}` : "") + (devRequested() ? "&dev=1" : "") + (this.inline ? "&inline=1" : "");
1090
+ )}&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
1091
+ // programmatic `dev` (the React prop). See both doc comments above.
1092
+ (devRequested() || this.config.dev ? "&dev=1" : "") + (this.inline ? "&inline=1" : "");
1026
1093
  this.iframe = iframe;
1027
1094
  this.shadow.appendChild(iframe);
1028
1095
  window.addEventListener("message", this.onMessage);
@@ -1112,7 +1179,7 @@ var EmbedHost = class {
1112
1179
  }
1113
1180
  loadContext() {
1114
1181
  this.context ?? (this.context = Promise.resolve().then(() => (init_context(), context_exports)).then((m) => {
1115
- m.start(this.send, this.config.origin);
1182
+ m.start(this.send, this.config.origin, this.config.pageContext);
1116
1183
  if (this.config.theme !== "auto") {
1117
1184
  this.send({ type: "host.theme", mode: this.config.theme });
1118
1185
  }
@@ -1135,6 +1202,7 @@ var EmbedHost = class {
1135
1202
  this.iframe = null;
1136
1203
  this.shadow = null;
1137
1204
  this.ready = false;
1205
+ void this.context?.then((m) => m.stop());
1138
1206
  }
1139
1207
  };
1140
1208
  function mount(config) {