@matterfact/embed 0.15.0 → 0.16.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 +37 -2
- package/dist/react.cjs +79 -8
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +25 -1
- package/dist/react.d.ts +25 -1
- package/dist/react.js +76 -5
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -61,6 +61,39 @@ about the data behind it — no wiring, and the token never reaches the model.
|
|
|
61
61
|
An artifact can declare typed params — a company, a time window, a peer set. Readers change
|
|
62
62
|
them in a control bar on the artifact itself; your page can drive them too.
|
|
63
63
|
|
|
64
|
+
There are two artifacts you might be driving, and they're **different iframes** — one
|
|
65
|
+
doesn't reach the other:
|
|
66
|
+
|
|
67
|
+
| The artifact… | Drive it with |
|
|
68
|
+
|---|---|
|
|
69
|
+
| on your page, via `<MatterfactArtifact>` | the `params` prop |
|
|
70
|
+
| inside the chat widget | `host.setArtifactParams()` |
|
|
71
|
+
|
|
72
|
+
### An artifact on your page
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<MatterfactArtifact
|
|
76
|
+
slug="tsla-liquidity"
|
|
77
|
+
owner="you@firm.com"
|
|
78
|
+
token="…"
|
|
79
|
+
params={{ ticker, window: '5Y' }}
|
|
80
|
+
onParamsChange={(params, source) => setTicker(params.ticker)}
|
|
81
|
+
/>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Pass your whole param state — the component works out what actually changed and pushes only
|
|
85
|
+
that. Safe to set before the artifact has loaded; it's delivered as soon as the frame is
|
|
86
|
+
ready. Changing a param never reloads the artifact.
|
|
87
|
+
|
|
88
|
+
Dropping a key stops driving it and leaves its current value alone; there is no "unset".
|
|
89
|
+
Re-adding a key you'd dropped re-asserts it, which is how you force a value back after a
|
|
90
|
+
reader has changed it.
|
|
91
|
+
|
|
92
|
+
`onParamsChange` fires for reader- and page-context-driven changes, never for your own
|
|
93
|
+
pushes — so feeding it straight back into `params` can't loop.
|
|
94
|
+
|
|
95
|
+
### An artifact inside the chat
|
|
96
|
+
|
|
64
97
|
```js
|
|
65
98
|
const host = mount({ …config });
|
|
66
99
|
|
|
@@ -69,8 +102,8 @@ host.setArtifactParams({ ticker: 'NVDA' }); // or window.matterfact.setArtifac
|
|
|
69
102
|
|
|
70
103
|
Safe to call before the widget finishes loading — it's queued and delivered on ready.
|
|
71
104
|
|
|
72
|
-
**A push is authoritative for every key it names.**
|
|
73
|
-
changing
|
|
105
|
+
**A push is authoritative for every key it names.** Unlike the `params` prop, this is raw:
|
|
106
|
+
send only the params you're actually changing.
|
|
74
107
|
|
|
75
108
|
```js
|
|
76
109
|
host.setArtifactParams({ window: '5Y' }); // ✅ changes the window
|
|
@@ -90,6 +123,8 @@ onEvent(e) {
|
|
|
90
123
|
}
|
|
91
124
|
```
|
|
92
125
|
|
|
126
|
+
### Either way
|
|
127
|
+
|
|
93
128
|
A param can also follow your page automatically: if it declares a binding and you publish
|
|
94
129
|
page context (`window.matterfact.context` or `getPageContext`), it tracks the entity you're
|
|
95
130
|
showing with no glue code. A reader's own pick takes over from there, until they choose to
|
package/dist/react.cjs
CHANGED
|
@@ -1362,8 +1362,8 @@ async function readFocus() {
|
|
|
1362
1362
|
}
|
|
1363
1363
|
const active = document.activeElement;
|
|
1364
1364
|
if (active && active !== document.body && !isPrivate(active) && !active.closest("[data-mf-private]")) {
|
|
1365
|
-
const { snapshot:
|
|
1366
|
-
void
|
|
1365
|
+
const { snapshot: snapshot3 } = await loadSnapshotModule();
|
|
1366
|
+
void snapshot3;
|
|
1367
1367
|
focus.focused = {
|
|
1368
1368
|
label: redact(describeControl(active)),
|
|
1369
1369
|
role: active.getAttribute("role") || active.tagName.toLowerCase()
|
|
@@ -1406,9 +1406,9 @@ async function sendSnapshot(emit) {
|
|
|
1406
1406
|
emit({ type: "host.focus", focus: lastFocus });
|
|
1407
1407
|
return;
|
|
1408
1408
|
}
|
|
1409
|
-
const { snapshot:
|
|
1409
|
+
const { snapshot: snapshot3 } = await loadSnapshotModule();
|
|
1410
1410
|
if (!allowsAuto(effectivePageContextMode())) return;
|
|
1411
|
-
const { yaml, truncated, visibleRefs } =
|
|
1411
|
+
const { yaml, truncated, visibleRefs } = snapshot3();
|
|
1412
1412
|
emit({
|
|
1413
1413
|
type: "host.snapshot",
|
|
1414
1414
|
snapshot: { yaml: redact(yaml), seq: ++snapshotSeq, truncated }
|
|
@@ -2624,6 +2624,13 @@ function MatterfactAgent({
|
|
|
2624
2624
|
);
|
|
2625
2625
|
}
|
|
2626
2626
|
var DEFAULT_ARTIFACT_ORIGIN = "https://app.matterfact.com";
|
|
2627
|
+
function snapshot2(params) {
|
|
2628
|
+
const out = /* @__PURE__ */ new Map();
|
|
2629
|
+
for (const [key, value] of Object.entries(params ?? {})) {
|
|
2630
|
+
out.set(key, JSON.stringify(value ?? null));
|
|
2631
|
+
}
|
|
2632
|
+
return out;
|
|
2633
|
+
}
|
|
2627
2634
|
function MatterfactArtifact({
|
|
2628
2635
|
name: nameProp,
|
|
2629
2636
|
slug,
|
|
@@ -2632,7 +2639,9 @@ function MatterfactArtifact({
|
|
|
2632
2639
|
widgetOrigin: widgetOriginProp,
|
|
2633
2640
|
theme: themeProp,
|
|
2634
2641
|
className: className2,
|
|
2635
|
-
style
|
|
2642
|
+
style,
|
|
2643
|
+
params,
|
|
2644
|
+
onParamsChange
|
|
2636
2645
|
}) {
|
|
2637
2646
|
const ctx = useMatterfactConfig();
|
|
2638
2647
|
const artifactName = nameProp ?? slug;
|
|
@@ -2643,6 +2652,66 @@ function MatterfactArtifact({
|
|
|
2643
2652
|
}
|
|
2644
2653
|
const origin = widgetOriginProp ?? ctx?.widgetOrigin ?? DEFAULT_ARTIFACT_ORIGIN;
|
|
2645
2654
|
const theme = themeProp ?? ctx?.theme ?? "auto";
|
|
2655
|
+
const frame = (0, import_react2.useRef)(null);
|
|
2656
|
+
const changeRef = (0, import_react2.useRef)(onParamsChange);
|
|
2657
|
+
changeRef.current = onParamsChange;
|
|
2658
|
+
const paramsRef = (0, import_react2.useRef)(params);
|
|
2659
|
+
paramsRef.current = params;
|
|
2660
|
+
const posted = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
2661
|
+
const post = (0, import_react2.useCallback)(
|
|
2662
|
+
(values) => {
|
|
2663
|
+
if (Object.keys(values).length === 0) return;
|
|
2664
|
+
frame.current?.contentWindow?.postMessage(
|
|
2665
|
+
{ type: "host.artifactParams", params: values },
|
|
2666
|
+
origin
|
|
2667
|
+
);
|
|
2668
|
+
},
|
|
2669
|
+
[origin]
|
|
2670
|
+
);
|
|
2671
|
+
const postAll = (0, import_react2.useCallback)(() => {
|
|
2672
|
+
posted.current = snapshot2(paramsRef.current);
|
|
2673
|
+
post({ ...paramsRef.current });
|
|
2674
|
+
}, [post]);
|
|
2675
|
+
const onLoad = (0, import_react2.useCallback)(() => postAll(), [postAll]);
|
|
2676
|
+
(0, import_react2.useEffect)(() => {
|
|
2677
|
+
if (typeof window === "undefined") return;
|
|
2678
|
+
const onMessage = (event) => {
|
|
2679
|
+
if (!frame.current || event.source !== frame.current.contentWindow) return;
|
|
2680
|
+
const data = event.data;
|
|
2681
|
+
if (!data || typeof data !== "object") return;
|
|
2682
|
+
if (data.type === "widget.artifactReady") {
|
|
2683
|
+
postAll();
|
|
2684
|
+
return;
|
|
2685
|
+
}
|
|
2686
|
+
if (data.type === "widget.artifactParams" && data.params) {
|
|
2687
|
+
const source = data.source === "context" ? "context" : "user";
|
|
2688
|
+
try {
|
|
2689
|
+
changeRef.current?.(data.params, source);
|
|
2690
|
+
} catch {
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
};
|
|
2694
|
+
window.addEventListener("message", onMessage);
|
|
2695
|
+
return () => window.removeEventListener("message", onMessage);
|
|
2696
|
+
}, [postAll]);
|
|
2697
|
+
const paramsKey = JSON.stringify(params ?? null);
|
|
2698
|
+
const settled = (0, import_react2.useRef)(false);
|
|
2699
|
+
(0, import_react2.useEffect)(() => {
|
|
2700
|
+
const next = snapshot2(paramsRef.current);
|
|
2701
|
+
if (!settled.current) {
|
|
2702
|
+
settled.current = true;
|
|
2703
|
+
posted.current = next;
|
|
2704
|
+
return;
|
|
2705
|
+
}
|
|
2706
|
+
const changed = {};
|
|
2707
|
+
for (const [key, json] of next) {
|
|
2708
|
+
if (posted.current.get(key) !== json) {
|
|
2709
|
+
changed[key] = paramsRef.current[key];
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
posted.current = next;
|
|
2713
|
+
post(changed);
|
|
2714
|
+
}, [paramsKey, post]);
|
|
2646
2715
|
let src;
|
|
2647
2716
|
if (token) {
|
|
2648
2717
|
src = `${origin}/embed/artifacts/${encodeURIComponent(artifactName)}?owner=${encodeURIComponent(owner)}&t=${encodeURIComponent(token)}&theme=${theme}`;
|
|
@@ -2670,7 +2739,9 @@ function MatterfactArtifact({
|
|
|
2670
2739
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2671
2740
|
"iframe",
|
|
2672
2741
|
{
|
|
2742
|
+
ref: frame,
|
|
2673
2743
|
src,
|
|
2744
|
+
onLoad,
|
|
2674
2745
|
title: `matterfact artifact ${artifactName}`,
|
|
2675
2746
|
className: className2,
|
|
2676
2747
|
style: { width: "100%", height: 600, border: 0, ...style },
|
|
@@ -2683,10 +2754,10 @@ function diffDocParams(params, sent) {
|
|
|
2683
2754
|
const changed = {};
|
|
2684
2755
|
for (const [key, value] of Object.entries(params)) {
|
|
2685
2756
|
if (value === void 0) continue;
|
|
2686
|
-
const
|
|
2687
|
-
if (sent.get(key) ===
|
|
2757
|
+
const snapshot3 = JSON.stringify(value);
|
|
2758
|
+
if (sent.get(key) === snapshot3) continue;
|
|
2688
2759
|
changed[key] = value;
|
|
2689
|
-
sent.set(key,
|
|
2760
|
+
sent.set(key, snapshot3);
|
|
2690
2761
|
}
|
|
2691
2762
|
return changed;
|
|
2692
2763
|
}
|