@graview/embed 0.1.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/LICENSE ADDED
@@ -0,0 +1,96 @@
1
+ Elastic License 2.0
2
+
3
+ ## Acceptance
4
+
5
+ By using the software, you agree to all of the terms and conditions below.
6
+
7
+ ## Copyright License
8
+
9
+ The licensor grants you a non-exclusive, royalty-free, worldwide,
10
+ non-sublicensable, non-transferable license to use, copy, distribute, make
11
+ available, and prepare derivative works of the software, in each case subject
12
+ to the limitations and conditions below.
13
+
14
+ ## Limitations
15
+
16
+ You may not provide the software to third parties as a hosted or managed
17
+ service, where the service provides users with access to any substantial set
18
+ of the features or functionality of the software.
19
+
20
+ You may not move, change, disable, or circumvent the license key
21
+ functionality in the software, and you may not remove or obscure any
22
+ functionality in the software that is protected by the license key.
23
+
24
+ You may not alter, remove, or obscure any licensing, copyright, or other
25
+ notices of the licensor in the software. Any use of the licensor's trademarks
26
+ is subject to applicable law.
27
+
28
+ ## Patents
29
+
30
+ The licensor grants you a license, under any patent claims the licensor can
31
+ license, or becomes able to license, to make, have made, use, sell, offer for
32
+ sale, import and have imported the software, in each case subject to the
33
+ limitations and conditions in this license. This license does not cover any
34
+ patent claims that you cause to be infringed by modifications or additions to
35
+ the software. If you or your company make any written claim that the software
36
+ infringes or contributes to infringement of any patent, your patent license
37
+ for the software granted under these terms ends immediately. If your company
38
+ makes such a claim, your patent license ends immediately for work on behalf
39
+ of your company.
40
+
41
+ ## Notices
42
+
43
+ You must ensure that anyone who gets a copy of any part of the software from
44
+ you also gets a copy of these terms.
45
+
46
+ If you modify the software, you must include in any modified copies of the
47
+ software prominent notices stating that you have modified the software.
48
+
49
+ ## No Other Rights
50
+
51
+ These terms do not imply any licenses other than those expressly granted in
52
+ these terms.
53
+
54
+ ## Termination
55
+
56
+ If you use the software in violation of these terms, such use is not
57
+ licensed, and your licenses will automatically terminate. If the licensor
58
+ provides you with a notice of your violation, and you cease all violation of
59
+ this license no later than 30 days after you receive that notice, your
60
+ licenses will be reinstated retroactively. However, if you violate these
61
+ terms after such reinstatement, any additional violation of these terms will
62
+ cause your licenses to terminate automatically and permanently.
63
+
64
+ ## No Liability
65
+
66
+ *As far as the law allows, the software comes as is, without any warranty or
67
+ condition, and the licensor will not be liable to you for any damages arising
68
+ out of these terms or the use or nature of the software, under any kind of
69
+ legal claim.*
70
+
71
+ ## Definitions
72
+
73
+ The **licensor** is the entity offering these terms, and the **software** is
74
+ the software the licensor makes available under these terms, including any
75
+ portion of it.
76
+
77
+ **you** refers to the individual or entity agreeing to these terms.
78
+
79
+ **your company** is any legal entity, sole proprietorship, or other kind of
80
+ organization that you work for, plus all organizations that have control
81
+ over, are under the control of, or are under common control with that
82
+ organization. **control** means ownership of substantially all the assets of
83
+ an entity, or the power to direct its management and policies by vote,
84
+ contract, or otherwise. Control can be direct or indirect.
85
+
86
+ **your licenses** are all the licenses granted to you for the software under
87
+ these terms.
88
+
89
+ **use** means anything you do with the software requiring one of your
90
+ licenses.
91
+
92
+ **trademark** means trademarks, service marks, and similar rights.
93
+
94
+ ---
95
+
96
+ Copyright 2025-2026 En Dash Consulting
package/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # @graview/embed
2
+
3
+ Mount a declared Graview app into any element — a paragraph of a docs page, a
4
+ card on a dashboard, a preview in a builder — without the Shell, sized to the
5
+ element, themed within it, and switchable between its faces.
6
+
7
+ ```ts
8
+ import { mount } from "@graview/embed";
9
+
10
+ const handle = mount(document.querySelector("#garden")!, {
11
+ app, // defineApp(...)
12
+ seed, // the graph to open with, or nothing
13
+ face: "graview", // "scene" | "graview" | "pages" | "picture" — one named lens, no chrome: stop "#view=<place>"
14
+ stop: "#focus=plot-1", // the scene's view state, as its URL fragment
15
+ principal: { kind: "human", id: "june", roles: ["coordinator"] },
16
+ toggle: true, // the face switcher and Standing, above the picture
17
+ });
18
+
19
+ handle.setFace("pages"); // the routed face, at the element's width
20
+ handle.setStop("#overview=1&expand=kind:plot");
21
+ handle.unmount();
22
+ ```
23
+
24
+ `<Embed {...options} />` is the same thing as a React component.
25
+
26
+ What this asks of the framework, and what it adds: the theme scopes to the
27
+ element (`themeCss(scheme, brand, { scope })`) rather than the document; the
28
+ panes size against the picture's own box (`cqh`) rather than the viewport;
29
+ the routed face runs on a memory router, so the host page's address is never
30
+ touched; the brand's fonts are fetched by the embed rather than assumed. The
31
+ store is in memory and starts from the seed on every mount.
@@ -0,0 +1,121 @@
1
+ import { Store, type AnySchema, type Brand, type GraviewApp, type PresenceChannel, type Principal } from "@graview/core";
2
+ import { type PageComponent, type PageRegistry } from "@graview/pages";
3
+ import { type Scheme, type ReactViewRegistry } from "@graview/react";
4
+ /**
5
+ * A GRAVIEW IN SOMEBODY ELSE'S PAGE.
6
+ *
7
+ * The Shell assumes it owns the window: the viewport is its height, the
8
+ * document is its theme, the address bar is its view state. An embed owns
9
+ * one element. So the theme is scoped to that element, the panes size
10
+ * against the picture's own box, the routed face runs on a memory router,
11
+ * the store lives in memory and starts from the seed, and the view state is
12
+ * a prop rather than a URL. Everything else — the scene, the rails, the
13
+ * inspector, the pages — is the framework's own, unchanged.
14
+ */
15
+ /**
16
+ * The faces. `picture` is ONE NAMED LENS AND NOTHING ELSE — the place the
17
+ * stop names (`#view=the-week`), drawn at full size over the kind's current
18
+ * members, with no bar, no rail, no standing: a page that is about a lens
19
+ * shows the lens, not an app with the lens somewhere inside it.
20
+ */
21
+ export type EmbedFace = "scene" | "graview" | "pages" | "picture";
22
+ export interface EmbedOptions<S extends AnySchema = AnySchema> {
23
+ readonly app: GraviewApp<S>;
24
+ /** The graph to open with. Nothing means the empty city. */
25
+ readonly seed?: {
26
+ readonly nodes: readonly unknown[];
27
+ readonly edges: readonly unknown[];
28
+ };
29
+ /** Which face to show. */
30
+ /** Which face to open on. Omitted, the stop decides: altitude opens the Graview, anything else the scene. */
31
+ readonly face?: EmbedFace;
32
+ /** The scene's view state, as the fragment the app itself would put in its address bar. */
33
+ readonly stop?: string;
34
+ /** For the pages face: the path to open, within the app's own routes. */
35
+ readonly path?: string;
36
+ readonly principal?: Principal;
37
+ /**
38
+ * WHO ELSE IS HERE, if the host wants that: an embed broadcasts nothing
39
+ * and draws nobody unless it is handed a channel — a page that puts a
40
+ * graph on it is not thereby a page that tells its readers about each
41
+ * other.
42
+ */
43
+ readonly presence?: PresenceChannel;
44
+ /**
45
+ * The seats a reader may take, when the page wants the policy to be felt
46
+ * rather than read: each is a name and a principal, shown on the strip and
47
+ * pressed while it is at the keyboard. The strip, the pages and the acts
48
+ * all narrow to the seat, so what a gardener may not do is struck through
49
+ * the moment a gardener sits down.
50
+ */
51
+ readonly seats?: readonly {
52
+ readonly label: string;
53
+ readonly principal: Principal;
54
+ }[];
55
+ /** "auto" reads the host page: its `data-theme` stamp, else the system's preference. */
56
+ readonly scheme?: Scheme | "auto";
57
+ /** Defaults to the app's own brand. */
58
+ readonly brand?: Brand;
59
+ /** A store to share; otherwise one is made from the app and the seed. */
60
+ readonly store?: Store<S>;
61
+ /** Views beyond the derived defaults. */
62
+ readonly views?: (schema: S) => ReactViewRegistry<S>;
63
+ /** The pages face's own pages, over the derived defaults. */
64
+ readonly pages?: PageRegistry<S, PageComponent<S>>;
65
+ /** The face switcher and Standing, above the picture. Default on. */
66
+ readonly toggle?: boolean;
67
+ /** Fetch the brand's fonts. Default on; off when the host already has them. */
68
+ readonly fonts?: boolean;
69
+ /** The embed's height; the element's own by default. */
70
+ readonly height?: number | string;
71
+ /** What Standing says when nothing is wrong. */
72
+ readonly standing?: string;
73
+ /**
74
+ * What this embed is called, for assistive technology. Several Graviews
75
+ * on one page each carry the same landmarks — the relation key, the
76
+ * inspector, the pages' navigation — and a landmark has to be unique by
77
+ * role and name; every landmark inside is named after the embed.
78
+ */
79
+ readonly label?: string;
80
+ }
81
+ export interface EmbedProps<S extends AnySchema = AnySchema> extends EmbedOptions<S> {
82
+ /** Called when the strip's switcher is pressed; the host decides the face. */
83
+ readonly onFace?: (face: EmbedFace) => void;
84
+ /** Called when a seat on the strip is pressed; the host decides who sits. */
85
+ readonly onSeat?: (principal: Principal) => void;
86
+ }
87
+ /** The face a stop implies: a stop at altitude opens the Graview. */
88
+ export declare function faceOf(stop: string | undefined): EmbedFace;
89
+ /** The host page's scheme: an explicit `data-theme`, else the system's preference. */
90
+ export declare function hostScheme(): Scheme;
91
+ export declare function Embed<S extends AnySchema>(props: EmbedProps<S>): import("react").JSX.Element;
92
+ export interface EmbedHandle {
93
+ setFace(face: EmbedFace): void;
94
+ setStop(stop: string): void;
95
+ setScheme(scheme: Scheme): void;
96
+ /** Put another principal at the keyboard; the store and its history stay. */
97
+ setSeat(principal: Principal): void;
98
+ /** Re-dress the embed: another brand, or the same brand with a different kit. */
99
+ setBrand(brand: Brand | undefined): void;
100
+ readonly store: Store<AnySchema>;
101
+ unmount(): void;
102
+ }
103
+ /**
104
+ * Mounts an app into an element and hands back the controls. The first
105
+ * render is synchronous, so what comes back is already on the page.
106
+ */
107
+ export declare function mount<S extends AnySchema>(element: HTMLElement, options: EmbedOptions<S>): EmbedHandle;
108
+ /**
109
+ * Mount each element as the reader comes near it.
110
+ *
111
+ * Twelve applications at once is a lot to ask of a first paint; each mounts
112
+ * when the reader is a screen away, and stays. A sweep on scroll rather than
113
+ * an IntersectionObserver: a fast scroll can jump an element through the
114
+ * observer's margin between two of its checks, and a picture that stayed
115
+ * "loading…" because the reader scrolled quickly is worse than a sweep that
116
+ * costs one rectangle per element per frame.
117
+ */
118
+ export declare function mountWhenNear(elements: Iterable<HTMLElement>, mountOne: (element: HTMLElement) => void, options?: {
119
+ readonly near?: number;
120
+ }): () => void;
121
+ //# sourceMappingURL=embed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../src/embed.tsx"],"names":[],"mappings":"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"}
package/dist/embed.js ADDED
@@ -0,0 +1,316 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Store } from "@graview/core";
3
+ import { EMPTY_VIEW, aggregateId, fromUrl, withFocus, withOverview } from "@graview/layout";
4
+ import { PagesApp, PlacePicture } from "@graview/pages";
5
+ import { Companion, Inspector, OverviewButton, Places, Profile, ShowInstallation, Standing, descentTarget, registerDefaultViews, themeCss, useWidth } from "@graview/primitives";
6
+ import { StudioPlace } from "@graview/studio";
7
+ import { createViews, GraviewProvider, Scene, useGraview, useNavigation, useTheKeyboardLandsSomewhere, } from "@graview/react";
8
+ import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
9
+ import { createRoot } from "react-dom/client";
10
+ import { flushSync } from "react-dom";
11
+ import { fontsLink } from "./fonts.js";
12
+ let sequence = 0;
13
+ /** A store from a declaration and a seed: the app's own policy, in memory. */
14
+ function storeOf(app, seed) {
15
+ return new Store({
16
+ schema: app.schema,
17
+ mutations: app.mutations ?? [],
18
+ invariants: app.invariants ?? [],
19
+ ...(seed ? { snapshot: seed } : {}),
20
+ ...(app.policy ? { policy: app.policy } : {}),
21
+ ...(app.intelligence ? { intelligence: app.intelligence } : {}),
22
+ });
23
+ }
24
+ /**
25
+ * The scene's view for a face and a stop.
26
+ *
27
+ * A STOP THAT NAMES A PLACE GOES THERE HERE TOO. `#view=the-season` is the
28
+ * link a page can write — `placeHref` spells it — and the scene's URL sync
29
+ * has resolved it to the group the place is a picture of since it existed.
30
+ * The embed read its `stop` through `fromUrl` alone, so a host page saying
31
+ * `data-stop="#view=the-season"` landed at the default view with the
32
+ * season's pill unpressed: the pasted-link problem, one level up again.
33
+ */
34
+ function viewFor(face, stop, kinds, places) {
35
+ const parsed = stop ? fromUrl(stop) : EMPTY_VIEW;
36
+ const named = parsed.within?.["view"];
37
+ const place = named !== undefined && !parsed.focusId ? places.find((candidate) => candidate.as === named) : undefined;
38
+ const asked = place ? { ...parsed, focusId: aggregateId(place.kind) } : parsed;
39
+ if (face === "graview")
40
+ return withOverview(asked, true);
41
+ if (asked.overview)
42
+ return withFocus(withOverview(asked, false), descentTarget(asked, kinds));
43
+ return asked;
44
+ }
45
+ /** The face a stop implies: a stop at altitude opens the Graview. */
46
+ export function faceOf(stop) {
47
+ return stop && fromUrl(stop).overview ? "graview" : "scene";
48
+ }
49
+ /** The host page's scheme: an explicit `data-theme`, else the system's preference. */
50
+ export function hostScheme() {
51
+ if (typeof document === "undefined")
52
+ return "light";
53
+ const stamped = document.documentElement.dataset["theme"];
54
+ if (stamped === "dark" || stamped === "light")
55
+ return stamped;
56
+ return typeof matchMedia === "function" && matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
57
+ }
58
+ export function Embed(props) {
59
+ const { app, seed, face = faceOf(props.stop), stop, path = "/", principal, scheme: askedScheme = "auto", brand = app.brand, toggle = true, fonts = true, height = "100%", standing = "Everything is in order", pages, label, } = props;
60
+ const rootRef = useRef(null);
61
+ useTheKeyboardLandsSomewhere(rootRef);
62
+ const scope = useMemo(() => `graview-embed-${++sequence}`, []);
63
+ /*
64
+ * ONE STORE ACROSS THE SEATS. Who is at the keyboard is the provider's
65
+ * business, not the store's: with the principal in these dependencies a
66
+ * seat change made a fresh store from the seed, and a React host that sat
67
+ * somebody else down lost every edit and the history with them.
68
+ */
69
+ const store = useMemo(() => props.store ?? storeOf(app, seed), [props.store, app, seed]);
70
+ const views = useMemo(() => (props.views ? props.views(app.schema) : registerDefaultViews(app.schema, createViews(app.schema))), [props.views, app.schema]);
71
+ const kinds = app.schema.kinds;
72
+ // The first view only: after it, where the reader goes is theirs.
73
+ const initialView = useMemo(() => viewFor(face, stop, kinds, views.places()), []);
74
+ const scheme = askedScheme === "auto" ? hostScheme() : askedScheme;
75
+ const css = useMemo(() => themeCss(scheme, brand, { scope: `.${scope}` }), [scheme, brand, scope]);
76
+ // The brand's fonts, fetched once per family set, without the host's help.
77
+ useEffect(() => {
78
+ if (!fonts || typeof document === "undefined")
79
+ return;
80
+ const href = fontsLink(brand);
81
+ if (!href || document.querySelector(`link[href="${href}"]`))
82
+ return;
83
+ const link = document.createElement("link");
84
+ link.rel = "stylesheet";
85
+ link.href = href;
86
+ document.head.appendChild(link);
87
+ }, [brand, fonts]);
88
+ // Landmarks inside, named after the embed — kept so through re-renders.
89
+ useLayoutEffect(() => {
90
+ const root = rootRef.current;
91
+ if (!root || !label)
92
+ return;
93
+ const name = (el) => {
94
+ const own = el.getAttribute("aria-label") ?? "";
95
+ if (own.startsWith(`${label} · `))
96
+ return;
97
+ // Named the same thing: "The pipeline · The pipeline" is one name said
98
+ // twice, not a place inside a place. A region of that name IS the
99
+ // embed's region, so it stops being a second landmark (two regions of
100
+ // one name is axe's `landmark-unique`) and stays a named group.
101
+ if (own === label) {
102
+ if (el.getAttribute("role") === "region")
103
+ el.setAttribute("role", "group");
104
+ return;
105
+ }
106
+ el.setAttribute("aria-label", own ? `${label} · ${own}` : label);
107
+ };
108
+ // The root is the embed's own region and already wears the label; the
109
+ // sweep names what is INSIDE it.
110
+ const sweep = () => root.querySelectorAll("aside, nav, main, header, footer, [role=region], [role=complementary], [role=navigation]").forEach(name);
111
+ sweep();
112
+ const observer = new MutationObserver(sweep);
113
+ observer.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: ["aria-label"] });
114
+ return () => observer.disconnect();
115
+ }, [label]);
116
+ /*
117
+ * THE EMBED IS ITSELF A LANDMARK.
118
+ *
119
+ * `label` named every landmark INSIDE ("Chapter 13 · Places") and left the
120
+ * root a plain div — so on somebody else's page the strip, the seats and
121
+ * the picture sat outside any landmark at all (axe `region`), and a reader
122
+ * moving by landmark could not reach the app, let alone tell two of them
123
+ * apart at the top. A named region is what the label was for.
124
+ *
125
+ * Without a label it takes the app's own name, and two unlabelled embeds
126
+ * of one app are then two regions with one name — which is the ambiguity
127
+ * the docs warn about, said out loud by `landmark-unique` instead of
128
+ * silently.
129
+ */
130
+ return (_jsxs("section", { ref: rootRef, className: scope, "aria-label": label ?? app.name, "data-graview-embed": face, style: { position: "relative", height, minHeight: 320, display: "flex", flexDirection: "column", overflow: "hidden", borderRadius: "var(--graview-radius, 12px)" }, children: [_jsx("style", { children: css }), _jsxs(GraviewProvider, { store: store, views: views, initialView: initialView, scheme: scheme, ...(brand ? { brand } : {}), ...(principal ? { principal } : {}), ...(props.seats ? { seats: props.seats } : {}), ...(props.presence ? { presence: props.presence } : {}),
131
+ /* The reader's own text size and motion, on somebody else's page
132
+ too: the answer lives on the browser, not on the installation. */
133
+ settings: app.settings ?? [], children: [_jsx(Faces, { face: face, stop: stop, kinds: kinds, places: views.places() }), toggle && face !== "picture" ? _jsx(Strip, { app: app, face: face, onFace: props.onFace, standing: standing, seats: props.seats, principal: principal, onSeat: props.onSeat }) : null, face === "picture" ? (
134
+ /*
135
+ * The lens fills the frame: a one-row grid stretches it to the
136
+ * height it was given, and it scrolls inside itself past that.
137
+ */
138
+ _jsx("div", { "data-testid": "embed-picture",
139
+ // A region that may scroll has to be reachable by keyboard, and a
140
+ // reachable region has to say what it is: the picture's own name.
141
+ tabIndex: 0, "aria-label": views.places().find((place) => place.as === (stop ? fromUrl(stop).within?.["view"] : undefined))?.title ?? "The picture", style: {
142
+ flex: "1 1 auto",
143
+ minHeight: 0,
144
+ display: "grid",
145
+ gridTemplateRows: "minmax(0, 1fr)",
146
+ overflow: "auto",
147
+ background: "var(--graview-ground)",
148
+ color: "var(--graview-ink)",
149
+ fontFamily: "var(--graview-font-body, system-ui)",
150
+ }, children: _jsx(PlacePicture, { store: store, views: views, as: (stop ? fromUrl(stop).within?.["view"] : undefined) ?? "" }) })) : face === "pages" ? (_jsx("div", { style: { flex: "1 1 auto", minHeight: 0, overflow: "auto" }, children: _jsx(PagesApp, { context: { store, embedded: true, ...(brand ? { brand } : {}), ...(principal ? { principal } : {}), ...(props.seats ? { seats: props.seats } : {}) }, ...(pages ? { registry: pages } : {}), initialPath: path }) })) : (_jsxs("div", { style: { position: "relative", flex: "1 1 auto", minHeight: 0, containerType: "size" }, children: [_jsx(Scene, { renderer: "dom" }), _jsx(OverviewButton, {}), _jsx(Companion, {}), _jsx(Inspector, { placement: "menu" })] }))] })] }));
151
+ }
152
+ /** Keeps the scene's view in step with the face and stop props. */
153
+ function Faces({ face, stop, kinds, places }) {
154
+ const { view, go } = useNavigation();
155
+ const last = useRef({ face, stop });
156
+ // A layout effect, so a face set through the handle is on the page when
157
+ // the handle's call returns rather than one tick later.
158
+ useLayoutEffect(() => {
159
+ const stopChanged = last.current.stop !== stop;
160
+ const faceChanged = last.current.face !== face;
161
+ const wasPages = last.current.face === "pages";
162
+ last.current = { face, stop };
163
+ if (!stopChanged && !faceChanged)
164
+ return;
165
+ // The pages face has no view, and a picture is its stop; a stop set
166
+ // while there lands when the scene comes back. Otherwise a face change
167
+ // keeps where you were and only rises or descends.
168
+ if (face === "pages" || face === "picture")
169
+ return;
170
+ const next = (stopChanged || wasPages) && stop !== undefined
171
+ ? viewFor(face, stop, kinds, places)
172
+ : face === "graview"
173
+ ? withOverview(view, true)
174
+ : view.overview
175
+ ? withFocus(withOverview(view, false), descentTarget(view, kinds))
176
+ : view;
177
+ go(next);
178
+ }, [face, stop, kinds, view, go]);
179
+ return null;
180
+ }
181
+ function Strip({ app, face, onFace, standing, seats, principal, onSeat, }) {
182
+ const { brand } = useGraview();
183
+ const sameSeat = (a, b) => a !== undefined && a.id === b.id && a.kind === b.kind;
184
+ /*
185
+ * COMPACT BELOW A PHONE'S WIDTH: the places and the seats as one select
186
+ * each rather than a pill per name. At 360px the pills wrapped to five
187
+ * rows and the strip was taller than the picture under it.
188
+ */
189
+ const strip = useRef(null);
190
+ const width = useWidth(strip);
191
+ const compact = width !== null && width < 560;
192
+ // Two faces, not three: altitude is the scene's own control, on the
193
+ // picture, and a third pill for it here said the same thing twice.
194
+ const faces = [
195
+ { id: "scene", label: "Scene", title: "The picture — rise and descend on it", pressed: face !== "pages" },
196
+ { id: "pages", label: "Pages", title: "The same app as ordinary pages", pressed: face === "pages" },
197
+ ];
198
+ return (_jsxs("div", { ref: strip, role: "group", "aria-label": "Face", "data-testid": "embed-faces", "data-embed-strip": compact ? "compact" : "full", style: {
199
+ display: "flex",
200
+ alignItems: "center",
201
+ // Wraps rather than clips: at a phone's width Standing takes the
202
+ // next line instead of losing its last word.
203
+ flexWrap: "wrap",
204
+ gap: 6,
205
+ padding: "8px 12px",
206
+ flex: "0 0 auto",
207
+ borderBottom: "1px solid var(--graview-edge)",
208
+ background: "var(--graview-bar)",
209
+ fontSize: "0.875rem",
210
+ }, children: [_jsx("span", { style: { fontFamily: "var(--graview-font-display)", letterSpacing: "0.12em", textTransform: "uppercase", fontSize: "0.75rem", marginRight: 6 }, children: brand?.name ?? "Graview" }), faces.map((candidate) => (_jsx("button", { type: "button", "aria-pressed": candidate.pressed, "data-testid": `embed-face-${candidate.id}`, title: candidate.title, onClick: () => onFace?.(candidate.id), style: {
211
+ padding: "3px 11px",
212
+ borderRadius: 999,
213
+ fontSize: "0.875rem",
214
+ borderWidth: 1,
215
+ borderStyle: "solid",
216
+ borderColor: candidate.pressed ? "var(--graview-accent)" : "var(--graview-edge)",
217
+ color: candidate.pressed ? "var(--graview-accent)" : "var(--graview-ink-muted)",
218
+ background: candidate.pressed ? "var(--graview-panel)" : "transparent",
219
+ }, children: candidate.label }, candidate.id))), face !== "pages" ? _jsx(Places, { compact: compact }) : null, face !== "pages" ? _jsx(ShowInstallation, {}) : null, face !== "pages" ? _jsx(StudioPlace, { app: app, within: "box" }) : null, _jsx(Profile, {}), seats && seats.length > 1 && compact ? (_jsx("select", { "aria-label": "Seat", "data-testid": "embed-seats", value: seats.find((seat) => sameSeat(principal, seat.principal))?.principal.id ?? "", onChange: (event) => {
220
+ const seat = seats.find((candidate) => candidate.principal.id === event.target.value);
221
+ if (seat)
222
+ onSeat?.(seat.principal);
223
+ }, style: {
224
+ minHeight: 24,
225
+ maxWidth: "46%",
226
+ padding: "3px 8px",
227
+ borderRadius: 999,
228
+ fontSize: "0.875rem",
229
+ borderWidth: 1,
230
+ borderStyle: "solid",
231
+ borderColor: "var(--graview-accent)",
232
+ color: "var(--graview-accent)",
233
+ background: "var(--graview-panel)",
234
+ }, children: seats.map((seat) => (_jsxs("option", { value: seat.principal.id, children: ["As ", seat.label] }, seat.principal.id))) })) : seats && seats.length > 1 ? (_jsxs("div", { role: "group", "aria-label": "Seat", "data-testid": "embed-seats", style: { display: "flex", alignItems: "center", gap: 6, marginLeft: 6 }, children: [_jsx("span", { style: { fontSize: "0.75rem", letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--graview-ink-faint)" }, children: "As" }), seats.map((seat) => {
235
+ const pressed = sameSeat(principal, seat.principal);
236
+ return (_jsx("button", { type: "button", "aria-pressed": pressed, "data-testid": `embed-seat-${seat.principal.id}`, title: `Sit down as ${seat.label}: the strip, the pages and the acts narrow to what this seat may do`, onClick: () => onSeat?.(seat.principal), style: {
237
+ padding: "3px 11px",
238
+ borderRadius: 999,
239
+ fontSize: "0.875rem",
240
+ borderWidth: 1,
241
+ borderStyle: "solid",
242
+ borderColor: pressed ? "var(--graview-accent)" : "var(--graview-edge)",
243
+ color: pressed ? "var(--graview-accent)" : "var(--graview-ink-muted)",
244
+ background: pressed ? "var(--graview-panel)" : "transparent",
245
+ }, children: seat.label }, seat.principal.id));
246
+ })] })) : null, _jsx("div", { style: { marginLeft: "auto", minWidth: 0 }, children: _jsx(Standing, { clean: standing }) })] }));
247
+ }
248
+ /**
249
+ * Mounts an app into an element and hands back the controls. The first
250
+ * render is synchronous, so what comes back is already on the page.
251
+ */
252
+ export function mount(element, options) {
253
+ const store = options.store ?? storeOf(options.app, options.seed);
254
+ let setters = null;
255
+ function Host() {
256
+ const [face, setFace] = useState(options.face ?? faceOf(options.stop));
257
+ const [stop, setStop] = useState(options.stop);
258
+ const [scheme, setScheme] = useState(options.scheme ?? "auto");
259
+ const [principal, setSeat] = useState(options.principal);
260
+ const [brand, setBrand] = useState(options.brand);
261
+ setters = { face: setFace, stop: setStop, scheme: setScheme, seat: setSeat, brand: setBrand };
262
+ return (_jsx(Embed, { ...options, store: store, face: face, ...(stop !== undefined ? { stop } : {}), ...(principal ? { principal } : {}), ...(brand ? { brand } : {}), scheme: scheme, onFace: setFace, onSeat: setSeat }));
263
+ }
264
+ const root = createRoot(element);
265
+ flushSync(() => root.render(_jsx(Host, {})));
266
+ return {
267
+ store: store,
268
+ setFace: (face) => flushSync(() => setters?.face(face)),
269
+ setStop: (stop) => flushSync(() => setters?.stop(stop)),
270
+ setScheme: (scheme) => flushSync(() => setters?.scheme(scheme)),
271
+ setSeat: (principal) => flushSync(() => setters?.seat(principal)),
272
+ setBrand: (brand) => flushSync(() => setters?.brand(brand)),
273
+ unmount: () => root.unmount(),
274
+ };
275
+ }
276
+ /**
277
+ * Mount each element as the reader comes near it.
278
+ *
279
+ * Twelve applications at once is a lot to ask of a first paint; each mounts
280
+ * when the reader is a screen away, and stays. A sweep on scroll rather than
281
+ * an IntersectionObserver: a fast scroll can jump an element through the
282
+ * observer's margin between two of its checks, and a picture that stayed
283
+ * "loading…" because the reader scrolled quickly is worse than a sweep that
284
+ * costs one rectangle per element per frame.
285
+ */
286
+ export function mountWhenNear(elements, mountOne, options = {}) {
287
+ const near = options.near ?? 900;
288
+ const waiting = new Set(elements);
289
+ let pending = false;
290
+ const sweep = () => {
291
+ pending = false;
292
+ for (const element of waiting) {
293
+ const rect = element.getBoundingClientRect();
294
+ // Near below, on screen, or already scrolled past: all of these are
295
+ // places a reader can be looking at next.
296
+ if (rect.top < innerHeight + near && rect.bottom > -near) {
297
+ waiting.delete(element);
298
+ mountOne(element);
299
+ }
300
+ }
301
+ };
302
+ const later = () => {
303
+ if (pending || waiting.size === 0)
304
+ return;
305
+ pending = true;
306
+ requestAnimationFrame(sweep);
307
+ };
308
+ addEventListener("scroll", later, { passive: true });
309
+ addEventListener("resize", later, { passive: true });
310
+ sweep();
311
+ return () => {
312
+ removeEventListener("scroll", later);
313
+ removeEventListener("resize", later);
314
+ };
315
+ }
316
+ //# sourceMappingURL=embed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embed.js","sourceRoot":"","sources":["../src/embed.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Brand } from "@graview/core";
2
+ /**
3
+ * The families a brand names, in the order it names them — the first family
4
+ * of each stack, which is the one that has to be fetched. `ui-sans-serif`
5
+ * and friends are the browser's own and are left out.
6
+ */
7
+ export declare function familiesOf(brand: Brand | undefined): readonly string[];
8
+ /** A Google Fonts stylesheet URL for those families, or null when there is nothing to fetch. */
9
+ export declare function fontsLink(brand: Brand | undefined): string | null;
10
+ //# sourceMappingURL=fonts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,MAAM,EAAE,CAStE;AAED,gGAAgG;AAChG,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKjE"}
package/dist/fonts.js ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The families a brand names, in the order it names them — the first family
3
+ * of each stack, which is the one that has to be fetched. `ui-sans-serif`
4
+ * and friends are the browser's own and are left out.
5
+ */
6
+ export function familiesOf(brand) {
7
+ const stacks = [brand?.typography?.body, brand?.typography?.display, brand?.typography?.mono];
8
+ const out = [];
9
+ for (const stack of stacks) {
10
+ const first = stack?.split(",")[0]?.trim().replace(/^["']|["']$/g, "");
11
+ if (!first || first.startsWith("ui-") || first === "system-ui" || first.startsWith("-apple"))
12
+ continue;
13
+ if (!out.includes(first))
14
+ out.push(first);
15
+ }
16
+ return out;
17
+ }
18
+ /** A Google Fonts stylesheet URL for those families, or null when there is nothing to fetch. */
19
+ export function fontsLink(brand) {
20
+ const families = familiesOf(brand);
21
+ if (families.length === 0)
22
+ return null;
23
+ const query = families.map((f) => `family=${encodeURIComponent(f).replace(/%20/g, "+")}:wght@400;500;600;700`).join("&");
24
+ return `https://fonts.googleapis.com/css2?${query}&display=swap`;
25
+ }
26
+ //# sourceMappingURL=fonts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fonts.js","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAwB;IACjD,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IAC9F,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,SAAS;QACvG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,SAAS,CAAC,KAAwB;IAChD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,kBAAkB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzH,OAAO,qCAAqC,KAAK,eAAe,CAAC;AACnE,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { Embed, faceOf, hostScheme, mount, mountWhenNear } from "./embed.js";
2
+ export type { EmbedFace, EmbedHandle, EmbedOptions, EmbedProps } from "./embed.js";
3
+ export { fontsLink, familiesOf } from "./fonts.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC7E,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { Embed, faceOf, hostScheme, mount, mountWhenNear } from "./embed.js";
2
+ export { fontsLink, familiesOf } from "./fonts.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@graview/embed",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Mount a declared Graview app into any element — the scene, the Graview, or the routed pages — without the Shell, sized and themed within the element.",
6
+ "keywords": [
7
+ "graview",
8
+ "context-graph",
9
+ "typed-graph",
10
+ "interface",
11
+ "declarative",
12
+ "embed",
13
+ "widget"
14
+ ],
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ }
22
+ },
23
+ "dependencies": {
24
+ "@graview/core": "0.1.0",
25
+ "@graview/pages": "0.1.0",
26
+ "@graview/primitives": "0.1.0",
27
+ "@graview/react": "0.1.0",
28
+ "@graview/layout": "0.1.0",
29
+ "@graview/tools": "0.1.0",
30
+ "@graview/studio": "0.1.0"
31
+ },
32
+ "peerDependencies": {
33
+ "react": ">=18",
34
+ "react-dom": ">=18"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "README.md"
39
+ ],
40
+ "sideEffects": false,
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/en-dash-consulting/graview.git",
44
+ "directory": "packages/embed"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "license": "Elastic-2.0",
50
+ "homepage": "https://graview.dev/docs/packages/embed.html",
51
+ "bugs": {
52
+ "url": "https://github.com/en-dash-consulting/graview/issues"
53
+ },
54
+ "engines": {
55
+ "node": ">=22"
56
+ },
57
+ "scripts": {
58
+ "build": "tsc -b"
59
+ }
60
+ }