@matterfact/embed 0.16.0 → 0.18.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-5X2WFSIL.js +2 -0
- package/dist/chunk-5X2WFSIL.js.map +7 -0
- package/dist/deeplink-KCGMGNIR.js +180 -0
- package/dist/deeplink-KCGMGNIR.js.map +1 -0
- package/dist/deeplink-X7IQDBCR.js +176 -0
- package/dist/deeplink-X7IQDBCR.js.map +1 -0
- package/dist/embed.js +1 -1
- package/dist/embed.js.map +3 -3
- package/dist/index.cjs +208 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -1
- package/dist/index.d.ts +38 -1
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +246 -7
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +32 -7
- package/dist/react.d.ts +32 -7
- package/dist/react.js +61 -7
- package/dist/react.js.map +1 -1
- package/examples/embed-demo/src/App.tsx +6 -0
- package/package.json +1 -1
package/dist/react.d.cts
CHANGED
|
@@ -295,6 +295,28 @@ interface MatterfactAgentProps {
|
|
|
295
295
|
widgetOrigin?: string;
|
|
296
296
|
/** Label for THIS embedding, for per-surface usage/history attribution. */
|
|
297
297
|
surface?: string;
|
|
298
|
+
/**
|
|
299
|
+
* Host-site share-link template. When set, "Share chat" links are minted in this
|
|
300
|
+
* format (`{share_token}` is replaced), and when this page is loaded at a URL
|
|
301
|
+
* matching the template the widget auto-opens that shared conversation.
|
|
302
|
+
* Exactly one `{share_token}`, as a whole path segment or whole query value,
|
|
303
|
+
* e.g. "https://portal.acme.com/assistant?mf_share={share_token}".
|
|
304
|
+
*
|
|
305
|
+
* DYNAMIC form: `{path}` directly after the origin stands for the page's current
|
|
306
|
+
* pathname — one template serves every page a popup install lives on. Links then
|
|
307
|
+
* carry the page the sharer was on, and pickup fires on any page:
|
|
308
|
+
* `` `${location.origin}{path}?mf_share={share_token}` `` (the token must be a
|
|
309
|
+
* query value in this form). Note `{path}` shares the current pathname with the
|
|
310
|
+
* widget; static templates never do.
|
|
311
|
+
*
|
|
312
|
+
* A query-only URL rewrite by your router (boot-time normalisation) does not
|
|
313
|
+
* cancel a picked-up conversation — only a real pathname change does. Your auth
|
|
314
|
+
* flow must still deliver the URL to the page: a redirect that drops the query
|
|
315
|
+
* before this page boots is unrecoverable from here.
|
|
316
|
+
*
|
|
317
|
+
* Read at mount; change requires a remount.
|
|
318
|
+
*/
|
|
319
|
+
shareDeeplinkFormat?: string;
|
|
298
320
|
/** Resolved as `prop ?? MatterfactAuthProvider's theme ?? 'auto'`. */
|
|
299
321
|
theme?: 'light' | 'dark' | 'auto';
|
|
300
322
|
/**
|
|
@@ -409,7 +431,7 @@ interface MatterfactAgentProps {
|
|
|
409
431
|
*/
|
|
410
432
|
onEvent?: (e: MatterfactEvent) => void;
|
|
411
433
|
}
|
|
412
|
-
declare function MatterfactAgent({ publishableKey: publishableKeyProp, widgetOrigin: widgetOriginProp, surface, theme: themeProp, getAuthToken: getAuthTokenProp, getPageContext, inline, className, style, pageContext, dev, actions, sitemap, artifacts, resolve, tools, onToolEvent, onEvent, }: MatterfactAgentProps): react_jsx_runtime.JSX.Element | null;
|
|
434
|
+
declare function MatterfactAgent({ publishableKey: publishableKeyProp, widgetOrigin: widgetOriginProp, surface, shareDeeplinkFormat, theme: themeProp, getAuthToken: getAuthTokenProp, getPageContext, inline, className, style, pageContext, dev, actions, sitemap, artifacts, resolve, tools, onToolEvent, onEvent, ...unknownProps }: MatterfactAgentProps): react_jsx_runtime.JSX.Element | null;
|
|
413
435
|
interface MatterfactArtifactProps {
|
|
414
436
|
/** The artifact's name (its slug). */
|
|
415
437
|
name?: string;
|
|
@@ -476,12 +498,15 @@ interface MatterfactArtifactProps {
|
|
|
476
498
|
* MatterfactAgent is embedded on the same page, the loader sees this iframe and both
|
|
477
499
|
* makes the agent aware of it and (via its token) lets the agent read its data.
|
|
478
500
|
*
|
|
479
|
-
* Two auth modes
|
|
480
|
-
* -
|
|
481
|
-
*
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
*
|
|
501
|
+
* Two auth modes; a provider wins when both are available:
|
|
502
|
+
* - SESSION mode (an ancestor `MatterfactAuthProvider` is present): tokenless,
|
|
503
|
+
* `?k=<publishableKey>&o=<host origin>`, the same authentication
|
|
504
|
+
* `MatterfactAgent` uses. Chosen even when a `token` is ALSO given — with an
|
|
505
|
+
* identity the embed should read as the signed-in user, and it spares the
|
|
506
|
+
* host from stripping a legacy token to get session auth.
|
|
507
|
+
* - TOKEN mode (`token` given, no provider): a standalone share link, `?t=`.
|
|
508
|
+
* This is the LIVE third-party embed path — its `src` format must stay
|
|
509
|
+
* byte-identical.
|
|
485
510
|
* With neither, there is no way for the iframe to authenticate, so no iframe is
|
|
486
511
|
* built at all — matching the "incomplete link" placeholder the embed artifact
|
|
487
512
|
* page itself renders for a missing owner/token.
|
package/dist/react.d.ts
CHANGED
|
@@ -295,6 +295,28 @@ interface MatterfactAgentProps {
|
|
|
295
295
|
widgetOrigin?: string;
|
|
296
296
|
/** Label for THIS embedding, for per-surface usage/history attribution. */
|
|
297
297
|
surface?: string;
|
|
298
|
+
/**
|
|
299
|
+
* Host-site share-link template. When set, "Share chat" links are minted in this
|
|
300
|
+
* format (`{share_token}` is replaced), and when this page is loaded at a URL
|
|
301
|
+
* matching the template the widget auto-opens that shared conversation.
|
|
302
|
+
* Exactly one `{share_token}`, as a whole path segment or whole query value,
|
|
303
|
+
* e.g. "https://portal.acme.com/assistant?mf_share={share_token}".
|
|
304
|
+
*
|
|
305
|
+
* DYNAMIC form: `{path}` directly after the origin stands for the page's current
|
|
306
|
+
* pathname — one template serves every page a popup install lives on. Links then
|
|
307
|
+
* carry the page the sharer was on, and pickup fires on any page:
|
|
308
|
+
* `` `${location.origin}{path}?mf_share={share_token}` `` (the token must be a
|
|
309
|
+
* query value in this form). Note `{path}` shares the current pathname with the
|
|
310
|
+
* widget; static templates never do.
|
|
311
|
+
*
|
|
312
|
+
* A query-only URL rewrite by your router (boot-time normalisation) does not
|
|
313
|
+
* cancel a picked-up conversation — only a real pathname change does. Your auth
|
|
314
|
+
* flow must still deliver the URL to the page: a redirect that drops the query
|
|
315
|
+
* before this page boots is unrecoverable from here.
|
|
316
|
+
*
|
|
317
|
+
* Read at mount; change requires a remount.
|
|
318
|
+
*/
|
|
319
|
+
shareDeeplinkFormat?: string;
|
|
298
320
|
/** Resolved as `prop ?? MatterfactAuthProvider's theme ?? 'auto'`. */
|
|
299
321
|
theme?: 'light' | 'dark' | 'auto';
|
|
300
322
|
/**
|
|
@@ -409,7 +431,7 @@ interface MatterfactAgentProps {
|
|
|
409
431
|
*/
|
|
410
432
|
onEvent?: (e: MatterfactEvent) => void;
|
|
411
433
|
}
|
|
412
|
-
declare function MatterfactAgent({ publishableKey: publishableKeyProp, widgetOrigin: widgetOriginProp, surface, theme: themeProp, getAuthToken: getAuthTokenProp, getPageContext, inline, className, style, pageContext, dev, actions, sitemap, artifacts, resolve, tools, onToolEvent, onEvent, }: MatterfactAgentProps): react_jsx_runtime.JSX.Element | null;
|
|
434
|
+
declare function MatterfactAgent({ publishableKey: publishableKeyProp, widgetOrigin: widgetOriginProp, surface, shareDeeplinkFormat, theme: themeProp, getAuthToken: getAuthTokenProp, getPageContext, inline, className, style, pageContext, dev, actions, sitemap, artifacts, resolve, tools, onToolEvent, onEvent, ...unknownProps }: MatterfactAgentProps): react_jsx_runtime.JSX.Element | null;
|
|
413
435
|
interface MatterfactArtifactProps {
|
|
414
436
|
/** The artifact's name (its slug). */
|
|
415
437
|
name?: string;
|
|
@@ -476,12 +498,15 @@ interface MatterfactArtifactProps {
|
|
|
476
498
|
* MatterfactAgent is embedded on the same page, the loader sees this iframe and both
|
|
477
499
|
* makes the agent aware of it and (via its token) lets the agent read its data.
|
|
478
500
|
*
|
|
479
|
-
* Two auth modes
|
|
480
|
-
* -
|
|
481
|
-
*
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
*
|
|
501
|
+
* Two auth modes; a provider wins when both are available:
|
|
502
|
+
* - SESSION mode (an ancestor `MatterfactAuthProvider` is present): tokenless,
|
|
503
|
+
* `?k=<publishableKey>&o=<host origin>`, the same authentication
|
|
504
|
+
* `MatterfactAgent` uses. Chosen even when a `token` is ALSO given — with an
|
|
505
|
+
* identity the embed should read as the signed-in user, and it spares the
|
|
506
|
+
* host from stripping a legacy token to get session auth.
|
|
507
|
+
* - TOKEN mode (`token` given, no provider): a standalone share link, `?t=`.
|
|
508
|
+
* This is the LIVE third-party embed path — its `src` format must stay
|
|
509
|
+
* byte-identical.
|
|
485
510
|
* With neither, there is no way for the iframe to authenticate, so no iframe is
|
|
486
511
|
* built at all — matching the "incomplete link" placeholder the embed artifact
|
|
487
512
|
* page itself renders for a missing owner/token.
|
package/dist/react.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { useCallback, useEffect as useEffect2, useRef } from "react";
|
|
6
6
|
|
|
7
7
|
// src/protocol.ts
|
|
8
|
-
var PROTOCOL_VERSION =
|
|
8
|
+
var PROTOCOL_VERSION = 4;
|
|
9
9
|
var CHANNEL = "mf-embed";
|
|
10
10
|
function envelope(payload, id) {
|
|
11
11
|
return {
|
|
@@ -227,6 +227,7 @@ function dockBox(g, vw, _vh) {
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
// src/loader.ts
|
|
230
|
+
var EMBED_VERSION = "0.18.0";
|
|
230
231
|
function devRequested() {
|
|
231
232
|
try {
|
|
232
233
|
if (new URLSearchParams(location.search).get("mfdev") === "1") return true;
|
|
@@ -314,6 +315,8 @@ var EmbedHost = class {
|
|
|
314
315
|
this.inline = !!config.container;
|
|
315
316
|
}
|
|
316
317
|
mount() {
|
|
318
|
+
const w = window;
|
|
319
|
+
(w.matterfact ?? (w.matterfact = {})).embedVersion = EMBED_VERSION;
|
|
317
320
|
const host = document.createElement("div");
|
|
318
321
|
this.hostEl = host;
|
|
319
322
|
host.id = "matterfact-embed";
|
|
@@ -357,7 +360,7 @@ var EmbedHost = class {
|
|
|
357
360
|
"sandbox",
|
|
358
361
|
"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads"
|
|
359
362
|
);
|
|
360
|
-
iframe.setAttribute("allow", "microphone; clipboard-write");
|
|
363
|
+
iframe.setAttribute("allow", "microphone; clipboard-write; web-share");
|
|
361
364
|
iframe.src = `${this.config.origin}/embed/chat?k=${encodeURIComponent(
|
|
362
365
|
this.config.publishableKey
|
|
363
366
|
)}&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
|
|
@@ -370,6 +373,18 @@ var EmbedHost = class {
|
|
|
370
373
|
window.addEventListener("resize", this.onViewportResize);
|
|
371
374
|
this.place();
|
|
372
375
|
}
|
|
376
|
+
const fmt = this.config.shareDeeplinkFormat;
|
|
377
|
+
if (fmt) {
|
|
378
|
+
void import("./deeplink-KCGMGNIR.js").then((m) => {
|
|
379
|
+
if (this.destroyed) return;
|
|
380
|
+
this.deeplinkStop = m.installDeeplinkWatch(
|
|
381
|
+
fmt,
|
|
382
|
+
(token) => this.send({ type: "host.openShare", token }),
|
|
383
|
+
(format) => this.send({ type: "host.deeplinkFormat", format })
|
|
384
|
+
);
|
|
385
|
+
}).catch(() => {
|
|
386
|
+
});
|
|
387
|
+
}
|
|
373
388
|
}
|
|
374
389
|
/**
|
|
375
390
|
* Test seam. The shadow root is CLOSED, so a test cannot reach the iframe to forge a
|
|
@@ -793,6 +808,9 @@ var EmbedHost = class {
|
|
|
793
808
|
this.iframe = null;
|
|
794
809
|
this.shadow = null;
|
|
795
810
|
this.ready = false;
|
|
811
|
+
this.destroyed = true;
|
|
812
|
+
this.deeplinkStop?.();
|
|
813
|
+
this.deeplinkStop = null;
|
|
796
814
|
void this.context?.then((m) => m.stop());
|
|
797
815
|
}
|
|
798
816
|
};
|
|
@@ -905,10 +923,32 @@ function toolDescriptorKey(artifacts, resolve, tools) {
|
|
|
905
923
|
}))
|
|
906
924
|
});
|
|
907
925
|
}
|
|
926
|
+
var KNOWN_AGENT_PROPS = [
|
|
927
|
+
"publishableKey",
|
|
928
|
+
"widgetOrigin",
|
|
929
|
+
"surface",
|
|
930
|
+
"shareDeeplinkFormat",
|
|
931
|
+
"theme",
|
|
932
|
+
"getAuthToken",
|
|
933
|
+
"getPageContext",
|
|
934
|
+
"inline",
|
|
935
|
+
"className",
|
|
936
|
+
"style",
|
|
937
|
+
"pageContext",
|
|
938
|
+
"dev",
|
|
939
|
+
"actions",
|
|
940
|
+
"sitemap",
|
|
941
|
+
"artifacts",
|
|
942
|
+
"resolve",
|
|
943
|
+
"tools",
|
|
944
|
+
"onToolEvent",
|
|
945
|
+
"onEvent"
|
|
946
|
+
];
|
|
908
947
|
function MatterfactAgent({
|
|
909
948
|
publishableKey: publishableKeyProp,
|
|
910
949
|
widgetOrigin: widgetOriginProp,
|
|
911
950
|
surface = "",
|
|
951
|
+
shareDeeplinkFormat,
|
|
912
952
|
theme: themeProp,
|
|
913
953
|
getAuthToken: getAuthTokenProp,
|
|
914
954
|
getPageContext,
|
|
@@ -923,8 +963,20 @@ function MatterfactAgent({
|
|
|
923
963
|
resolve,
|
|
924
964
|
tools,
|
|
925
965
|
onToolEvent,
|
|
926
|
-
onEvent
|
|
966
|
+
onEvent,
|
|
967
|
+
...unknownProps
|
|
927
968
|
}) {
|
|
969
|
+
useEffect2(() => {
|
|
970
|
+
if (process.env.NODE_ENV === "production") return;
|
|
971
|
+
for (const key of Object.keys(unknownProps)) {
|
|
972
|
+
const meant = KNOWN_AGENT_PROPS.find(
|
|
973
|
+
(k) => k.toLowerCase() === key.toLowerCase()
|
|
974
|
+
);
|
|
975
|
+
console.warn(
|
|
976
|
+
`[mf-embed] unknown prop "${key}" on <MatterfactAgent>` + (meant ? ` \u2014 did you mean "${meant}"?` : "")
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
}, []);
|
|
928
980
|
const ctx = useMatterfactConfig();
|
|
929
981
|
const publishableKey = publishableKeyProp ?? ctx?.publishableKey;
|
|
930
982
|
if (!publishableKey) {
|
|
@@ -970,7 +1022,8 @@ function MatterfactAgent({
|
|
|
970
1022
|
pageContextProvider: async () => await pageContextRef.current?.() ?? null,
|
|
971
1023
|
container: inline ? slot.current : null,
|
|
972
1024
|
pageContext,
|
|
973
|
-
dev
|
|
1025
|
+
dev,
|
|
1026
|
+
shareDeeplinkFormat
|
|
974
1027
|
};
|
|
975
1028
|
let host = null;
|
|
976
1029
|
try {
|
|
@@ -990,6 +1043,7 @@ function MatterfactAgent({
|
|
|
990
1043
|
publishableKey,
|
|
991
1044
|
widgetOrigin,
|
|
992
1045
|
surface,
|
|
1046
|
+
shareDeeplinkFormat,
|
|
993
1047
|
theme,
|
|
994
1048
|
inline,
|
|
995
1049
|
pageContext,
|
|
@@ -1100,11 +1154,11 @@ function MatterfactArtifact({
|
|
|
1100
1154
|
post(changed);
|
|
1101
1155
|
}, [paramsKey, post]);
|
|
1102
1156
|
let src;
|
|
1103
|
-
if (
|
|
1104
|
-
src = `${origin}/embed/artifacts/${encodeURIComponent(artifactName)}?owner=${encodeURIComponent(owner)}&t=${encodeURIComponent(token)}&theme=${theme}`;
|
|
1105
|
-
} else if (ctx) {
|
|
1157
|
+
if (ctx) {
|
|
1106
1158
|
const hostOrigin = typeof window === "undefined" ? "" : window.location.origin;
|
|
1107
1159
|
src = `${origin}/embed/artifacts/${encodeURIComponent(artifactName)}?owner=${encodeURIComponent(owner)}&k=${encodeURIComponent(ctx.publishableKey)}&o=${encodeURIComponent(hostOrigin)}&theme=${theme}`;
|
|
1160
|
+
} else if (token) {
|
|
1161
|
+
src = `${origin}/embed/artifacts/${encodeURIComponent(artifactName)}?owner=${encodeURIComponent(owner)}&t=${encodeURIComponent(token)}&theme=${theme}`;
|
|
1108
1162
|
} else {
|
|
1109
1163
|
return /* @__PURE__ */ jsx2(
|
|
1110
1164
|
"div",
|