@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.cjs
CHANGED
|
@@ -22,6 +22,191 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
22
22
|
};
|
|
23
23
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
24
24
|
|
|
25
|
+
// src/deeplink.ts
|
|
26
|
+
var deeplink_exports = {};
|
|
27
|
+
__export(deeplink_exports, {
|
|
28
|
+
compileDeeplink: () => compileDeeplink,
|
|
29
|
+
compileDeeplinkFormat: () => compileDeeplinkFormat,
|
|
30
|
+
installDeeplinkWatch: () => installDeeplinkWatch
|
|
31
|
+
});
|
|
32
|
+
function compileDeeplinkFormat(format) {
|
|
33
|
+
return compileDeeplink(format)?.match ?? null;
|
|
34
|
+
}
|
|
35
|
+
function compileDeeplink(format) {
|
|
36
|
+
if (format.includes(PATH_TOKEN)) return compileDynamic(format);
|
|
37
|
+
const match = compileStatic(format);
|
|
38
|
+
return match ? { match, mintFormat: () => format, dynamic: false } : null;
|
|
39
|
+
}
|
|
40
|
+
function compileDynamic(format) {
|
|
41
|
+
const pi = format.indexOf(PATH_TOKEN);
|
|
42
|
+
if (format.indexOf(PATH_TOKEN, pi + 1) >= 0) return null;
|
|
43
|
+
let prefix = format.slice(0, pi);
|
|
44
|
+
if (prefix.endsWith("/")) prefix = prefix.slice(0, -1);
|
|
45
|
+
const suffix = format.slice(pi + PATH_TOKEN.length);
|
|
46
|
+
let po;
|
|
47
|
+
try {
|
|
48
|
+
po = new URL(prefix);
|
|
49
|
+
} catch {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
if (po.protocol !== "https:" && po.protocol !== "http:") return null;
|
|
53
|
+
if (po.origin !== prefix) return null;
|
|
54
|
+
if (!suffix.startsWith("?")) return null;
|
|
55
|
+
const c1 = suffix.indexOf(PLACEHOLDER);
|
|
56
|
+
if (c1 < 0 || suffix.indexOf(PLACEHOLDER, c1 + 1) >= 0) return null;
|
|
57
|
+
let probe;
|
|
58
|
+
try {
|
|
59
|
+
probe = new URL(prefix + "/__mfp__" + suffix.replace(PLACEHOLDER, SENTINEL));
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const keys = [...probe.searchParams.keys()];
|
|
64
|
+
if (new Set(keys).size !== keys.length) return null;
|
|
65
|
+
let queryKey = null;
|
|
66
|
+
for (const [k, v] of probe.searchParams) {
|
|
67
|
+
if (v === SENTINEL) queryKey = k;
|
|
68
|
+
}
|
|
69
|
+
if (!queryKey) return null;
|
|
70
|
+
const match = (href) => {
|
|
71
|
+
let u;
|
|
72
|
+
try {
|
|
73
|
+
u = new URL(href);
|
|
74
|
+
} catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
if (u.origin !== prefix) return null;
|
|
78
|
+
for (const [k, v] of probe.searchParams) {
|
|
79
|
+
if (v === SENTINEL) continue;
|
|
80
|
+
if (u.searchParams.get(k) !== v) return null;
|
|
81
|
+
}
|
|
82
|
+
const token = u.searchParams.get(queryKey);
|
|
83
|
+
return token && TOKEN_RE.test(token) ? token : null;
|
|
84
|
+
};
|
|
85
|
+
return {
|
|
86
|
+
match,
|
|
87
|
+
mintFormat: (pathname) => prefix + pathname + suffix,
|
|
88
|
+
dynamic: true
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function compileStatic(format) {
|
|
92
|
+
const first = format.indexOf(PLACEHOLDER);
|
|
93
|
+
if (first < 0 || format.indexOf(PLACEHOLDER, first + 1) >= 0) return null;
|
|
94
|
+
let f;
|
|
95
|
+
try {
|
|
96
|
+
f = new URL(format.replace(PLACEHOLDER, SENTINEL));
|
|
97
|
+
} catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
if (f.protocol !== "https:" && f.protocol !== "http:") return null;
|
|
101
|
+
const keys = [...f.searchParams.keys()];
|
|
102
|
+
if (new Set(keys).size !== keys.length) return null;
|
|
103
|
+
const fPath = trimSlash(f.pathname);
|
|
104
|
+
const segs = fPath.split("/");
|
|
105
|
+
const segIdx = segs.indexOf(SENTINEL);
|
|
106
|
+
let queryKey = null;
|
|
107
|
+
for (const [k, v] of f.searchParams) {
|
|
108
|
+
if (v === SENTINEL) queryKey = k;
|
|
109
|
+
}
|
|
110
|
+
if (segIdx >= 0 === (queryKey !== null)) return null;
|
|
111
|
+
return (href) => {
|
|
112
|
+
let u;
|
|
113
|
+
try {
|
|
114
|
+
u = new URL(href);
|
|
115
|
+
} catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
if (u.origin !== f.origin) return null;
|
|
119
|
+
const uPath = trimSlash(u.pathname);
|
|
120
|
+
let token;
|
|
121
|
+
if (segIdx >= 0) {
|
|
122
|
+
const us = uPath.split("/");
|
|
123
|
+
if (us.length !== segs.length) return null;
|
|
124
|
+
for (let i = 0; i < segs.length; i++) {
|
|
125
|
+
if (i !== segIdx && us[i] !== segs[i]) return null;
|
|
126
|
+
}
|
|
127
|
+
token = us[segIdx];
|
|
128
|
+
for (const [k, v] of f.searchParams) {
|
|
129
|
+
if (u.searchParams.get(k) !== v) return null;
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
if (uPath !== fPath) return null;
|
|
133
|
+
for (const [k, v] of f.searchParams) {
|
|
134
|
+
if (v === SENTINEL) continue;
|
|
135
|
+
if (u.searchParams.get(k) !== v) return null;
|
|
136
|
+
}
|
|
137
|
+
token = u.searchParams.get(queryKey);
|
|
138
|
+
}
|
|
139
|
+
return token && TOKEN_RE.test(token) ? token : null;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function installDeeplinkWatch(format, onChange2, onFormat) {
|
|
143
|
+
const c = compileDeeplink(format);
|
|
144
|
+
if (!c) return () => {
|
|
145
|
+
};
|
|
146
|
+
let last = null;
|
|
147
|
+
let lastTokenPath = null;
|
|
148
|
+
let lastMintPath = null;
|
|
149
|
+
let stopped = false;
|
|
150
|
+
const emitFormat = () => {
|
|
151
|
+
if (!onFormat) return;
|
|
152
|
+
const p = location.pathname;
|
|
153
|
+
if (lastMintPath === null || c.dynamic && p !== lastMintPath) {
|
|
154
|
+
lastMintPath = p;
|
|
155
|
+
onFormat(c.mintFormat(p));
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
const fire = () => {
|
|
159
|
+
if (stopped) return;
|
|
160
|
+
try {
|
|
161
|
+
emitFormat();
|
|
162
|
+
const token = c.match(location.href);
|
|
163
|
+
if (token === null && last !== null && trimSlash(location.pathname) === lastTokenPath) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (token !== last) {
|
|
167
|
+
last = token;
|
|
168
|
+
if (token !== null) lastTokenPath = trimSlash(location.pathname);
|
|
169
|
+
onChange2(token);
|
|
170
|
+
}
|
|
171
|
+
} catch (err) {
|
|
172
|
+
console.warn("[mf-embed] deeplink match failed", err);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const origPush = history.pushState;
|
|
176
|
+
const origReplace = history.replaceState;
|
|
177
|
+
const ourPush = function(...args) {
|
|
178
|
+
const r = origPush.apply(this, args);
|
|
179
|
+
fire();
|
|
180
|
+
return r;
|
|
181
|
+
};
|
|
182
|
+
const ourReplace = function(...args) {
|
|
183
|
+
const r = origReplace.apply(this, args);
|
|
184
|
+
fire();
|
|
185
|
+
return r;
|
|
186
|
+
};
|
|
187
|
+
history.pushState = ourPush;
|
|
188
|
+
history.replaceState = ourReplace;
|
|
189
|
+
window.addEventListener("popstate", fire);
|
|
190
|
+
fire();
|
|
191
|
+
return () => {
|
|
192
|
+
stopped = true;
|
|
193
|
+
window.removeEventListener("popstate", fire);
|
|
194
|
+
if (history.pushState === ourPush) history.pushState = origPush;
|
|
195
|
+
if (history.replaceState === ourReplace) history.replaceState = origReplace;
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
var PLACEHOLDER, PATH_TOKEN, SENTINEL, TOKEN_RE, trimSlash;
|
|
199
|
+
var init_deeplink = __esm({
|
|
200
|
+
"src/deeplink.ts"() {
|
|
201
|
+
"use strict";
|
|
202
|
+
PLACEHOLDER = "{share_token}";
|
|
203
|
+
PATH_TOKEN = "{path}";
|
|
204
|
+
SENTINEL = "mf-share-token-sentinel";
|
|
205
|
+
TOKEN_RE = /^[A-Za-z0-9._~-]{4,256}$/;
|
|
206
|
+
trimSlash = (path) => path.length > 1 && path.endsWith("/") ? path.slice(0, -1) : path;
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
|
|
25
210
|
// src/pageContextMode.ts
|
|
26
211
|
function parsePageContextMode(value) {
|
|
27
212
|
if (typeof value === "boolean") return value ? "full" : "off";
|
|
@@ -1618,7 +1803,7 @@ module.exports = __toCommonJS(react_exports);
|
|
|
1618
1803
|
var import_react2 = require("react");
|
|
1619
1804
|
|
|
1620
1805
|
// src/protocol.ts
|
|
1621
|
-
var PROTOCOL_VERSION =
|
|
1806
|
+
var PROTOCOL_VERSION = 4;
|
|
1622
1807
|
var CHANNEL = "mf-embed";
|
|
1623
1808
|
function envelope(payload, id) {
|
|
1624
1809
|
return {
|
|
@@ -1840,6 +2025,7 @@ function dockBox(g, vw, _vh) {
|
|
|
1840
2025
|
}
|
|
1841
2026
|
|
|
1842
2027
|
// src/loader.ts
|
|
2028
|
+
var EMBED_VERSION = "0.18.0";
|
|
1843
2029
|
function devRequested() {
|
|
1844
2030
|
try {
|
|
1845
2031
|
if (new URLSearchParams(location.search).get("mfdev") === "1") return true;
|
|
@@ -1927,6 +2113,8 @@ var EmbedHost = class {
|
|
|
1927
2113
|
this.inline = !!config.container;
|
|
1928
2114
|
}
|
|
1929
2115
|
mount() {
|
|
2116
|
+
const w = window;
|
|
2117
|
+
(w.matterfact ?? (w.matterfact = {})).embedVersion = EMBED_VERSION;
|
|
1930
2118
|
const host = document.createElement("div");
|
|
1931
2119
|
this.hostEl = host;
|
|
1932
2120
|
host.id = "matterfact-embed";
|
|
@@ -1970,7 +2158,7 @@ var EmbedHost = class {
|
|
|
1970
2158
|
"sandbox",
|
|
1971
2159
|
"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads"
|
|
1972
2160
|
);
|
|
1973
|
-
iframe.setAttribute("allow", "microphone; clipboard-write");
|
|
2161
|
+
iframe.setAttribute("allow", "microphone; clipboard-write; web-share");
|
|
1974
2162
|
iframe.src = `${this.config.origin}/embed/chat?k=${encodeURIComponent(
|
|
1975
2163
|
this.config.publishableKey
|
|
1976
2164
|
)}&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
|
|
@@ -1983,6 +2171,18 @@ var EmbedHost = class {
|
|
|
1983
2171
|
window.addEventListener("resize", this.onViewportResize);
|
|
1984
2172
|
this.place();
|
|
1985
2173
|
}
|
|
2174
|
+
const fmt = this.config.shareDeeplinkFormat;
|
|
2175
|
+
if (fmt) {
|
|
2176
|
+
void Promise.resolve().then(() => (init_deeplink(), deeplink_exports)).then((m) => {
|
|
2177
|
+
if (this.destroyed) return;
|
|
2178
|
+
this.deeplinkStop = m.installDeeplinkWatch(
|
|
2179
|
+
fmt,
|
|
2180
|
+
(token) => this.send({ type: "host.openShare", token }),
|
|
2181
|
+
(format) => this.send({ type: "host.deeplinkFormat", format })
|
|
2182
|
+
);
|
|
2183
|
+
}).catch(() => {
|
|
2184
|
+
});
|
|
2185
|
+
}
|
|
1986
2186
|
}
|
|
1987
2187
|
/**
|
|
1988
2188
|
* Test seam. The shadow root is CLOSED, so a test cannot reach the iframe to forge a
|
|
@@ -2406,6 +2606,9 @@ var EmbedHost = class {
|
|
|
2406
2606
|
this.iframe = null;
|
|
2407
2607
|
this.shadow = null;
|
|
2408
2608
|
this.ready = false;
|
|
2609
|
+
this.destroyed = true;
|
|
2610
|
+
this.deeplinkStop?.();
|
|
2611
|
+
this.deeplinkStop = null;
|
|
2409
2612
|
void this.context?.then((m) => m.stop());
|
|
2410
2613
|
}
|
|
2411
2614
|
};
|
|
@@ -2518,10 +2721,32 @@ function toolDescriptorKey(artifacts, resolve, tools) {
|
|
|
2518
2721
|
}))
|
|
2519
2722
|
});
|
|
2520
2723
|
}
|
|
2724
|
+
var KNOWN_AGENT_PROPS = [
|
|
2725
|
+
"publishableKey",
|
|
2726
|
+
"widgetOrigin",
|
|
2727
|
+
"surface",
|
|
2728
|
+
"shareDeeplinkFormat",
|
|
2729
|
+
"theme",
|
|
2730
|
+
"getAuthToken",
|
|
2731
|
+
"getPageContext",
|
|
2732
|
+
"inline",
|
|
2733
|
+
"className",
|
|
2734
|
+
"style",
|
|
2735
|
+
"pageContext",
|
|
2736
|
+
"dev",
|
|
2737
|
+
"actions",
|
|
2738
|
+
"sitemap",
|
|
2739
|
+
"artifacts",
|
|
2740
|
+
"resolve",
|
|
2741
|
+
"tools",
|
|
2742
|
+
"onToolEvent",
|
|
2743
|
+
"onEvent"
|
|
2744
|
+
];
|
|
2521
2745
|
function MatterfactAgent({
|
|
2522
2746
|
publishableKey: publishableKeyProp,
|
|
2523
2747
|
widgetOrigin: widgetOriginProp,
|
|
2524
2748
|
surface = "",
|
|
2749
|
+
shareDeeplinkFormat,
|
|
2525
2750
|
theme: themeProp,
|
|
2526
2751
|
getAuthToken: getAuthTokenProp,
|
|
2527
2752
|
getPageContext,
|
|
@@ -2536,8 +2761,20 @@ function MatterfactAgent({
|
|
|
2536
2761
|
resolve,
|
|
2537
2762
|
tools,
|
|
2538
2763
|
onToolEvent,
|
|
2539
|
-
onEvent
|
|
2764
|
+
onEvent,
|
|
2765
|
+
...unknownProps
|
|
2540
2766
|
}) {
|
|
2767
|
+
(0, import_react2.useEffect)(() => {
|
|
2768
|
+
if (process.env.NODE_ENV === "production") return;
|
|
2769
|
+
for (const key of Object.keys(unknownProps)) {
|
|
2770
|
+
const meant = KNOWN_AGENT_PROPS.find(
|
|
2771
|
+
(k) => k.toLowerCase() === key.toLowerCase()
|
|
2772
|
+
);
|
|
2773
|
+
console.warn(
|
|
2774
|
+
`[mf-embed] unknown prop "${key}" on <MatterfactAgent>` + (meant ? ` \u2014 did you mean "${meant}"?` : "")
|
|
2775
|
+
);
|
|
2776
|
+
}
|
|
2777
|
+
}, []);
|
|
2541
2778
|
const ctx = useMatterfactConfig();
|
|
2542
2779
|
const publishableKey = publishableKeyProp ?? ctx?.publishableKey;
|
|
2543
2780
|
if (!publishableKey) {
|
|
@@ -2583,7 +2820,8 @@ function MatterfactAgent({
|
|
|
2583
2820
|
pageContextProvider: async () => await pageContextRef.current?.() ?? null,
|
|
2584
2821
|
container: inline ? slot.current : null,
|
|
2585
2822
|
pageContext,
|
|
2586
|
-
dev
|
|
2823
|
+
dev,
|
|
2824
|
+
shareDeeplinkFormat
|
|
2587
2825
|
};
|
|
2588
2826
|
let host = null;
|
|
2589
2827
|
try {
|
|
@@ -2603,6 +2841,7 @@ function MatterfactAgent({
|
|
|
2603
2841
|
publishableKey,
|
|
2604
2842
|
widgetOrigin2,
|
|
2605
2843
|
surface,
|
|
2844
|
+
shareDeeplinkFormat,
|
|
2606
2845
|
theme,
|
|
2607
2846
|
inline,
|
|
2608
2847
|
pageContext,
|
|
@@ -2713,11 +2952,11 @@ function MatterfactArtifact({
|
|
|
2713
2952
|
post(changed);
|
|
2714
2953
|
}, [paramsKey, post]);
|
|
2715
2954
|
let src;
|
|
2716
|
-
if (
|
|
2717
|
-
src = `${origin}/embed/artifacts/${encodeURIComponent(artifactName)}?owner=${encodeURIComponent(owner)}&t=${encodeURIComponent(token)}&theme=${theme}`;
|
|
2718
|
-
} else if (ctx) {
|
|
2955
|
+
if (ctx) {
|
|
2719
2956
|
const hostOrigin = typeof window === "undefined" ? "" : window.location.origin;
|
|
2720
2957
|
src = `${origin}/embed/artifacts/${encodeURIComponent(artifactName)}?owner=${encodeURIComponent(owner)}&k=${encodeURIComponent(ctx.publishableKey)}&o=${encodeURIComponent(hostOrigin)}&theme=${theme}`;
|
|
2958
|
+
} else if (token) {
|
|
2959
|
+
src = `${origin}/embed/artifacts/${encodeURIComponent(artifactName)}?owner=${encodeURIComponent(owner)}&t=${encodeURIComponent(token)}&theme=${theme}`;
|
|
2721
2960
|
} else {
|
|
2722
2961
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2723
2962
|
"div",
|