@matterfact/embed 0.16.0 → 0.17.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 +25 -0
- package/dist/chunk-QVNE5FQV.js +2 -0
- package/dist/chunk-QVNE5FQV.js.map +7 -0
- package/dist/deeplink-IBFUWANV.js +104 -0
- package/dist/deeplink-IBFUWANV.js.map +1 -0
- package/dist/deeplink-QW3VRPOY.js +101 -0
- package/dist/deeplink-QW3VRPOY.js.map +1 -0
- package/dist/embed.js +1 -1
- package/dist/embed.js.map +3 -3
- package/dist/index.cjs +131 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.js +23 -3
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +135 -6
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +19 -7
- package/dist/react.d.ts +19 -7
- package/dist/react.js +26 -6
- package/dist/react.js.map +1 -1
- package/examples/embed-demo/src/App.tsx +6 -0
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* shapes are right, "deeper integration" is a transport swap (postMessage ->
|
|
19
19
|
* direct call), not a rewrite. So model the DOMAIN here, not the plumbing.
|
|
20
20
|
*/
|
|
21
|
-
declare const PROTOCOL_VERSION =
|
|
21
|
+
declare const PROTOCOL_VERSION = 4;
|
|
22
22
|
/** Every message is namespaced so we never collide with the host page's own postMessage traffic. */
|
|
23
23
|
declare const CHANNEL = "mf-embed";
|
|
24
24
|
/**
|
|
@@ -346,6 +346,26 @@ type HostToWidget = {
|
|
|
346
346
|
type: 'host.theme';
|
|
347
347
|
mode: 'light' | 'dark';
|
|
348
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* The share-link template the integration configured on the loader
|
|
351
|
+
* (`shareDeeplinkFormat`), e.g. `https://portal.acme.com/share/{share_token}`. Sent
|
|
352
|
+
* at mount; the widget mints "Share chat" links in this format. Absent config ⇒
|
|
353
|
+
* never sent, and the widget falls back to its own share route.
|
|
354
|
+
*/
|
|
355
|
+
| {
|
|
356
|
+
type: 'host.deeplinkFormat';
|
|
357
|
+
format: string;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* The host page's URL matches that same template, and this is the share token it
|
|
361
|
+
* carries — or `null` the moment the user navigates off it. Only the loader can see
|
|
362
|
+
* the host URL, so only the loader can report this; the widget opens (or closes) the
|
|
363
|
+
* shared thread on the back of it.
|
|
364
|
+
*/
|
|
365
|
+
| {
|
|
366
|
+
type: 'host.openShare';
|
|
367
|
+
token: string | null;
|
|
368
|
+
}
|
|
349
369
|
/**
|
|
350
370
|
* Where the widget currently IS. Sent on mount and after anything that moves it
|
|
351
371
|
* (drag, snap, mode change, viewport resize).
|
|
@@ -669,6 +689,14 @@ interface LoaderConfig {
|
|
|
669
689
|
* the URL param still works untouched; `mount()` ORs the two together.
|
|
670
690
|
*/
|
|
671
691
|
dev?: boolean;
|
|
692
|
+
/**
|
|
693
|
+
* Host-site share-link template. The widget mints "Share chat" links in this format,
|
|
694
|
+
* and this loader watches the host URL for a match so a visitor landing on one opens
|
|
695
|
+
* that conversation. Exactly one `{share_token}`, as a whole path segment or whole
|
|
696
|
+
* query value, e.g. `https://portal.acme.com/assistant?mf_share={share_token}`.
|
|
697
|
+
* Absent ⇒ no watch is installed and the widget keeps its own share route.
|
|
698
|
+
*/
|
|
699
|
+
shareDeeplinkFormat?: string;
|
|
672
700
|
}
|
|
673
701
|
declare function readConfig(): LoaderConfig | null;
|
|
674
702
|
declare class EmbedHost {
|
|
@@ -706,6 +734,12 @@ declare class EmbedHost {
|
|
|
706
734
|
private dragLeftBand;
|
|
707
735
|
/** Loaded on first open. Holds everything that touches the customer's DOM. */
|
|
708
736
|
private context;
|
|
737
|
+
/** Uninstall for the share-deeplink URL watch. No initializer on purpose: an `= null`
|
|
738
|
+
* emits a constructor assignment into the size-budgeted stub for no behaviour. */
|
|
739
|
+
private deeplinkStop?;
|
|
740
|
+
/** Set once `destroy()` has run; falsy (never assigned) otherwise — no initializer,
|
|
741
|
+
* same reasoning as `deeplinkStop` above. */
|
|
742
|
+
private destroyed?;
|
|
709
743
|
/** The host element; kept so `destroy()` can remove it (React lifecycle). */
|
|
710
744
|
private hostEl;
|
|
711
745
|
/** Rendering into the host's own element: they own the box, the chrome and visibility. */
|
package/dist/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* shapes are right, "deeper integration" is a transport swap (postMessage ->
|
|
19
19
|
* direct call), not a rewrite. So model the DOMAIN here, not the plumbing.
|
|
20
20
|
*/
|
|
21
|
-
declare const PROTOCOL_VERSION =
|
|
21
|
+
declare const PROTOCOL_VERSION = 4;
|
|
22
22
|
/** Every message is namespaced so we never collide with the host page's own postMessage traffic. */
|
|
23
23
|
declare const CHANNEL = "mf-embed";
|
|
24
24
|
/**
|
|
@@ -346,6 +346,26 @@ type HostToWidget = {
|
|
|
346
346
|
type: 'host.theme';
|
|
347
347
|
mode: 'light' | 'dark';
|
|
348
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* The share-link template the integration configured on the loader
|
|
351
|
+
* (`shareDeeplinkFormat`), e.g. `https://portal.acme.com/share/{share_token}`. Sent
|
|
352
|
+
* at mount; the widget mints "Share chat" links in this format. Absent config ⇒
|
|
353
|
+
* never sent, and the widget falls back to its own share route.
|
|
354
|
+
*/
|
|
355
|
+
| {
|
|
356
|
+
type: 'host.deeplinkFormat';
|
|
357
|
+
format: string;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* The host page's URL matches that same template, and this is the share token it
|
|
361
|
+
* carries — or `null` the moment the user navigates off it. Only the loader can see
|
|
362
|
+
* the host URL, so only the loader can report this; the widget opens (or closes) the
|
|
363
|
+
* shared thread on the back of it.
|
|
364
|
+
*/
|
|
365
|
+
| {
|
|
366
|
+
type: 'host.openShare';
|
|
367
|
+
token: string | null;
|
|
368
|
+
}
|
|
349
369
|
/**
|
|
350
370
|
* Where the widget currently IS. Sent on mount and after anything that moves it
|
|
351
371
|
* (drag, snap, mode change, viewport resize).
|
|
@@ -669,6 +689,14 @@ interface LoaderConfig {
|
|
|
669
689
|
* the URL param still works untouched; `mount()` ORs the two together.
|
|
670
690
|
*/
|
|
671
691
|
dev?: boolean;
|
|
692
|
+
/**
|
|
693
|
+
* Host-site share-link template. The widget mints "Share chat" links in this format,
|
|
694
|
+
* and this loader watches the host URL for a match so a visitor landing on one opens
|
|
695
|
+
* that conversation. Exactly one `{share_token}`, as a whole path segment or whole
|
|
696
|
+
* query value, e.g. `https://portal.acme.com/assistant?mf_share={share_token}`.
|
|
697
|
+
* Absent ⇒ no watch is installed and the widget keeps its own share route.
|
|
698
|
+
*/
|
|
699
|
+
shareDeeplinkFormat?: string;
|
|
672
700
|
}
|
|
673
701
|
declare function readConfig(): LoaderConfig | null;
|
|
674
702
|
declare class EmbedHost {
|
|
@@ -706,6 +734,12 @@ declare class EmbedHost {
|
|
|
706
734
|
private dragLeftBand;
|
|
707
735
|
/** Loaded on first open. Holds everything that touches the customer's DOM. */
|
|
708
736
|
private context;
|
|
737
|
+
/** Uninstall for the share-deeplink URL watch. No initializer on purpose: an `= null`
|
|
738
|
+
* emits a constructor assignment into the size-budgeted stub for no behaviour. */
|
|
739
|
+
private deeplinkStop?;
|
|
740
|
+
/** Set once `destroy()` has run; falsy (never assigned) otherwise — no initializer,
|
|
741
|
+
* same reasoning as `deeplinkStop` above. */
|
|
742
|
+
private destroyed?;
|
|
709
743
|
/** The host element; kept so `destroy()` can remove it (React lifecycle). */
|
|
710
744
|
private hostEl;
|
|
711
745
|
/** Rendering into the host's own element: they own the box, the chrome and visibility. */
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/protocol.ts
|
|
2
|
-
var PROTOCOL_VERSION =
|
|
2
|
+
var PROTOCOL_VERSION = 4;
|
|
3
3
|
var CHANNEL = "mf-embed";
|
|
4
4
|
function envelope(payload, id) {
|
|
5
5
|
return {
|
|
@@ -222,6 +222,7 @@ function dockBox(g, vw, _vh) {
|
|
|
222
222
|
|
|
223
223
|
// src/loader.ts
|
|
224
224
|
var DEFAULT_ORIGIN = "https://app.matterfact.com";
|
|
225
|
+
var EMBED_VERSION = "0.17.0";
|
|
225
226
|
function devRequested() {
|
|
226
227
|
try {
|
|
227
228
|
if (new URLSearchParams(location.search).get("mfdev") === "1") return true;
|
|
@@ -266,7 +267,10 @@ function readConfig() {
|
|
|
266
267
|
theme: el?.dataset.theme || "auto",
|
|
267
268
|
surface: el?.dataset.surface || "",
|
|
268
269
|
container,
|
|
269
|
-
pageContext
|
|
270
|
+
pageContext,
|
|
271
|
+
// `data-share-deeplink-format="https://…/{share_token}"` — the script-tag twin of
|
|
272
|
+
// the React `shareDeeplinkFormat` prop.
|
|
273
|
+
shareDeeplinkFormat: el?.dataset.shareDeeplinkFormat
|
|
270
274
|
// No `data-dev` — see the `dev` field's doc comment: the URL trigger is the
|
|
271
275
|
// point for the script-tag path, so there is deliberately no script-tag knob here.
|
|
272
276
|
// No `data-actions` either: the action policy lives entirely in the lazy chunk,
|
|
@@ -347,6 +351,8 @@ var EmbedHost = class {
|
|
|
347
351
|
this.inline = !!config.container;
|
|
348
352
|
}
|
|
349
353
|
mount() {
|
|
354
|
+
const w = window;
|
|
355
|
+
(w.matterfact ?? (w.matterfact = {})).embedVersion = EMBED_VERSION;
|
|
350
356
|
const host = document.createElement("div");
|
|
351
357
|
this.hostEl = host;
|
|
352
358
|
host.id = "matterfact-embed";
|
|
@@ -390,7 +396,7 @@ var EmbedHost = class {
|
|
|
390
396
|
"sandbox",
|
|
391
397
|
"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads"
|
|
392
398
|
);
|
|
393
|
-
iframe.setAttribute("allow", "microphone; clipboard-write");
|
|
399
|
+
iframe.setAttribute("allow", "microphone; clipboard-write; web-share");
|
|
394
400
|
iframe.src = `${this.config.origin}/embed/chat?k=${encodeURIComponent(
|
|
395
401
|
this.config.publishableKey
|
|
396
402
|
)}&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
|
|
@@ -403,6 +409,17 @@ var EmbedHost = class {
|
|
|
403
409
|
window.addEventListener("resize", this.onViewportResize);
|
|
404
410
|
this.place();
|
|
405
411
|
}
|
|
412
|
+
const fmt = this.config.shareDeeplinkFormat;
|
|
413
|
+
if (fmt) {
|
|
414
|
+
this.send({ type: "host.deeplinkFormat", format: fmt });
|
|
415
|
+
void import('./deeplink-QW3VRPOY.js').then((m) => {
|
|
416
|
+
if (this.destroyed) return;
|
|
417
|
+
this.deeplinkStop = m.installDeeplinkWatch(fmt, (token) => {
|
|
418
|
+
this.send({ type: "host.openShare", token });
|
|
419
|
+
});
|
|
420
|
+
}).catch(() => {
|
|
421
|
+
});
|
|
422
|
+
}
|
|
406
423
|
}
|
|
407
424
|
/**
|
|
408
425
|
* Test seam. The shadow root is CLOSED, so a test cannot reach the iframe to forge a
|
|
@@ -825,6 +842,9 @@ var EmbedHost = class {
|
|
|
825
842
|
this.iframe = null;
|
|
826
843
|
this.shadow = null;
|
|
827
844
|
this.ready = false;
|
|
845
|
+
this.destroyed = true;
|
|
846
|
+
this.deeplinkStop?.();
|
|
847
|
+
this.deeplinkStop = null;
|
|
828
848
|
void this.context?.then((m) => m.stop());
|
|
829
849
|
}
|
|
830
850
|
};
|