@matterfact/embed 0.13.0 → 0.15.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/dist/react.cjs +199 -23
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +140 -11
- package/dist/react.d.ts +140 -11
- package/dist/react.js +192 -18
- package/dist/react.js.map +1 -1
- package/examples/embed-demo/.env.example +9 -0
- package/examples/embed-demo/README.md +66 -12
- package/examples/embed-demo/src/App.tsx +56 -12
- package/examples/embed-demo/src/config.ts +8 -0
- package/package.json +1 -1
|
@@ -27,6 +27,15 @@ VITE_MF_ARTIFACT_SLUG=
|
|
|
27
27
|
VITE_MF_ARTIFACT_OWNER=
|
|
28
28
|
VITE_MF_ARTIFACT_TOKEN=
|
|
29
29
|
|
|
30
|
+
# ── Document (the embedded matterfact catalog document) ───────────────────────
|
|
31
|
+
# The <MatterfactDoc> surface is session-authed through the MatterfactAuthProvider
|
|
32
|
+
# (no token of its own — it reuses the publishable key + origin above). docKey is
|
|
33
|
+
# the catalog document key; ticker seeds its initial view; version is pinned to
|
|
34
|
+
# `latest` in the demo. These ship with sensible placeholders so the doc renders
|
|
35
|
+
# out of the box — swap them for a real document in your deployment.
|
|
36
|
+
VITE_MF_DOC_KEY=company-dossier
|
|
37
|
+
VITE_MF_DOC_TICKER=NVDA
|
|
38
|
+
|
|
30
39
|
# ── Optional ──────────────────────────────────────────────────────────────────
|
|
31
40
|
VITE_MF_SURFACE=embed-demo
|
|
32
41
|
VITE_MF_THEME=auto
|
|
@@ -1,14 +1,54 @@
|
|
|
1
1
|
# matterfact embed demo
|
|
2
2
|
|
|
3
|
-
A tiny React + Vite app that puts **
|
|
4
|
-
`@matterfact/embed
|
|
3
|
+
A tiny React + Vite app that puts **three** matterfact embed surfaces on one page using
|
|
4
|
+
`@matterfact/embed`, all configured through a **single `<MatterfactAuthProvider>`**:
|
|
5
5
|
|
|
6
6
|
- **`<MatterfactAgent inline>`** — the chat, mounted in the page's right rail;
|
|
7
|
-
- **`<MatterfactArtifact>`** — a matterfact artifact embedded in the page
|
|
7
|
+
- **`<MatterfactArtifact>`** — a matterfact artifact embedded in the page (tokenless);
|
|
8
|
+
- **`<MatterfactDoc>`** — a matterfact catalog document (dossier / report), embedded
|
|
9
|
+
in the page (tokenless).
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
All three on the page means the agent auto-detects the artifact by origin and can answer
|
|
10
12
|
questions about the data behind it — no wiring.
|
|
11
13
|
|
|
14
|
+
## Configure once: `<MatterfactAuthProvider>`
|
|
15
|
+
|
|
16
|
+
The publishable key, widget origin, theme and host-auth hook are set **once** on a
|
|
17
|
+
provider that wraps every surface — the components underneath read them from context:
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import {
|
|
21
|
+
MatterfactAuthProvider,
|
|
22
|
+
MatterfactAgent,
|
|
23
|
+
MatterfactArtifact,
|
|
24
|
+
MatterfactDoc,
|
|
25
|
+
} from '@matterfact/embed/react';
|
|
26
|
+
|
|
27
|
+
<MatterfactAuthProvider
|
|
28
|
+
publishableKey="pk_live_…"
|
|
29
|
+
widgetOrigin="https://emc.matterfact.com"
|
|
30
|
+
getAuthToken={getAuthToken} // silent host-auth; return null → popup sign-in
|
|
31
|
+
theme="auto"
|
|
32
|
+
>
|
|
33
|
+
<MatterfactAgent inline surface="…" />
|
|
34
|
+
<MatterfactArtifact name="…" owner="you@firm.com" /> {/* no token, no origin */}
|
|
35
|
+
<MatterfactDoc docKey="…" ticker="NVDA" version="latest" />
|
|
36
|
+
</MatterfactAuthProvider>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**This is the migration from the pre-provider pattern.** Previously each
|
|
40
|
+
`<MatterfactAgent>` / `<MatterfactArtifact>` carried its own `publishableKey`,
|
|
41
|
+
`widgetOrigin`, `theme` — and the artifact carried a per-component share `token`. Now:
|
|
42
|
+
|
|
43
|
+
- lift `publishableKey` / `widgetOrigin` / `theme` / `getAuthToken` onto the provider;
|
|
44
|
+
- `<MatterfactArtifact>`: `slug=` → `name=`, and **drop** `token=` and `widgetOrigin=`
|
|
45
|
+
(inside a provider it authenticates with the session — publishable key + host origin —
|
|
46
|
+
the same way the agent does). Keep `owner=`;
|
|
47
|
+
- `<MatterfactDoc>` is **always** session-authed — it has no standalone token mode at
|
|
48
|
+
all, so it only works inside a provider.
|
|
49
|
+
|
|
50
|
+
`src/App.tsx` is that migration end-to-end — read it as the copy-this reference.
|
|
51
|
+
|
|
12
52
|
### Two agent surfaces: inline + full page
|
|
13
53
|
|
|
14
54
|
The header has an **Inline / Full page** switch (deep-linkable via `?view=full`):
|
|
@@ -51,9 +91,10 @@ Vite exposes only `VITE_`-prefixed vars to the app.
|
|
|
51
91
|
| `VITE_MF_ENV` | Deployment: `ecm` \| `prod` \| `staging` \| `local`. Picks the widget origin. |
|
|
52
92
|
| `VITE_MF_WIDGET_ORIGIN` | Optional. Overrides the origin (required for `staging`). |
|
|
53
93
|
| `VITE_MF_PUBLISHABLE_KEY` | The agent's publishable key (`pk_live_…` / `pk_test_…`). |
|
|
54
|
-
| `VITE_MF_ARTIFACT_SLUG` / `_OWNER` / `_TOKEN` | The artifact — from its **Share → Embed** dialog.
|
|
94
|
+
| `VITE_MF_ARTIFACT_SLUG` / `_OWNER` / `_TOKEN` | The artifact — from its **Share → Embed** dialog. Inside the provider only `_SLUG` (→ `name`) and `_OWNER` are used; `_TOKEN` is no longer needed. |
|
|
95
|
+
| `VITE_MF_DOC_KEY` / `VITE_MF_DOC_TICKER` | The catalog document (`<MatterfactDoc>`) — its catalog key and initial ticker. Ship with placeholders. |
|
|
55
96
|
| `VITE_MF_SURFACE` | Free-form usage/history label. |
|
|
56
|
-
| `VITE_MF_THEME` | `light` \| `dark` \| `auto`.
|
|
97
|
+
| `VITE_MF_THEME` | `light` \| `dark` \| `auto`. Set once — the provider fans it out to every surface. |
|
|
57
98
|
|
|
58
99
|
### Env → origin
|
|
59
100
|
|
|
@@ -75,7 +116,10 @@ If it isn't, the agent iframe renders nothing — the key isn't wrong, the origi
|
|
|
75
116
|
## Signing in
|
|
76
117
|
|
|
77
118
|
The widget runs its own sign-in in a popup — a cross-site iframe has no ambient session, so
|
|
78
|
-
this is the honest production behaviour.
|
|
119
|
+
this is the honest production behaviour. The provider's `getAuthToken` hook (silent host-auth)
|
|
120
|
+
is wired in `src/App.tsx` to show where it goes, but returns `null` here — so the demo falls
|
|
121
|
+
back to that popup sign-in. A trusted first-party host returns a real token (its Firebase
|
|
122
|
+
idToken, an Entra token, …) and every surface under the provider signs in silently instead.
|
|
79
123
|
|
|
80
124
|
## Host tools & telemetry
|
|
81
125
|
|
|
@@ -140,13 +184,23 @@ detection takes over. It doubles as a reference for what a real Hoist app needs
|
|
|
140
184
|
the same result: nothing — just the `GridModel` / `ChartModel` / `TabContainerModel` / router
|
|
141
185
|
surface a real Hoist app already has mounted.
|
|
142
186
|
|
|
143
|
-
## The
|
|
187
|
+
## The shape that matters
|
|
144
188
|
|
|
145
189
|
```tsx
|
|
146
|
-
import {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
190
|
+
import {
|
|
191
|
+
MatterfactAuthProvider,
|
|
192
|
+
MatterfactAgent,
|
|
193
|
+
MatterfactArtifact,
|
|
194
|
+
MatterfactDoc,
|
|
195
|
+
} from '@matterfact/embed/react';
|
|
196
|
+
|
|
197
|
+
// Configure once on the provider…
|
|
198
|
+
<MatterfactAuthProvider publishableKey="pk_live_…" widgetOrigin="https://emc.matterfact.com" theme="auto">
|
|
199
|
+
{/* …and every surface underneath inherits it. */}
|
|
200
|
+
<MatterfactAgent inline />
|
|
201
|
+
<MatterfactArtifact name="…" owner="you@firm.com" />
|
|
202
|
+
<MatterfactDoc docKey="…" ticker="NVDA" version="latest" />
|
|
203
|
+
</MatterfactAuthProvider>
|
|
150
204
|
```
|
|
151
205
|
|
|
152
206
|
See the package [README](../../README.md) for the full API.
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { useCallback, useMemo, useState } from 'react';
|
|
2
2
|
import {
|
|
3
|
+
MatterfactAuthProvider,
|
|
3
4
|
MatterfactAgent,
|
|
4
5
|
MatterfactArtifact,
|
|
6
|
+
MatterfactDoc,
|
|
5
7
|
type HostToolDef,
|
|
6
8
|
} from '@matterfact/embed/react';
|
|
7
9
|
import type { MatterfactEvent } from '@matterfact/embed';
|
|
@@ -78,6 +80,14 @@ export function App() {
|
|
|
78
80
|
setEvents((prev) => [...prev.slice(-19), { t: Date.now(), line }]);
|
|
79
81
|
}, []);
|
|
80
82
|
|
|
83
|
+
// SILENT HOST-AUTH passthrough — set once on the provider, inherited by every
|
|
84
|
+
// surface below (agent, artifact, doc). Return a token this matterfact
|
|
85
|
+
// deployment already trusts (the host app's Firebase idToken, an Entra token,
|
|
86
|
+
// …) and the widgets sign in silently with it. This demo has no host session,
|
|
87
|
+
// so it returns null — which falls back to the widget's own popup sign-in. It's
|
|
88
|
+
// wired here purely to show WHERE a real integration would supply the token.
|
|
89
|
+
const getAuthToken = useCallback(() => null, []);
|
|
90
|
+
|
|
81
91
|
// Host-defined `app.*` tools: the agent can call these, and you watch the page react.
|
|
82
92
|
// `selectHolding` mutates real page state (the same `selected` the pull-context demo
|
|
83
93
|
// uses) so a tool call is visible; `filterHoldings` is a read-only query.
|
|
@@ -157,7 +167,18 @@ export function App() {
|
|
|
157
167
|
data: { selectedHolding: selected },
|
|
158
168
|
});
|
|
159
169
|
|
|
170
|
+
// CONFIGURE ONCE. Everything that used to be repeated on each <MatterfactAgent>
|
|
171
|
+
// / <MatterfactArtifact> — the publishable key, the widget origin, the theme,
|
|
172
|
+
// and the host-auth hook — now lives on ONE provider that wraps every embed
|
|
173
|
+
// surface. The agent, artifact and doc below read it from context, so they only
|
|
174
|
+
// carry the props that are actually specific to them.
|
|
160
175
|
return (
|
|
176
|
+
<MatterfactAuthProvider
|
|
177
|
+
publishableKey={config.publishableKey}
|
|
178
|
+
widgetOrigin={config.widgetOrigin}
|
|
179
|
+
getAuthToken={getAuthToken}
|
|
180
|
+
theme={config.theme}
|
|
181
|
+
>
|
|
161
182
|
<div
|
|
162
183
|
className="app"
|
|
163
184
|
data-placement={placement}
|
|
@@ -239,14 +260,15 @@ export function App() {
|
|
|
239
260
|
<span className="mf">✦</span> matterfact artifact ·{' '}
|
|
240
261
|
<code>{config.artifact.slug}</code>
|
|
241
262
|
</div>
|
|
242
|
-
{/*
|
|
243
|
-
|
|
263
|
+
{/* Tokenless. Inside the provider the artifact authenticates with
|
|
264
|
+
the SAME session as the agent (publishable key + host origin) —
|
|
265
|
+
no per-component share token. Only `name` and `owner` identify
|
|
266
|
+
it; widgetOrigin and theme are inherited from the provider. The
|
|
267
|
+
agent, mounted on the same page below, still auto-detects this
|
|
268
|
+
artifact by origin and can answer questions about its data. */}
|
|
244
269
|
<MatterfactArtifact
|
|
245
|
-
|
|
270
|
+
name={config.artifact.slug}
|
|
246
271
|
owner={config.artifact.owner}
|
|
247
|
-
token={config.artifact.token}
|
|
248
|
-
widgetOrigin={config.widgetOrigin}
|
|
249
|
-
theme={config.theme}
|
|
250
272
|
style={{ width: '100%', height: '100%' }}
|
|
251
273
|
/>
|
|
252
274
|
</div>
|
|
@@ -258,6 +280,33 @@ export function App() {
|
|
|
258
280
|
</>
|
|
259
281
|
)}
|
|
260
282
|
|
|
283
|
+
<div className="section-title">Embedded matterfact document</div>
|
|
284
|
+
<div className="artifact-frame">
|
|
285
|
+
<div className="artifact-badge">
|
|
286
|
+
<span className="mf">✦</span> matterfact document ·{' '}
|
|
287
|
+
<code>{config.doc.docKey}</code>
|
|
288
|
+
</div>
|
|
289
|
+
{/* A catalog document (dossier / report). ALWAYS session-authed — there
|
|
290
|
+
is no standalone share-token mode — so it relies on the provider for
|
|
291
|
+
the publishable key + origin. `docKey` is fixed at mount; `ticker`
|
|
292
|
+
and `version` seed the initial view (and are live-drivable via a
|
|
293
|
+
`params` prop, not shown here). */}
|
|
294
|
+
<MatterfactDoc
|
|
295
|
+
docKey={config.doc.docKey}
|
|
296
|
+
ticker={config.doc.ticker}
|
|
297
|
+
version="latest"
|
|
298
|
+
style={{ width: '100%', height: '100%' }}
|
|
299
|
+
/>
|
|
300
|
+
</div>
|
|
301
|
+
<p className="artifact-caption">
|
|
302
|
+
<strong>Tokenless, session-authed:</strong> like the artifact above,
|
|
303
|
+
this document has no token of its own — it inherits the session from
|
|
304
|
+
the provider. Swap the placeholder <code>docKey</code>/
|
|
305
|
+
<code>ticker</code> (<code>VITE_MF_DOC_KEY</code> /{' '}
|
|
306
|
+
<code>VITE_MF_DOC_TICKER</code>) for a real catalog document in your
|
|
307
|
+
deployment.
|
|
308
|
+
</p>
|
|
309
|
+
|
|
261
310
|
<div className="section-title">Holdings</div>
|
|
262
311
|
<table>
|
|
263
312
|
<thead>
|
|
@@ -328,10 +377,7 @@ export function App() {
|
|
|
328
377
|
<div className="agent-slot">
|
|
329
378
|
<MatterfactAgent
|
|
330
379
|
inline
|
|
331
|
-
publishableKey={config.publishableKey}
|
|
332
|
-
widgetOrigin={config.widgetOrigin}
|
|
333
380
|
surface={config.surface}
|
|
334
|
-
theme={config.theme}
|
|
335
381
|
// Pulled fresh every turn — the whole point of this example.
|
|
336
382
|
getPageContext={getPageContext}
|
|
337
383
|
// Host-defined tools + the unified telemetry hook.
|
|
@@ -350,16 +396,14 @@ export function App() {
|
|
|
350
396
|
right-click menu, and the float/dock panel. */}
|
|
351
397
|
{placement === 'corner' && (
|
|
352
398
|
<MatterfactAgent
|
|
353
|
-
publishableKey={config.publishableKey}
|
|
354
|
-
widgetOrigin={config.widgetOrigin}
|
|
355
399
|
surface={config.surface}
|
|
356
|
-
theme={config.theme}
|
|
357
400
|
getPageContext={getPageContext}
|
|
358
401
|
tools={tools}
|
|
359
402
|
onEvent={logEvent}
|
|
360
403
|
/>
|
|
361
404
|
)}
|
|
362
405
|
</div>
|
|
406
|
+
</MatterfactAuthProvider>
|
|
363
407
|
);
|
|
364
408
|
}
|
|
365
409
|
|
|
@@ -41,6 +41,14 @@ export const config = {
|
|
|
41
41
|
owner: decodeOwner(env.VITE_MF_ARTIFACT_OWNER),
|
|
42
42
|
token: env.VITE_MF_ARTIFACT_TOKEN ?? '',
|
|
43
43
|
},
|
|
44
|
+
// The embedded catalog document (MatterfactDoc). Session-authed through the
|
|
45
|
+
// provider — no per-component token — so it needs only a docKey + an initial
|
|
46
|
+
// ticker. Both ship with sensible placeholders so the demo renders out of the
|
|
47
|
+
// box; swap them for a real document in your deployment.
|
|
48
|
+
doc: {
|
|
49
|
+
docKey: env.VITE_MF_DOC_KEY ?? 'company-dossier',
|
|
50
|
+
ticker: env.VITE_MF_DOC_TICKER ?? 'NVDA',
|
|
51
|
+
},
|
|
44
52
|
surface: env.VITE_MF_SURFACE ?? 'embed-demo',
|
|
45
53
|
theme: (env.VITE_MF_THEME ?? 'light') as Theme,
|
|
46
54
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterfact/embed",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "The matterfact embeddable agent: mount the chat in a cross-origin iframe (a <script> loader for any site, or a <MatterfactAgent> React component), give the agent eyes on the host page, and embed matterfact artifacts inline with <MatterfactArtifact>.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"private": false,
|