@graview/embed 0.1.38 → 0.1.40
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 +135 -2
- package/dist/draft.d.ts +29 -0
- package/dist/draft.d.ts.map +1 -0
- package/dist/draft.js +54 -0
- package/dist/draft.js.map +1 -0
- package/dist/drawn.d.ts +21 -0
- package/dist/drawn.d.ts.map +1 -0
- package/dist/drawn.js +154 -0
- package/dist/drawn.js.map +1 -0
- package/dist/embed.d.ts +39 -5
- package/dist/embed.d.ts.map +1 -1
- package/dist/embed.js +67 -24
- package/dist/embed.js.map +1 -1
- package/dist/first-draw.d.ts +60 -0
- package/dist/first-draw.d.ts.map +1 -0
- package/dist/first-draw.js +95 -0
- package/dist/first-draw.js.map +1 -0
- package/dist/frame.d.ts +40 -5
- package/dist/frame.d.ts.map +1 -1
- package/dist/frame.js +31 -6
- package/dist/frame.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/pages.d.ts +22 -1
- package/dist/pages.d.ts.map +1 -1
- package/dist/pages.js +25 -7
- package/dist/pages.js.map +1 -1
- package/package.json +13 -8
package/README.md
CHANGED
|
@@ -11,9 +11,10 @@ const handle = mount(document.querySelector("#garden")!, {
|
|
|
11
11
|
app, // defineApp(...)
|
|
12
12
|
seed, // the graph to open with, or nothing
|
|
13
13
|
face: "graview", // "scene" | "graview" | "pages" | "picture" — one named lens, no chrome: stop "#view=<place>"; leave it out and the app opens on its home view, else the scene
|
|
14
|
-
stop: "#focus=plot-1", // the scene's view state, as its URL fragment
|
|
14
|
+
stop: "#focus=plot-1", // the scene's view state, as its URL fragment; none, and the scene opens on the overview
|
|
15
|
+
path: "/plots", // the routed face's page; on the scene, nothing or "/places/overview" — the whole thing from above
|
|
15
16
|
principal: { kind: "human", id: "june", roles: ["coordinator"] },
|
|
16
|
-
bar: true, // the app bar over every face (the default)
|
|
17
|
+
bar: true, // the app bar over every face (the default); { faces: false, name: false } under a host's own bar
|
|
17
18
|
switch: "words", // the bar's Scene/Pages switch: its words where they fit (the default), or "icons" for its marks alone
|
|
18
19
|
});
|
|
19
20
|
|
|
@@ -23,6 +24,12 @@ handle.setStop("#overview=1&expand=kind:plot");
|
|
|
23
24
|
handle.unmount();
|
|
24
25
|
```
|
|
25
26
|
|
|
27
|
+
A scene with nowhere to be — no `stop`, no `path` but the overview's, no
|
|
28
|
+
first place in the declaration — opens on the overview, the whole thing
|
|
29
|
+
from above, as `graview preview` at `/places/overview` does: `mount(stage,
|
|
30
|
+
{ face: "scene" })` under either routing, and `routing: "address"` at a bare
|
|
31
|
+
base. A `stop` set then or later goes down to it.
|
|
32
|
+
|
|
26
33
|
`<Embed {...options} />` is the same thing as a React component.
|
|
27
34
|
|
|
28
35
|
## The app bar
|
|
@@ -71,6 +78,21 @@ signed in, the seats, the host's own actions and, for whoever keeps the
|
|
|
71
78
|
app, the installation and the studio). `bar: false` draws none of it, for a
|
|
72
79
|
host whose own page already says all of that.
|
|
73
80
|
|
|
81
|
+
UNDER A HOST'S OWN BAR. A product with its own shell that mounts the scene
|
|
82
|
+
in it says what the bar leaves out (`EmbedBar`): `faces: false` draws no
|
|
83
|
+
switch — its Pages side is Graview's derived pages, not the product's own —
|
|
84
|
+
and `name: false` no app mark and name, which the product's bar already
|
|
85
|
+
says. The scene's places, Find, the standing (Activity beside it once
|
|
86
|
+
anything has happened) and the person stay. Pass `heading: false` too, so
|
|
87
|
+
nothing in the embed says the app's name as a heading.
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
mount(stage, { app, store, face: "graview", bar: { faces: false, name: false }, heading: false });
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`@graview/embed/pages` takes `bar: { name: false }` the same way (it has no
|
|
94
|
+
switch to leave out).
|
|
95
|
+
|
|
74
96
|
THE BAR FITS ITS BOX. Every rule the bar is drawn by reads the bar's own
|
|
75
97
|
width, never the screen's: an embed in a 650 px box on a 1440 desk is a
|
|
76
98
|
narrow bar, not a desk's bar squeezed, and below 640 px of its own it is a
|
|
@@ -108,6 +130,32 @@ draws them first. Until a face's chunk arrives its box stands empty
|
|
|
108
130
|
(`aria-busy`), and `handle.drawn()` resolves once the face asked for is on
|
|
109
131
|
the page — after `mount`, and after every change of face.
|
|
110
132
|
|
|
133
|
+
A face on the page is not yet a place a person can read: its parts, the
|
|
134
|
+
fonts, a worker view's drawing and its pictures may still be on their way.
|
|
135
|
+
Once the place the reader is on has drawn and settled — every part drawn
|
|
136
|
+
on it arrived, the fonts and images loaded, each worker view drawn (or
|
|
137
|
+
stopped, what stands in its place drawn), each frame guest drawn (or
|
|
138
|
+
silent past its `limits.readyMs`, eight seconds by default) and nothing
|
|
139
|
+
moving for 200 ms —
|
|
140
|
+
the embed's root wears `data-graview-drawn`, its value the place's path,
|
|
141
|
+
and `onDrawn(place)` is told where it is as `where()` says it. A move to
|
|
142
|
+
another place takes the attribute off in the same commit, and the next
|
|
143
|
+
place puts it back as it settles. A place that never stops moving is said
|
|
144
|
+
drawn after ten seconds all the same. A host picturing a place headless
|
|
145
|
+
waits for the attribute rather than a timer:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
await page.waitForSelector("[data-graview-drawn]");
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
A frame guest (`guestView({ url })`) has drawn once it has said it is
|
|
152
|
+
ready, been handed what it shows and asked for its height — or stayed
|
|
153
|
+
quiet for a moment after, if it never asks — and its frame says
|
|
154
|
+
`data-guest-view-drawn`; one that never says it is ready says
|
|
155
|
+
`data-guest-view-failed="silent"`. Until one or the other, the frame is
|
|
156
|
+
`aria-busy`, and so is its holder until the frame's host has drawn the
|
|
157
|
+
frame in it.
|
|
158
|
+
|
|
111
159
|
A host that knows its face before it mounts starts that chunk at once,
|
|
112
160
|
beside its own requests, and an embed mounted once it is here draws it in
|
|
113
161
|
the first commit:
|
|
@@ -122,6 +170,40 @@ await faceReady;
|
|
|
122
170
|
const handle = mount(root, { app, face }); // drawn in this commit
|
|
123
171
|
```
|
|
124
172
|
|
|
173
|
+
A face opens doors of its own as it first draws — on the pages the home's
|
|
174
|
+
lenses, a list's arranging, the bar's Activity and a form's date box; on
|
|
175
|
+
the scene the relations' ribbons, the city's ground, the districts' states
|
|
176
|
+
and the way back after an act — each a chunk asked for only once the face
|
|
177
|
+
has run, a round trip after the face's own on a phone (FR-194). They stay
|
|
178
|
+
doors, so a page that never draws a lens never runs one, and
|
|
179
|
+
`@graview/embed/first-draw` names them for a host's build:
|
|
180
|
+
`firstDrawChunks(metafile, face)` reads esbuild's metafile and returns the
|
|
181
|
+
chunks a face's first draw asks for — each door's chunk and every chunk it
|
|
182
|
+
imports outright — to name in the page's head beside the face's own;
|
|
183
|
+
`FIRST_DRAW_DOORS` is the list it reads, each door by its package and
|
|
184
|
+
module. It is a build script's, never the page's: importing it costs a page
|
|
185
|
+
nothing.
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import { firstDrawChunks } from "@graview/embed/first-draw";
|
|
189
|
+
|
|
190
|
+
const built = await esbuild.build({ ...shell, splitting: true, metafile: true });
|
|
191
|
+
const doors = firstDrawChunks(built.metafile, "pages").map((chunk) => `/${chunk.split("/").pop()}`);
|
|
192
|
+
// Less what the head already names for the face itself.
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Ask for them once the face's own chunks have arrived, not beside them: on
|
|
196
|
+
a phone's network a door named beside the face takes its bandwidth, and
|
|
197
|
+
the face draws later. `graview preview`'s page writes them from a script in
|
|
198
|
+
its head that waits for each `modulepreload` link's `load`; so asked, the
|
|
199
|
+
face drew when it did and the place settled about half a second sooner on
|
|
200
|
+
a slow 4G (`pnpm verify first-load`).
|
|
201
|
+
|
|
202
|
+
What is fetched before it is wanted — the acts' pane when the page is
|
|
203
|
+
idle, a date's editor, the other face at a desk — waits until the place
|
|
204
|
+
has first drawn and settled (`data-graview-drawn`), so on a phone the
|
|
205
|
+
network is the first draw's until then.
|
|
206
|
+
|
|
125
207
|
What this asks of the framework, and what it adds: the theme scopes to the
|
|
126
208
|
element (`themeBaseCss(scheme, brand, { scope })`, and the blocks a view is
|
|
127
209
|
drawn with, `viewsCss`, and the scene's own rules, `sceneCss`, drawn by the
|
|
@@ -219,6 +301,51 @@ handle.unmount();
|
|
|
219
301
|
handle = mount(root, { app, store, at });
|
|
220
302
|
```
|
|
221
303
|
|
|
304
|
+
## A view proposed and not kept
|
|
305
|
+
|
|
306
|
+
A chat that proposes a worker view can try it headless and be told what it
|
|
307
|
+
drew in words; to see it at a phone's width in dark it had to keep it
|
|
308
|
+
first. `draftView` draws one for the seat at the keyboard without keeping
|
|
309
|
+
it: its manifest and its `source` (or `worker`, and anything else a
|
|
310
|
+
`WorkerViewDefinition` takes but `draft`):
|
|
311
|
+
|
|
312
|
+
```ts
|
|
313
|
+
mount(root, { app, remote, routing: "address", draftView: { manifest, source, author: "Proposed by Claude" } });
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
It is drawn where its manifest attaches — the home, a kind's list at the
|
|
317
|
+
place its title names (`/places/<title>`), each record's page — under one
|
|
318
|
+
line, "Draft — <title> · Not kept", in a group named "Draft: <title>"
|
|
319
|
+
(`[data-graview-draft-view="<name>"]`), as the seat's drawn panel is marked
|
|
320
|
+
on `/~draft`. A kept view of the same name is the one it stands in for: the
|
|
321
|
+
host's `views` may register it as ever, and it is drawn nowhere beside the
|
|
322
|
+
draft. A draft that is stopped says why in its place rather than standing
|
|
323
|
+
the kind's own face there. Nothing of it is kept: it is registered under no
|
|
324
|
+
name, so the place menu offers no Hide or Delete and `keptViews` is asked
|
|
325
|
+
nothing; the store is not written; the next page, handed no draft, has
|
|
326
|
+
none. The worker's host is fetched before the embed draws, and only when a
|
|
327
|
+
draft is handed. With `data-graview-drawn`, a host pictures the proposal
|
|
328
|
+
once it has drawn. `graview preview` and `graview shots` take one as
|
|
329
|
+
`--view <view.js> --manifest <manifest.json>`.
|
|
330
|
+
|
|
331
|
+
A host picturing several proposals in turn swaps them in place rather than
|
|
332
|
+
mounting again: `handle.setDraftView(draft)` draws another, and
|
|
333
|
+
`handle.setDraftView(null)` the app's own views again. The store, the place
|
|
334
|
+
and the seat stay; `data-graview-drawn` comes off in the call and comes
|
|
335
|
+
back, with `onDrawn` told again, once the new draft has drawn and settled:
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
for (const proposal of proposals) {
|
|
339
|
+
handle.setDraftView(proposal);
|
|
340
|
+
await page.waitForSelector("[data-graview-drawn]");
|
|
341
|
+
// picture it
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Under a base path — the page the app, served at `/a/<app>` — a draft of a
|
|
346
|
+
kind's view is drawn at `/a/<app>/places/<title>`, and the attribute's
|
|
347
|
+
value is the place's path within the app (`/places/<title>`).
|
|
348
|
+
|
|
222
349
|
## What stands over what
|
|
223
350
|
|
|
224
351
|
Every popover, menu and list of suggestions the embed draws — the profile,
|
|
@@ -376,6 +503,12 @@ that and does not bundle the scene, the Graview or the studio:
|
|
|
376
503
|
import { mount } from "@graview/embed/pages";
|
|
377
504
|
```
|
|
378
505
|
|
|
506
|
+
It says when a page has drawn as the whole embed does — `onDrawn(place)`,
|
|
507
|
+
and `data-graview-drawn` (`DRAWN_ATTRIBUTE`) on its root — and takes a
|
|
508
|
+
`draftView`, swapped in place with `handle.setDraftView`, drawn and marked
|
|
509
|
+
as the whole embed draws one, the worker's host fetched only when a draft
|
|
510
|
+
is handed.
|
|
511
|
+
|
|
379
512
|
Bundled for the browser without React, the pages face alone is about 500 KB
|
|
380
513
|
minified (165 KB gzipped); the whole embed loads about 750 KB (190 KB) before a
|
|
381
514
|
face is fetched, and every face about 1.28 MB (370 KB);
|
package/dist/draft.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { WorkerViewDefinition } from "@graview/guest/host/views";
|
|
2
|
+
import type { DraftOver } from "./frame.js";
|
|
3
|
+
/** A view proposed and not kept (FR-187): a worker view's definition, its code as `source` — a plain script against the `graview` global — or `worker`. */
|
|
4
|
+
export type EmbedDraftView = Omit<WorkerViewDefinition, "worker" | "draft"> & ({
|
|
5
|
+
readonly source: string;
|
|
6
|
+
readonly worker?: undefined;
|
|
7
|
+
} | {
|
|
8
|
+
readonly worker: WorkerViewDefinition["worker"];
|
|
9
|
+
readonly source?: undefined;
|
|
10
|
+
});
|
|
11
|
+
export declare const fetchDraftHost: () => Promise<void>;
|
|
12
|
+
/** Whether a draft handed now must wait for the worker's host before the embed first draws. */
|
|
13
|
+
export declare const draftWaits: (draft: EmbedDraftView | null | undefined) => boolean;
|
|
14
|
+
/** Stands in for the embed while what it draws with arrives — the worker's host for a draft, the rules for a place handed back — then draws it. */
|
|
15
|
+
export declare function Settling({ onReady, fetch }: {
|
|
16
|
+
readonly onReady: () => void;
|
|
17
|
+
readonly fetch: () => Promise<void>;
|
|
18
|
+
}): null;
|
|
19
|
+
/**
|
|
20
|
+
* How the frame registers the draft over the app's views, kept while the
|
|
21
|
+
* same draft is handed, and which draft it is. A draft handed after the
|
|
22
|
+
* embed first drew, before the worker's host is here, is registered once
|
|
23
|
+
* the host arrives; the embed is not drawn again from nothing for it.
|
|
24
|
+
*/
|
|
25
|
+
export declare function useDraft(draft: EmbedDraftView | null | undefined): {
|
|
26
|
+
readonly over: DraftOver | undefined;
|
|
27
|
+
readonly n: number;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=draft.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../src/draft.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ5C,2JAA2J;AAC3J,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAW5N,eAAO,MAAM,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAsB,CAAC;AAEtE,+FAA+F;AAC/F,eAAO,MAAM,UAAU,GAAI,OAAO,cAAc,GAAG,IAAI,GAAG,SAAS,KAAG,OAAoD,CAAC;AAE3H,mJAAmJ;AACnJ,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,QAGjH;AAKD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAqB/H"}
|
package/dist/draft.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { retryingImport } from "@graview/core/retry";
|
|
2
|
+
import { partArriving } from "@graview/react/provider";
|
|
3
|
+
import { useEffect, useLayoutEffect, useMemo, useState } from "react";
|
|
4
|
+
/*
|
|
5
|
+
* THE WORKER'S HOST FOR A DRAFT, fetched only when one is handed: a page
|
|
6
|
+
* that is handed none never loads it for this. Counted while it is on its
|
|
7
|
+
* way (`partArriving`), so a place a draft is handed to after it first drew
|
|
8
|
+
* is not said drawn before the draft is in it (FR-188).
|
|
9
|
+
*/
|
|
10
|
+
let draftHost;
|
|
11
|
+
const draftChunk = retryingImport(() => import("@graview/guest/host/views"));
|
|
12
|
+
const load = () => draftChunk().then((module) => void (draftHost = module), () => new Promise((resolve) => setTimeout(resolve, 2_000)).then(load));
|
|
13
|
+
export const fetchDraftHost = partArriving(load);
|
|
14
|
+
/** Whether a draft handed now must wait for the worker's host before the embed first draws. */
|
|
15
|
+
export const draftWaits = (draft) => Boolean(draft) && draftHost === undefined;
|
|
16
|
+
/** Stands in for the embed while what it draws with arrives — the worker's host for a draft, the rules for a place handed back — then draws it. */
|
|
17
|
+
export function Settling({ onReady, fetch }) {
|
|
18
|
+
useLayoutEffect(() => void fetch().then(onReady), [onReady, fetch]);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
/** Each draft handed, counted: what the drawn signal is watched again for when a draft is swapped (`setDraftView`). */
|
|
22
|
+
let handed = 0;
|
|
23
|
+
/**
|
|
24
|
+
* How the frame registers the draft over the app's views, kept while the
|
|
25
|
+
* same draft is handed, and which draft it is. A draft handed after the
|
|
26
|
+
* embed first drew, before the worker's host is here, is registered once
|
|
27
|
+
* the host arrives; the embed is not drawn again from nothing for it.
|
|
28
|
+
*/
|
|
29
|
+
export function useDraft(draft) {
|
|
30
|
+
const [host, setHost] = useState(() => draftHost);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (!draft || host)
|
|
33
|
+
return;
|
|
34
|
+
let gone = false;
|
|
35
|
+
void fetchDraftHost().then(() => {
|
|
36
|
+
if (!gone)
|
|
37
|
+
setHost(draftHost);
|
|
38
|
+
});
|
|
39
|
+
return () => {
|
|
40
|
+
gone = true;
|
|
41
|
+
};
|
|
42
|
+
}, [draft, host]);
|
|
43
|
+
const n = useMemo(() => (handed += 1), [draft]);
|
|
44
|
+
const over = useMemo(() => {
|
|
45
|
+
const views = host ?? draftHost;
|
|
46
|
+
if (!draft || !views)
|
|
47
|
+
return undefined;
|
|
48
|
+
const { source, worker, ...rest } = draft;
|
|
49
|
+
const definition = { ...rest, worker: worker ?? { source: source }, draft: true };
|
|
50
|
+
return { name: draft.manifest.name, home: draft.manifest.attach === "home", register: (registry) => views.registerWorkerView(registry, definition) };
|
|
51
|
+
}, [draft, host]);
|
|
52
|
+
return { over, n };
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=draft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft.js","sourceRoot":"","sources":["../src/draft.ts"],"names":[],"mappings":"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"}
|
package/dist/drawn.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { EmbedWhere } from "./where.js";
|
|
2
|
+
/** The attribute the embed's root wears while the place it is on has drawn and settled. */
|
|
3
|
+
export declare const DRAWN_ATTRIBUTE = "data-graview-drawn";
|
|
4
|
+
/**
|
|
5
|
+
* Watch a place settle: takes `data-graview-drawn` off the root at once,
|
|
6
|
+
* and puts it back — `path` its value — once the place has drawn and
|
|
7
|
+
* nothing has moved for a moment, then calls `settled`. The answer stops
|
|
8
|
+
* watching; a place left before it settled is never said drawn.
|
|
9
|
+
*/
|
|
10
|
+
export declare function watchDrawn(root: HTMLElement, path: string, settled: () => void): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* SAYS WHEN THE PLACE HAS DRAWN AND SETTLED, on the root and to the host:
|
|
13
|
+
* watched again from nothing each time `key` moves — another page, another
|
|
14
|
+
* stop on the scene, another face, another draft — so the attribute comes
|
|
15
|
+
* off in the commit that moved and goes back on once the new place
|
|
16
|
+
* settles. The whole embed and the pages alone say it alike.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useDrawnSignal(rootRef: {
|
|
19
|
+
readonly current: HTMLElement | null;
|
|
20
|
+
}, key: string, place: EmbedWhere, onDrawn: ((place: EmbedWhere) => void) | undefined): void;
|
|
21
|
+
//# sourceMappingURL=drawn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawn.d.ts","sourceRoot":"","sources":["../src/drawn.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAgB7C,2FAA2F;AAC3F,eAAO,MAAM,eAAe,uBAAuB,CAAC;AAyCpD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAoD3F;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,IAAI,CAmB1K"}
|
package/dist/drawn.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { partsArriving, placeDrawn, placeWatched } from "@graview/react/provider";
|
|
2
|
+
import { useLayoutEffect, useRef } from "react";
|
|
3
|
+
/*
|
|
4
|
+
* THE PAGE SAYS WHEN A PLACE HAS DRAWN AND SETTLED (FR-188).
|
|
5
|
+
*
|
|
6
|
+
* A host picturing a place — Graview Cloud's describe_place, headless —
|
|
7
|
+
* waited on a guess: the opening frame gone, the network quiet, then 600
|
|
8
|
+
* ms. The embed knows better. Once the place it is on has drawn — the face
|
|
9
|
+
* here, every part drawn on it arrived (or said it did not), the fonts and
|
|
10
|
+
* images loaded, every worker view drawn (or failed, its plain face drawn
|
|
11
|
+
* in its place), every frame guest drawn (or silent past its time) — and nothing in it has moved for a moment, its root says
|
|
12
|
+
* `data-graview-drawn`, its value the place's path, and the host is told
|
|
13
|
+
* `onDrawn(place)`. A move to another place takes it off in the same
|
|
14
|
+
* commit, and the new place says it again once it settles.
|
|
15
|
+
*/
|
|
16
|
+
/** The attribute the embed's root wears while the place it is on has drawn and settled. */
|
|
17
|
+
export const DRAWN_ATTRIBUTE = "data-graview-drawn";
|
|
18
|
+
/** How long nothing may move before a place is said to have settled. */
|
|
19
|
+
const QUIET_MS = 200;
|
|
20
|
+
/** How often a place still settling is looked at. */
|
|
21
|
+
const EVERY_MS = 50;
|
|
22
|
+
/** A place that never stops moving — a clock, a view that draws forever — is said drawn after this long all the same. */
|
|
23
|
+
const MOST_MS = 10_000;
|
|
24
|
+
const now = () => (typeof performance !== "undefined" ? performance.now() : Date.now());
|
|
25
|
+
/** Every image the place draws, the worker views' own among them (their shadow roots are open). */
|
|
26
|
+
function images(root) {
|
|
27
|
+
const all = [...root.querySelectorAll("img")];
|
|
28
|
+
for (const view of root.querySelectorAll("[data-worker-view]"))
|
|
29
|
+
if (view.shadowRoot)
|
|
30
|
+
all.push(...view.shadowRoot.querySelectorAll("img"));
|
|
31
|
+
return all;
|
|
32
|
+
}
|
|
33
|
+
/** Whether what the place draws is all here: the face, its parts, its fonts, its images and its views. */
|
|
34
|
+
function here(root) {
|
|
35
|
+
const fonts = root.ownerDocument.fonts;
|
|
36
|
+
if (fonts?.status === "loading")
|
|
37
|
+
return false;
|
|
38
|
+
if (partsArriving() > 0)
|
|
39
|
+
return false;
|
|
40
|
+
// The face on its way, or a part of it saying it is busy: a frame guest among them, until it has drawn or its time is up.
|
|
41
|
+
if (root.querySelector('[aria-busy="true"]'))
|
|
42
|
+
return false;
|
|
43
|
+
// An image off screen and lazy is not waited for: it never loads until it is scrolled to.
|
|
44
|
+
if (images(root).some((image) => !image.complete && image.loading !== "lazy"))
|
|
45
|
+
return false;
|
|
46
|
+
// Each worker view drawn, or failed with its plain face: the region inside its place says which.
|
|
47
|
+
for (const place of root.querySelectorAll("[data-worker-view-place]")) {
|
|
48
|
+
if (!place.querySelector("[data-worker-view][data-worker-view-drawn], [data-worker-view][data-worker-view-failed]"))
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
/** What a move would change: the sizes of the root, the face and each worker view, whose own drawing the observer cannot see. */
|
|
54
|
+
function measure(root) {
|
|
55
|
+
const content = root.querySelector("[data-embed-content]");
|
|
56
|
+
const views = [...root.querySelectorAll("[data-worker-view]")].map((view) => `${view.offsetWidth}x${view.offsetHeight}`);
|
|
57
|
+
return `${root.scrollWidth}x${root.scrollHeight}|${content ? `${content.scrollWidth}x${content.scrollHeight}` : ""}|${views.join(",")}`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Watch a place settle: takes `data-graview-drawn` off the root at once,
|
|
61
|
+
* and puts it back — `path` its value — once the place has drawn and
|
|
62
|
+
* nothing has moved for a moment, then calls `settled`. The answer stops
|
|
63
|
+
* watching; a place left before it settled is never said drawn.
|
|
64
|
+
*/
|
|
65
|
+
export function watchDrawn(root, path, settled) {
|
|
66
|
+
root.removeAttribute(DRAWN_ATTRIBUTE);
|
|
67
|
+
const window = root.ownerDocument.defaultView;
|
|
68
|
+
if (!window)
|
|
69
|
+
return () => undefined;
|
|
70
|
+
const started = now();
|
|
71
|
+
let moved = started;
|
|
72
|
+
let last = measure(root);
|
|
73
|
+
let stopped = false;
|
|
74
|
+
let timer;
|
|
75
|
+
const observer = typeof MutationObserver === "undefined" ? undefined : new MutationObserver((records) => {
|
|
76
|
+
if (records.some((record) => !(record.target === root && record.attributeName === DRAWN_ATTRIBUTE)))
|
|
77
|
+
moved = now();
|
|
78
|
+
});
|
|
79
|
+
observer?.observe(root, { childList: true, subtree: true, characterData: true, attributes: true });
|
|
80
|
+
const stop = () => {
|
|
81
|
+
stopped = true;
|
|
82
|
+
observer?.disconnect();
|
|
83
|
+
if (timer !== undefined)
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
};
|
|
86
|
+
// Said after the browser has painted what settled, where it paints at all.
|
|
87
|
+
// A tab out of sight paints nothing, so a frame that never comes is not waited for past a tenth of a second.
|
|
88
|
+
const afterPaint = (then) => {
|
|
89
|
+
let once = false;
|
|
90
|
+
const go = () => {
|
|
91
|
+
if (once)
|
|
92
|
+
return;
|
|
93
|
+
once = true;
|
|
94
|
+
then();
|
|
95
|
+
};
|
|
96
|
+
if (typeof window.requestAnimationFrame === "function")
|
|
97
|
+
window.requestAnimationFrame(() => setTimeout(go, 0));
|
|
98
|
+
setTimeout(go, 100);
|
|
99
|
+
};
|
|
100
|
+
const look = () => {
|
|
101
|
+
if (stopped)
|
|
102
|
+
return;
|
|
103
|
+
const size = measure(root);
|
|
104
|
+
if (size !== last) {
|
|
105
|
+
last = size;
|
|
106
|
+
moved = now();
|
|
107
|
+
}
|
|
108
|
+
const at = now();
|
|
109
|
+
if ((here(root) && at - moved >= QUIET_MS) || at - started >= MOST_MS) {
|
|
110
|
+
afterPaint(() => {
|
|
111
|
+
if (stopped)
|
|
112
|
+
return;
|
|
113
|
+
stop();
|
|
114
|
+
root.setAttribute(DRAWN_ATTRIBUTE, path);
|
|
115
|
+
placeDrawn();
|
|
116
|
+
settled();
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
timer = setTimeout(look, EVERY_MS);
|
|
121
|
+
};
|
|
122
|
+
timer = setTimeout(look, EVERY_MS);
|
|
123
|
+
return stop;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* SAYS WHEN THE PLACE HAS DRAWN AND SETTLED, on the root and to the host:
|
|
127
|
+
* watched again from nothing each time `key` moves — another page, another
|
|
128
|
+
* stop on the scene, another face, another draft — so the attribute comes
|
|
129
|
+
* off in the commit that moved and goes back on once the new place
|
|
130
|
+
* settles. The whole embed and the pages alone say it alike.
|
|
131
|
+
*/
|
|
132
|
+
export function useDrawnSignal(rootRef, key, place, onDrawn) {
|
|
133
|
+
// What is fetched early waits for the first draw (FR-194): said as the embed first renders, before any part's effect runs.
|
|
134
|
+
placeWatched();
|
|
135
|
+
const latest = useRef({ place, onDrawn });
|
|
136
|
+
latest.current = { place, onDrawn };
|
|
137
|
+
useLayoutEffect(() => {
|
|
138
|
+
const watch = (root) => watchDrawn(root, latest.current.place.path, () => latest.current.onDrawn?.(latest.current.place));
|
|
139
|
+
if (rootRef.current)
|
|
140
|
+
return watch(rootRef.current);
|
|
141
|
+
// First drawn below the root, its ref is set after this effect runs: watched once the commit is done (there is nothing to take off yet).
|
|
142
|
+
let stop;
|
|
143
|
+
let gone = false;
|
|
144
|
+
queueMicrotask(() => {
|
|
145
|
+
if (!gone && rootRef.current)
|
|
146
|
+
stop = watch(rootRef.current);
|
|
147
|
+
});
|
|
148
|
+
return () => {
|
|
149
|
+
gone = true;
|
|
150
|
+
stop?.();
|
|
151
|
+
};
|
|
152
|
+
}, [key, rootRef]);
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=drawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawn.js","sourceRoot":"","sources":["../src/drawn.ts"],"names":[],"mappings":"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"}
|
package/dist/embed.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { StudioOffered, StudioOnApply, StudioPlace as StudioPlaceType } fro
|
|
|
3
3
|
import { type Notice, type NoticeHandle } from "@graview/primitives/frame";
|
|
4
4
|
import { type Scheme } from "@graview/react/provider";
|
|
5
5
|
import type { EmbedWhere } from "./where.js";
|
|
6
|
+
import { type EmbedDraftView } from "./draft.js";
|
|
6
7
|
import { AUTO_SCENE_HEIGHT, type EmbedFace, type EmbedHostContext, type EmbedRemote, type FrameOptions } from "./frame.js";
|
|
7
8
|
/**
|
|
8
9
|
* FETCH A FACE BEFORE IT IS DRAWN (FR-57). A host that knows which face it
|
|
@@ -58,12 +59,16 @@ export interface EmbedOptions<S extends AnySchema = AnySchema> extends FrameOpti
|
|
|
58
59
|
*/
|
|
59
60
|
readonly studio?: false | EmbedStudio;
|
|
60
61
|
/**
|
|
61
|
-
* TOLD WHEN A
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
62
|
+
* TOLD WHEN A PLACE HAS DRAWN AND SETTLED (FR-188): once the place the
|
|
63
|
+
* reader is on — its face here, every part drawn on it arrived, the fonts
|
|
64
|
+
* and images loaded, each worker view drawn (or failed, its plain face
|
|
65
|
+
* drawn instead) — has not moved for a moment. It is handed the place as
|
|
66
|
+
* `where()` says it. The embed's root wears `data-graview-drawn` (the
|
|
67
|
+
* place's path) from then until the reader moves: a move takes it off in
|
|
68
|
+
* the same commit, and the next place puts it back as it settles. A host
|
|
69
|
+
* picturing a place waits for the attribute rather than a guess.
|
|
65
70
|
*/
|
|
66
|
-
readonly onDrawn?: (
|
|
71
|
+
readonly onDrawn?: (place: EmbedWhere) => void;
|
|
67
72
|
/**
|
|
68
73
|
* THE QUICK ASK on both faces (Roadmap f-quick-ask-framework): ⌘K's
|
|
69
74
|
* command bar beside what is selected, and the answer cards it leaves.
|
|
@@ -79,7 +84,20 @@ export interface EmbedOptions<S extends AnySchema = AnySchema> extends FrameOpti
|
|
|
79
84
|
* host that must remount on a new declaration hands the old place back here.
|
|
80
85
|
*/
|
|
81
86
|
readonly at?: EmbedWhere;
|
|
87
|
+
/**
|
|
88
|
+
* A VIEW PROPOSED AND NOT KEPT (FR-187): a worker view's manifest and its
|
|
89
|
+
* `source` (or `worker`), drawn for the seat at the keyboard where its
|
|
90
|
+
* manifest attaches — the home, a kind's list, a record — over the app's
|
|
91
|
+
* own views, and marked "Draft — <title> · Not kept". A kept view of the
|
|
92
|
+
* same name is the one it stands in for. Nothing of it is kept: it is in
|
|
93
|
+
* no store and no `keptViews`, the place menu offers it nothing, and it
|
|
94
|
+
* is gone when the page closes. The worker's host is fetched before the
|
|
95
|
+
* embed draws, only when a draft is handed. `handle.setDraftView` swaps
|
|
96
|
+
* it for another, or none, without a remount.
|
|
97
|
+
*/
|
|
98
|
+
readonly draftView?: EmbedDraftView | null;
|
|
82
99
|
}
|
|
100
|
+
export type { EmbedDraftView } from "./draft.js";
|
|
83
101
|
/** The studio an embed offers, for a host that keeps the declaration itself. */
|
|
84
102
|
export interface EmbedStudio {
|
|
85
103
|
/**
|
|
@@ -121,6 +139,14 @@ export interface EmbedProps<S extends AnySchema = AnySchema> extends EmbedOption
|
|
|
121
139
|
readonly onOpening?: (face: EmbedFace) => void;
|
|
122
140
|
/** Called when a seat is taken in the person's menu; the host decides who sits. */
|
|
123
141
|
readonly onSeat?: (principal: Principal) => void;
|
|
142
|
+
/**
|
|
143
|
+
* TOLD WHEN A FACE IS ON THE PAGE (FR-57). Each face is fetched as it is
|
|
144
|
+
* first drawn, so the frame stands before the face does; this is called
|
|
145
|
+
* with the face asked for once it has drawn (below `pagesBelow`, drawn
|
|
146
|
+
* as the pages that stand in for it), each time the face changes. What
|
|
147
|
+
* `handle.drawn()` waits for; `onDrawn` waits for the place to settle.
|
|
148
|
+
*/
|
|
149
|
+
readonly onFaceDrawn?: (face: EmbedFace) => void;
|
|
124
150
|
}
|
|
125
151
|
/** The face a stop implies: a stop at altitude opens the Graview, anything else the scene (FR-132). */
|
|
126
152
|
export declare function faceOf(stop: string | undefined): EmbedFace;
|
|
@@ -182,6 +208,14 @@ export interface EmbedHandle {
|
|
|
182
208
|
setHostContext(context: EmbedHostContext): void;
|
|
183
209
|
/** Re-dress the embed: another brand, or the same brand with a different kit. */
|
|
184
210
|
setBrand(brand: Brand | undefined): void;
|
|
211
|
+
/**
|
|
212
|
+
* ANOTHER VIEW PROPOSED AND NOT KEPT, OR NONE (FR-187): the draft drawn
|
|
213
|
+
* where it attaches swapped in place, without a remount — the store, the
|
|
214
|
+
* place and the seat stay. `data-graview-drawn` comes off in the call and
|
|
215
|
+
* returns once the new draft has drawn and settled; `null` draws the
|
|
216
|
+
* app's own views again.
|
|
217
|
+
*/
|
|
218
|
+
setDraftView(draft: EmbedDraftView | null): void;
|
|
185
219
|
/**
|
|
186
220
|
* Resolves once the face now asked for is drawn (FR-57). The frame is on
|
|
187
221
|
* the page when `mount` returns; each face is fetched as it is first
|
package/dist/embed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../src/embed.tsx"],"names":[],"mappings":"AACA,OAAO,EAAgE,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,KAAK,MAAM,EAAc,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,eAAe,CAAC;AAG/L,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACpG,OAAO,EAAiC,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC1G,OAAO,
|
|
1
|
+
{"version":3,"file":"embed.d.ts","sourceRoot":"","sources":["../src/embed.tsx"],"names":[],"mappings":"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"}
|