@graview/react 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 +96 -0
- package/README.md +20 -0
- package/dist/activity.d.ts +113 -0
- package/dist/activity.d.ts.map +1 -0
- package/dist/activity.js +207 -0
- package/dist/activity.js.map +1 -0
- package/dist/animation.d.ts +64 -0
- package/dist/animation.d.ts.map +1 -0
- package/dist/animation.js +245 -0
- package/dist/animation.js.map +1 -0
- package/dist/captions.d.ts +43 -0
- package/dist/captions.d.ts.map +1 -0
- package/dist/captions.js +61 -0
- package/dist/captions.js.map +1 -0
- package/dist/channels.d.ts +15 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +114 -0
- package/dist/channels.js.map +1 -0
- package/dist/connectors.d.ts +176 -0
- package/dist/connectors.d.ts.map +1 -0
- package/dist/connectors.js +837 -0
- package/dist/connectors.js.map +1 -0
- package/dist/context.d.ts +348 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +568 -0
- package/dist/context.js.map +1 -0
- package/dist/drawn.d.ts +60 -0
- package/dist/drawn.d.ts.map +1 -0
- package/dist/drawn.js +58 -0
- package/dist/drawn.js.map +1 -0
- package/dist/edge-signs.d.ts +13 -0
- package/dist/edge-signs.d.ts.map +1 -0
- package/dist/edge-signs.js +76 -0
- package/dist/edge-signs.js.map +1 -0
- package/dist/hooks.d.ts +160 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +457 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/keyboard.d.ts +5 -0
- package/dist/keyboard.d.ts.map +1 -0
- package/dist/keyboard.js +178 -0
- package/dist/keyboard.js.map +1 -0
- package/dist/kit.d.ts +10 -0
- package/dist/kit.d.ts.map +1 -0
- package/dist/kit.js +32 -0
- package/dist/kit.js.map +1 -0
- package/dist/local-intelligence.d.ts +31 -0
- package/dist/local-intelligence.d.ts.map +1 -0
- package/dist/local-intelligence.js +66 -0
- package/dist/local-intelligence.js.map +1 -0
- package/dist/motion.d.ts +17 -0
- package/dist/motion.d.ts.map +1 -0
- package/dist/motion.js +26 -0
- package/dist/motion.js.map +1 -0
- package/dist/occupants.d.ts +45 -0
- package/dist/occupants.d.ts.map +1 -0
- package/dist/occupants.js +57 -0
- package/dist/occupants.js.map +1 -0
- package/dist/parallel.d.ts +19 -0
- package/dist/parallel.d.ts.map +1 -0
- package/dist/parallel.js +30 -0
- package/dist/parallel.js.map +1 -0
- package/dist/picking.d.ts +30 -0
- package/dist/picking.d.ts.map +1 -0
- package/dist/picking.js +140 -0
- package/dist/picking.js.map +1 -0
- package/dist/plots.d.ts +106 -0
- package/dist/plots.d.ts.map +1 -0
- package/dist/plots.js +306 -0
- package/dist/plots.js.map +1 -0
- package/dist/pointer.d.ts +27 -0
- package/dist/pointer.d.ts.map +1 -0
- package/dist/pointer.js +39 -0
- package/dist/pointer.js.map +1 -0
- package/dist/presence.d.ts +110 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +280 -0
- package/dist/presence.js.map +1 -0
- package/dist/rails.d.ts +11 -0
- package/dist/rails.d.ts.map +1 -0
- package/dist/rails.js +15 -0
- package/dist/rails.js.map +1 -0
- package/dist/resolved-view.d.ts +78 -0
- package/dist/resolved-view.d.ts.map +1 -0
- package/dist/resolved-view.js +365 -0
- package/dist/resolved-view.js.map +1 -0
- package/dist/robot.d.ts +114 -0
- package/dist/robot.d.ts.map +1 -0
- package/dist/robot.js +93 -0
- package/dist/robot.js.map +1 -0
- package/dist/routes.d.ts +50 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +150 -0
- package/dist/routes.js.map +1 -0
- package/dist/scene-camera.d.ts +25 -0
- package/dist/scene-camera.d.ts.map +1 -0
- package/dist/scene-camera.js +130 -0
- package/dist/scene-camera.js.map +1 -0
- package/dist/scene-hand.d.ts +110 -0
- package/dist/scene-hand.d.ts.map +1 -0
- package/dist/scene-hand.js +317 -0
- package/dist/scene-hand.js.map +1 -0
- package/dist/scene-helpers.d.ts +46 -0
- package/dist/scene-helpers.d.ts.map +1 -0
- package/dist/scene-helpers.js +108 -0
- package/dist/scene-helpers.js.map +1 -0
- package/dist/scene-lines.d.ts +76 -0
- package/dist/scene-lines.d.ts.map +1 -0
- package/dist/scene-lines.js +578 -0
- package/dist/scene-lines.js.map +1 -0
- package/dist/scene-root.d.ts +71 -0
- package/dist/scene-root.d.ts.map +1 -0
- package/dist/scene-root.js +790 -0
- package/dist/scene-root.js.map +1 -0
- package/dist/scene.d.ts +17 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +17 -0
- package/dist/scene.js.map +1 -0
- package/dist/seat-marks.d.ts +35 -0
- package/dist/seat-marks.d.ts.map +1 -0
- package/dist/seat-marks.js +43 -0
- package/dist/seat-marks.js.map +1 -0
- package/dist/settings.d.ts +30 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +73 -0
- package/dist/settings.js.map +1 -0
- package/dist/view-boundary.d.ts +33 -0
- package/dist/view-boundary.d.ts.map +1 -0
- package/dist/view-boundary.js +53 -0
- package/dist/view-boundary.js.map +1 -0
- package/dist/view-host.d.ts +57 -0
- package/dist/view-host.d.ts.map +1 -0
- package/dist/view-host.js +474 -0
- package/dist/view-host.js.map +1 -0
- package/dist/view-registry.d.ts +122 -0
- package/dist/view-registry.d.ts.map +1 -0
- package/dist/view-registry.js +20 -0
- package/dist/view-registry.js.map +1 -0
- package/dist/where-drawn.d.ts +151 -0
- package/dist/where-drawn.d.ts.map +1 -0
- package/dist/where-drawn.js +231 -0
- package/dist/where-drawn.js.map +1 -0
- package/package.json +60 -0
package/dist/context.js
ADDED
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { search, touchWeights } from "@graview/core";
|
|
3
|
+
import { loadIntelligenceConfig, saveIntelligenceConfig } from "@graview/tools";
|
|
4
|
+
import { honourSetting, loadSetting, rememberSetting } from "./settings.js";
|
|
5
|
+
import { PRESENCE_SETTINGS, tabSession, usePresenceState } from "./presence.js";
|
|
6
|
+
import { useActivityState } from "./activity.js";
|
|
7
|
+
import { EMPTY_VIEW, edgeOfSelection, isBandAggregate, kindOfCard, kindsOfAggregate, withFocus, withSelection } from "@graview/layout";
|
|
8
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore, } from "react";
|
|
9
|
+
import { createPointerStore } from "./pointer.js";
|
|
10
|
+
import { createMotionStore } from "./motion.js";
|
|
11
|
+
import { foldRobots } from "./robot.js";
|
|
12
|
+
const GraviewContext = createContext(null);
|
|
13
|
+
/**
|
|
14
|
+
* Which mode the view being rendered right now is in.
|
|
15
|
+
*
|
|
16
|
+
* `mode` already arrives as a prop, and every view author was expected to
|
|
17
|
+
* thread it into whatever primitive needed it — which is the kind of contract
|
|
18
|
+
* that holds for the framework's own views and quietly does not for anyone
|
|
19
|
+
* else's. Three apps in, the app-written views were still drawing card
|
|
20
|
+
* furniture on a full page because nobody remembers a prop they only need on
|
|
21
|
+
* one screen.
|
|
22
|
+
*
|
|
23
|
+
* So the primitives read it themselves. A view can still say `variant`
|
|
24
|
+
* explicitly and win; the context is only what happens when it says nothing.
|
|
25
|
+
*/
|
|
26
|
+
const ViewModeContext = createContext("scene");
|
|
27
|
+
export function ViewModeProvider({ mode, children, }) {
|
|
28
|
+
return _jsx(ViewModeContext.Provider, { value: mode, children: children });
|
|
29
|
+
}
|
|
30
|
+
/** How the surrounding view is being drawn. `scene` outside any view. */
|
|
31
|
+
export function useViewMode() {
|
|
32
|
+
return useContext(ViewModeContext);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Nobody in particular. A store with no policy permits this principal
|
|
36
|
+
* everything, which is what makes permission opt-in rather than a tax every
|
|
37
|
+
* app pays before it has decided it has users.
|
|
38
|
+
*/
|
|
39
|
+
const ANONYMOUS = { kind: "human" };
|
|
40
|
+
const NO_SEATS = [];
|
|
41
|
+
const NO_SETTINGS = [];
|
|
42
|
+
/** One shared empty, so "nothing selected" is referentially stable. */
|
|
43
|
+
const EMPTY_SELECTION = [];
|
|
44
|
+
/**
|
|
45
|
+
* One provider holds the store, the view registry, the current view and the
|
|
46
|
+
* selection.
|
|
47
|
+
*
|
|
48
|
+
* Selection lives HERE rather than inside the scene so that the scene and the
|
|
49
|
+
* affordance surface are looking at the same thing — an action offered for a
|
|
50
|
+
* selection the scene no longer has is the bug this prevents.
|
|
51
|
+
*/
|
|
52
|
+
export function GraviewProvider({ store, views, initialView, scheme = "dark", initialSelection, principal, seats = NO_SEATS, onSeat, settings: appSettings = NO_SETTINGS, presence, brand, providers, view, onViewChange, children, }) {
|
|
53
|
+
/* This tab, for the life of the tab: see `tabSession`. */
|
|
54
|
+
const [session] = useState(() => tabSession());
|
|
55
|
+
const [intelligence, setIntelligence] = useState(() => loadIntelligenceConfig());
|
|
56
|
+
const chooseIntelligence = useCallback((next) => {
|
|
57
|
+
saveIntelligenceConfig(next);
|
|
58
|
+
setIntelligence(next);
|
|
59
|
+
}, []);
|
|
60
|
+
const [movedByHand, setMovedByHand] = useState(false);
|
|
61
|
+
const [hostAnswers, setHostAnswers] = useState(false);
|
|
62
|
+
const registerHostAnswers = useCallback((answers) => setHostAnswers(answers), []);
|
|
63
|
+
const noteMoved = useCallback(() => setMovedByHand(true), []);
|
|
64
|
+
/* Privacy is a reader setting, and it appears only where there is somebody to be seen by. */
|
|
65
|
+
const settings = useMemo(() => (presence ? [...appSettings, ...PRESENCE_SETTINGS] : appSettings), [appSettings, presence]);
|
|
66
|
+
const [internalView, setInternalView] = useState(() => withSelection(initialView ?? EMPTY_VIEW, initialSelection ?? initialView?.selection ?? []));
|
|
67
|
+
const homeView = useRef(initialView ?? EMPTY_VIEW).current;
|
|
68
|
+
const [menuAt, setMenuAt] = useState(null);
|
|
69
|
+
const [actsDoor, registerActsDoor] = useState(null);
|
|
70
|
+
/*
|
|
71
|
+
* The scene's handle, held in a ref: where things are changes every frame
|
|
72
|
+
* of a tween, and a context value that changed with it would re-render
|
|
73
|
+
* every consumer sixty times a second for a question most never ask.
|
|
74
|
+
*/
|
|
75
|
+
const sceneHandle = useRef(null);
|
|
76
|
+
const registerScene = useCallback((handle) => {
|
|
77
|
+
sceneHandle.current = handle;
|
|
78
|
+
}, []);
|
|
79
|
+
const whereIs = useCallback((id) => sceneHandle.current?.whereIs(id) ?? null, []);
|
|
80
|
+
const [pointer] = useState(() => createPointerStore());
|
|
81
|
+
const [motion] = useState(() => createMotionStore());
|
|
82
|
+
const [seatWho, setSeatWho] = useState(null);
|
|
83
|
+
/*
|
|
84
|
+
* THE ROBOTS' STATE, folded here beside the activity marks, from the same
|
|
85
|
+
* two sources — ops as they land, reads as the runtime reports them —
|
|
86
|
+
* and from what a seat says of itself. One timer rests them after the
|
|
87
|
+
* hold; a quiet city holds no timer.
|
|
88
|
+
*/
|
|
89
|
+
const [robots, setRobots] = useState(() => new Map());
|
|
90
|
+
const robotsLive = useRef(robots);
|
|
91
|
+
robotsLive.current = robots;
|
|
92
|
+
const restTimer = useRef(null);
|
|
93
|
+
const kindOf = useCallback((id) => store.graph.getNode(id)?.kind, [store]);
|
|
94
|
+
const foldSeat = useCallback((event) => {
|
|
95
|
+
const next = foldRobots(robotsLive.current, event, kindOf);
|
|
96
|
+
robotsLive.current = next;
|
|
97
|
+
setRobots(next);
|
|
98
|
+
if (restTimer.current)
|
|
99
|
+
clearTimeout(restTimer.current);
|
|
100
|
+
const busy = [...next.values()].some((robot) => robot.mode !== "docked" && robot.mode !== "asking");
|
|
101
|
+
if (busy) {
|
|
102
|
+
restTimer.current = setTimeout(() => {
|
|
103
|
+
const rested = foldRobots(robotsLive.current, { type: "rest", at: Date.now(), holdMs: ROBOT_REST_MS }, kindOf);
|
|
104
|
+
robotsLive.current = rested;
|
|
105
|
+
setRobots(rested);
|
|
106
|
+
}, ROBOT_REST_MS + 20);
|
|
107
|
+
}
|
|
108
|
+
}, [kindOf]);
|
|
109
|
+
const noteSeat = useCallback((event) => foldSeat({ ...event, at: event.at ?? Date.now() }), [foldSeat]);
|
|
110
|
+
/*
|
|
111
|
+
* A SEAT THAT SITS DOWN HAS A BODY AT ONCE, docked: the robot is in the
|
|
112
|
+
* city from the first frame, not from the first turn.
|
|
113
|
+
*/
|
|
114
|
+
const registerSeatWho = useCallback((who) => {
|
|
115
|
+
setSeatWho(who);
|
|
116
|
+
if (who)
|
|
117
|
+
foldSeat({ type: "home", author: { kind: "agent", id: who, session }, at: Date.now() });
|
|
118
|
+
}, [foldSeat, session]);
|
|
119
|
+
useEffect(() => store.subscribe((_diff, ops) => {
|
|
120
|
+
for (const op of ops) {
|
|
121
|
+
if (op.author.kind !== "agent")
|
|
122
|
+
continue;
|
|
123
|
+
foldSeat({ type: "write", author: op.author, ids: op.writes, at: Date.now() });
|
|
124
|
+
}
|
|
125
|
+
}), [store, foldSeat]);
|
|
126
|
+
useEffect(() => () => {
|
|
127
|
+
if (restTimer.current)
|
|
128
|
+
clearTimeout(restTimer.current);
|
|
129
|
+
}, []);
|
|
130
|
+
/*
|
|
131
|
+
* WHO IS AT THE KEYBOARD, and the reader's own answer to it.
|
|
132
|
+
*
|
|
133
|
+
* `principal` is the app's: a host that knows who signed in passes one and
|
|
134
|
+
* the seats never move it. Where the app instead offers seats — the demos,
|
|
135
|
+
* an embed on a page, anywhere the point is to FEEL the policy — sitting
|
|
136
|
+
* down is a state change here, so every surface (the strip's narrowing,
|
|
137
|
+
* the withheld sentence, "Show the installation", the pages, the agent's
|
|
138
|
+
* tools) re-derives from one principal rather than each reading its own.
|
|
139
|
+
*/
|
|
140
|
+
const [seated, setSeated] = useState(null);
|
|
141
|
+
const seatNow = seated ?? principal ?? seats[0]?.principal ?? ANONYMOUS;
|
|
142
|
+
// With this tab's session on it, so every op this seat authors names the tab that made it.
|
|
143
|
+
const who = useMemo(() => ({ ...seatNow, session }), [seatNow, session]);
|
|
144
|
+
const takeSeat = useCallback((next) => {
|
|
145
|
+
setSeated(next);
|
|
146
|
+
onSeat?.(next);
|
|
147
|
+
}, [onSeat]);
|
|
148
|
+
/*
|
|
149
|
+
* WHAT THE READER SET FOR THEMSELVES, read once and applied to the root.
|
|
150
|
+
*
|
|
151
|
+
* Read lazily so a browser that cannot remember still opens on the
|
|
152
|
+
* declaration's own values, and applied in an effect rather than during
|
|
153
|
+
* render — writing to `document.documentElement` while React is
|
|
154
|
+
* rendering is a side effect in the wrong place, and would also run on a
|
|
155
|
+
* server where there is no document at all.
|
|
156
|
+
*/
|
|
157
|
+
const [settingValues, setSettingValues] = useState(() => Object.fromEntries(settings.map((setting) => [setting.name, loadSetting(setting)])));
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
for (const setting of settings) {
|
|
160
|
+
honourSetting(setting, settingValues[setting.name] ?? setting.initial);
|
|
161
|
+
}
|
|
162
|
+
}, [settings, settingValues]);
|
|
163
|
+
const chooseSetting = useCallback((name, value) => {
|
|
164
|
+
const setting = settings.find((candidate) => candidate.name === name);
|
|
165
|
+
if (!setting || !setting.options.some((option) => option.value === value))
|
|
166
|
+
return;
|
|
167
|
+
rememberSetting(setting, value);
|
|
168
|
+
setSettingValues((current) => ({ ...current, [name]: value }));
|
|
169
|
+
}, [settings]);
|
|
170
|
+
const [emphasis, setEmphasis] = useState(null);
|
|
171
|
+
const { activity, noteAttention: markAttention } = useActivityState(store);
|
|
172
|
+
const noteAttention = useCallback((note) => {
|
|
173
|
+
markAttention(note);
|
|
174
|
+
foldSeat({ type: "read", author: note.author, ids: note.reads, at: Date.now() });
|
|
175
|
+
}, [markAttention, foldSeat]);
|
|
176
|
+
/** Whether an id in the address still names something the graph has. */
|
|
177
|
+
const stillThere = useCallback((id) => {
|
|
178
|
+
if (kindOfCard(id) !== null || kindsOfAggregate(id).length > 0)
|
|
179
|
+
return true;
|
|
180
|
+
// A band's group names a run of a relation, not a kind: it is kept as itself.
|
|
181
|
+
if (isBandAggregate(id))
|
|
182
|
+
return true;
|
|
183
|
+
const edge = edgeOfSelection(id);
|
|
184
|
+
if (edge) {
|
|
185
|
+
return store.graph
|
|
186
|
+
.allEdges()
|
|
187
|
+
.some((other) => other.kind === edge.kind && other.from === edge.from && other.to === edge.to);
|
|
188
|
+
}
|
|
189
|
+
return store.graph.getNode(id) !== undefined;
|
|
190
|
+
}, [store]);
|
|
191
|
+
/** The same stop with every dead id taken out of it. */
|
|
192
|
+
const withoutWhatIsGone = useCallback((state) => {
|
|
193
|
+
const held = state.selection ?? EMPTY_SELECTION;
|
|
194
|
+
const kept = held.filter(stillThere);
|
|
195
|
+
let next = kept.length === held.length ? state : withSelection(state, kept);
|
|
196
|
+
// Null, not home: `resolveStop` below already knows where an app's
|
|
197
|
+
// home is, and an app that opens from altitude has no in-stack one.
|
|
198
|
+
if (next.focusId !== null && !stillThere(next.focusId))
|
|
199
|
+
next = withFocus(next, null);
|
|
200
|
+
return next;
|
|
201
|
+
}, [stillThere]);
|
|
202
|
+
/*
|
|
203
|
+
* A STOP, MADE STANDABLE-ON.
|
|
204
|
+
*
|
|
205
|
+
* Every way in writes here — a control, a popstate, a pasted link — and
|
|
206
|
+
* so does the render itself, because the graph can change underneath a
|
|
207
|
+
* stop nobody navigated away from. An id resolved at navigation time only
|
|
208
|
+
* is an id that goes stale the moment an act removes what it names.
|
|
209
|
+
*/
|
|
210
|
+
const resolveStop = useCallback((state) => {
|
|
211
|
+
let resolved = withoutWhatIsGone(state);
|
|
212
|
+
/*
|
|
213
|
+
* A focus this workspace cannot show — a bookmarked node whose
|
|
214
|
+
* module is off — lands on home rather than on a void with its
|
|
215
|
+
* name in the address bar.
|
|
216
|
+
*/
|
|
217
|
+
const disabled = hiddenFor(store, who, resolved.shown);
|
|
218
|
+
if (resolved.focusId !== null && disabled.size > 0) {
|
|
219
|
+
const kinds = kindsOfAggregate(resolved.focusId);
|
|
220
|
+
const node = store.graph.getNode(resolved.focusId);
|
|
221
|
+
const gone = kinds.length > 0
|
|
222
|
+
? kinds.every((kind) => disabled.has(kind))
|
|
223
|
+
: node
|
|
224
|
+
? disabled.has(node.kind)
|
|
225
|
+
: false;
|
|
226
|
+
if (gone)
|
|
227
|
+
resolved = { ...resolved, focusId: null };
|
|
228
|
+
}
|
|
229
|
+
/*
|
|
230
|
+
* INSIDE THE STACK, SOMETHING IS ALWAYS FOCUSED.
|
|
231
|
+
*
|
|
232
|
+
* A focusless in-stack view renders a shelf and a void — a screen
|
|
233
|
+
* with no main view, which reads as being stuck rather than as being
|
|
234
|
+
* anywhere. No control writes that state on purpose, but URLs,
|
|
235
|
+
* history pops and chains of chrome can compose it. Whatever asked
|
|
236
|
+
* for nothing lands on the view the app opened with instead. The
|
|
237
|
+
* overview stays free to be focusless: up there the ring is the
|
|
238
|
+
* picture.
|
|
239
|
+
*/
|
|
240
|
+
if (!resolved.overview && resolved.focusId === null) {
|
|
241
|
+
if (homeView.focusId !== null) {
|
|
242
|
+
resolved = { ...resolved, focusId: homeView.focusId };
|
|
243
|
+
}
|
|
244
|
+
else if (homeView.overview === true) {
|
|
245
|
+
// An app that OPENS from altitude has no in-stack default:
|
|
246
|
+
// falling out of the overview with nothing to focus lands back
|
|
247
|
+
// on the overview, so Escape at the outermost place is a no-op
|
|
248
|
+
// rather than a void.
|
|
249
|
+
resolved = { ...resolved, overview: true };
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return resolved;
|
|
253
|
+
}, [withoutWhatIsGone, store, homeView, who]);
|
|
254
|
+
/*
|
|
255
|
+
* Resolved on the way OUT, not only on the way in: an act that removes
|
|
256
|
+
* the focused record has to leave a stop standing on solid ground in the
|
|
257
|
+
* very render that reports the removal, before a layout is asked to place
|
|
258
|
+
* a node that is not there.
|
|
259
|
+
*/
|
|
260
|
+
const current = resolveStop(view ?? internalView);
|
|
261
|
+
const hiddenKinds = useMemo(() => hiddenFor(store, who, current.shown), [store, who, current.shown]);
|
|
262
|
+
const administered = useMemo(() => [...store.modules.administered.entries()].map(([name, module]) => {
|
|
263
|
+
const canShow = store.mayAdminister(name, who);
|
|
264
|
+
return {
|
|
265
|
+
name,
|
|
266
|
+
...(module.description ? { description: module.description } : {}),
|
|
267
|
+
kinds: module.kinds ?? [],
|
|
268
|
+
canShow,
|
|
269
|
+
shown: canShow && (current.shown ?? []).includes(name),
|
|
270
|
+
};
|
|
271
|
+
}), [store, who, current.shown]);
|
|
272
|
+
const setView = useCallback((next) => {
|
|
273
|
+
const resolve = (base) => resolveStop(typeof next === "function" ? next(base) : next);
|
|
274
|
+
if (view !== undefined) {
|
|
275
|
+
onViewChange?.(resolve(view));
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (onViewChange)
|
|
279
|
+
onViewChange(resolve(current));
|
|
280
|
+
/*
|
|
281
|
+
* Resolved against the PREVIOUS state, not the render-time view.
|
|
282
|
+
*
|
|
283
|
+
* Two writes in one gesture are ordinary — travelling also selects,
|
|
284
|
+
* going home also clears — and React batches them into one commit.
|
|
285
|
+
* Resolving both against the same stale render made the second write
|
|
286
|
+
* silently discard the first: the travel never happened, only its
|
|
287
|
+
* selection did. Functional composition is what "two updates" means.
|
|
288
|
+
*/
|
|
289
|
+
setInternalView((previous) => resolve(previous));
|
|
290
|
+
}, [current, onViewChange, view, resolveStop]);
|
|
291
|
+
/*
|
|
292
|
+
* And the address follows: once the render has resolved the stop, the
|
|
293
|
+
* fragment says the place you are actually standing in rather than the
|
|
294
|
+
* one that was removed underneath you. `useUrlSync` writes from the
|
|
295
|
+
* resolved view, so this only has to make sure the state behind it
|
|
296
|
+
* agrees — otherwise the next navigation resolves against a dead id.
|
|
297
|
+
*/
|
|
298
|
+
useEffect(() => {
|
|
299
|
+
if (view !== undefined)
|
|
300
|
+
return;
|
|
301
|
+
setInternalView((previous) => {
|
|
302
|
+
const resolved = resolveStop(previous);
|
|
303
|
+
return resolved === previous ? previous : resolved;
|
|
304
|
+
});
|
|
305
|
+
}, [current, view, resolveStop]);
|
|
306
|
+
/*
|
|
307
|
+
* Selection is VIEW STATE — part of the stop, not component state beside
|
|
308
|
+
* it. That is what makes back/forward restore the pane that was open, a
|
|
309
|
+
* refresh keep what you were pointing at, and a link carry the thing as
|
|
310
|
+
* well as the place. Changing it is an adjustment of the stop you are on
|
|
311
|
+
* (like a pan), so a run of clicks is not a run of history entries.
|
|
312
|
+
*/
|
|
313
|
+
const selection = current.selection ?? EMPTY_SELECTION;
|
|
314
|
+
const setSelection = useCallback((next) => {
|
|
315
|
+
setView((currentView) => withSelection(currentView, typeof next === "function" ? next(currentView.selection ?? EMPTY_SELECTION) : next));
|
|
316
|
+
}, [setView]);
|
|
317
|
+
const { who: others, following, follow, sharing } = usePresenceState({
|
|
318
|
+
channel: presence,
|
|
319
|
+
store,
|
|
320
|
+
view: current,
|
|
321
|
+
principal: who,
|
|
322
|
+
session,
|
|
323
|
+
robots,
|
|
324
|
+
seatWho,
|
|
325
|
+
settingValues,
|
|
326
|
+
setView,
|
|
327
|
+
});
|
|
328
|
+
const value = useMemo(() => ({
|
|
329
|
+
store,
|
|
330
|
+
scheme,
|
|
331
|
+
views,
|
|
332
|
+
view: current,
|
|
333
|
+
setView,
|
|
334
|
+
homeView,
|
|
335
|
+
selection,
|
|
336
|
+
setSelection,
|
|
337
|
+
menuAt,
|
|
338
|
+
setMenuAt,
|
|
339
|
+
whereIs,
|
|
340
|
+
pointer,
|
|
341
|
+
motion,
|
|
342
|
+
registerScene,
|
|
343
|
+
robots,
|
|
344
|
+
noteSeat,
|
|
345
|
+
seatWho,
|
|
346
|
+
registerSeatWho,
|
|
347
|
+
actsDoor,
|
|
348
|
+
registerActsDoor,
|
|
349
|
+
who: others,
|
|
350
|
+
following,
|
|
351
|
+
follow,
|
|
352
|
+
sharing,
|
|
353
|
+
session,
|
|
354
|
+
intelligence,
|
|
355
|
+
chooseIntelligence,
|
|
356
|
+
hostAnswers,
|
|
357
|
+
registerHostAnswers,
|
|
358
|
+
movedByHand,
|
|
359
|
+
noteMoved,
|
|
360
|
+
emphasis,
|
|
361
|
+
setEmphasis,
|
|
362
|
+
activity,
|
|
363
|
+
noteAttention,
|
|
364
|
+
principal: who,
|
|
365
|
+
seats,
|
|
366
|
+
takeSeat,
|
|
367
|
+
settings,
|
|
368
|
+
settingValues,
|
|
369
|
+
chooseSetting,
|
|
370
|
+
hiddenKinds,
|
|
371
|
+
administered,
|
|
372
|
+
...(providers ? { providers } : {}),
|
|
373
|
+
...(brand ? { brand } : {}),
|
|
374
|
+
}), [
|
|
375
|
+
store,
|
|
376
|
+
scheme,
|
|
377
|
+
views,
|
|
378
|
+
current,
|
|
379
|
+
setView,
|
|
380
|
+
selection,
|
|
381
|
+
setSelection,
|
|
382
|
+
menuAt,
|
|
383
|
+
whereIs,
|
|
384
|
+
pointer,
|
|
385
|
+
motion,
|
|
386
|
+
registerScene,
|
|
387
|
+
robots,
|
|
388
|
+
noteSeat,
|
|
389
|
+
seatWho,
|
|
390
|
+
registerSeatWho,
|
|
391
|
+
actsDoor,
|
|
392
|
+
others,
|
|
393
|
+
following,
|
|
394
|
+
follow,
|
|
395
|
+
sharing,
|
|
396
|
+
session,
|
|
397
|
+
intelligence,
|
|
398
|
+
chooseIntelligence,
|
|
399
|
+
hostAnswers,
|
|
400
|
+
registerHostAnswers,
|
|
401
|
+
movedByHand,
|
|
402
|
+
noteMoved,
|
|
403
|
+
emphasis,
|
|
404
|
+
activity,
|
|
405
|
+
noteAttention,
|
|
406
|
+
who,
|
|
407
|
+
seats,
|
|
408
|
+
takeSeat,
|
|
409
|
+
settings,
|
|
410
|
+
settingValues,
|
|
411
|
+
chooseSetting,
|
|
412
|
+
hiddenKinds,
|
|
413
|
+
administered,
|
|
414
|
+
providers,
|
|
415
|
+
brand,
|
|
416
|
+
]);
|
|
417
|
+
return (_jsx(GraviewContext.Provider, { value: value, children: _jsx(FoundProvider, { children: children }) }));
|
|
418
|
+
}
|
|
419
|
+
/*
|
|
420
|
+
* WHAT THE WORDS FIND, once for the whole scene.
|
|
421
|
+
*
|
|
422
|
+
* Every view reads the hits — to light them, to count them on a district —
|
|
423
|
+
* and a search per view per render would be the same scan dozens of times.
|
|
424
|
+
* So it runs here, once per change of the words, the graph, the seat or
|
|
425
|
+
* the selection (nearness ranks by it), and only over the districts this
|
|
426
|
+
* seat has drawn.
|
|
427
|
+
*/
|
|
428
|
+
const FoundContext = createContext(null);
|
|
429
|
+
function FoundProvider({ children }) {
|
|
430
|
+
const { store, view, views, principal, hiddenKinds, selection } = useGraview();
|
|
431
|
+
const nodes = useGraph();
|
|
432
|
+
const q = view.q;
|
|
433
|
+
const focusId = view.focusId;
|
|
434
|
+
/*
|
|
435
|
+
* What the rules flag and what the log touched change only with the
|
|
436
|
+
* graph, so they are worked out once per graph change — not re-run, every
|
|
437
|
+
* invariant and the whole log, on every keystroke.
|
|
438
|
+
*/
|
|
439
|
+
const searching = Boolean(q && q.trim().length > 0);
|
|
440
|
+
const standing = useMemo(() => searching
|
|
441
|
+
? { flagged: new Set(store.violations().flatMap((violation) => violation.nodeIds)), touched: touchWeights(store.log.all()) }
|
|
442
|
+
: null,
|
|
443
|
+
// `nodes` is the graph's tick.
|
|
444
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
445
|
+
[store, nodes, searching]);
|
|
446
|
+
// The kind the person is in: the district they went into, or the kind of the record they are on.
|
|
447
|
+
const inKind = focusId
|
|
448
|
+
? store.graph.getNode(focusId)?.kind ??
|
|
449
|
+
kindOfCard(focusId) ??
|
|
450
|
+
(kindsOfAggregate(focusId).length === 1 ? kindsOfAggregate(focusId)[0] : undefined)
|
|
451
|
+
: undefined;
|
|
452
|
+
const found = useMemo(() => {
|
|
453
|
+
if (!q || !standing)
|
|
454
|
+
return null;
|
|
455
|
+
return search(store, q, {
|
|
456
|
+
...(inKind ? { inKind } : {}),
|
|
457
|
+
principal,
|
|
458
|
+
places: views.places(),
|
|
459
|
+
kinds: store.schema.kinds.filter((kind) => !hiddenKinds.has(kind)),
|
|
460
|
+
from: [...selection, ...(focusId && store.graph.has(focusId) ? [focusId] : [])],
|
|
461
|
+
flagged: standing.flagged,
|
|
462
|
+
touched: standing.touched,
|
|
463
|
+
// The strip reads this many; the picture lights every match through `matched`.
|
|
464
|
+
limit: 200,
|
|
465
|
+
});
|
|
466
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
467
|
+
}, [store, q, principal, views, hiddenKinds, selection, focusId, inKind, standing]);
|
|
468
|
+
return _jsx(FoundContext.Provider, { value: found, children: children });
|
|
469
|
+
}
|
|
470
|
+
/** The scene's search, when `#q=` says there is one; null otherwise. */
|
|
471
|
+
export function useFound() {
|
|
472
|
+
return useContext(FoundContext);
|
|
473
|
+
}
|
|
474
|
+
export function useGraview() {
|
|
475
|
+
const value = useContext(GraviewContext);
|
|
476
|
+
if (!value) {
|
|
477
|
+
throw new Error("useGraview must be used inside a <GraviewProvider>.");
|
|
478
|
+
}
|
|
479
|
+
return value;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* The same, for a surface that can live on EITHER FACE.
|
|
483
|
+
*
|
|
484
|
+
* The scene is always inside a provider; the routed face is not — it carries
|
|
485
|
+
* its store in a `PageContext` instead. Most primitives belong to one face
|
|
486
|
+
* and can insist, but the few that belong to both must be able to ask
|
|
487
|
+
* without throwing: a component cannot call a hook conditionally, so "is
|
|
488
|
+
* there a provider" has to be a hook that answers rather than one that
|
|
489
|
+
* raises.
|
|
490
|
+
*/
|
|
491
|
+
export function useGraviewIfAny() {
|
|
492
|
+
return useContext(GraviewContext) ?? null;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Subscribes to the graph. Re-renders on every applied diff, whoever caused
|
|
496
|
+
* it — so an agent's edit updates the interface through exactly the path a
|
|
497
|
+
* human edit does.
|
|
498
|
+
*
|
|
499
|
+
* The snapshot is CACHED between diffs. `allNodes()` builds a fresh array
|
|
500
|
+
* every call, and `useSyncExternalStore` compares snapshots by identity: a
|
|
501
|
+
* new array each read is an infinite render loop, which is exactly what this
|
|
502
|
+
* hook did before the cache existed.
|
|
503
|
+
*/
|
|
504
|
+
export function useGraph() {
|
|
505
|
+
const { store } = useGraview();
|
|
506
|
+
const cache = useRef(null);
|
|
507
|
+
const owner = useRef(null);
|
|
508
|
+
const read = useCallback(() => {
|
|
509
|
+
if (owner.current !== store) {
|
|
510
|
+
owner.current = store;
|
|
511
|
+
cache.current = null;
|
|
512
|
+
}
|
|
513
|
+
cache.current ??= store.graph.allNodes();
|
|
514
|
+
return cache.current;
|
|
515
|
+
}, [store]);
|
|
516
|
+
const subscribe = useCallback((listener) => store.subscribe(() => {
|
|
517
|
+
cache.current = null;
|
|
518
|
+
listener();
|
|
519
|
+
}), [store]);
|
|
520
|
+
return useSyncExternalStore(subscribe, read, read);
|
|
521
|
+
}
|
|
522
|
+
/** One node, kept current as the graph changes underneath it. */
|
|
523
|
+
export function useNode(id) {
|
|
524
|
+
const { store } = useGraview();
|
|
525
|
+
const subscribe = useCallback((listener) => store.subscribe(listener), [store]);
|
|
526
|
+
// A node is a stable object reference between edits, so this needs no cache.
|
|
527
|
+
const read = useCallback(() => (id === null ? undefined : store.graph.getNode(id)), [store, id]);
|
|
528
|
+
return useSyncExternalStore(subscribe, read, read);
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* What a seat does not see at a stop. Disabled modules are nobody's; an
|
|
532
|
+
* administered module is kept from a seat that may not run its acts, and
|
|
533
|
+
* from one that may until the stop says `shown` — what the address says is
|
|
534
|
+
* never enough on its own.
|
|
535
|
+
*/
|
|
536
|
+
function hiddenFor(store, principal, shown) {
|
|
537
|
+
const hidden = new Set(store.modules.disabledKinds);
|
|
538
|
+
for (const kind of store.kindsKeptFrom(principal))
|
|
539
|
+
hidden.add(kind);
|
|
540
|
+
for (const [name, module] of store.modules.administered) {
|
|
541
|
+
if (store.mayAdminister(name, principal) && (shown ?? []).includes(name))
|
|
542
|
+
continue;
|
|
543
|
+
for (const kind of module.kinds ?? [])
|
|
544
|
+
hidden.add(kind);
|
|
545
|
+
}
|
|
546
|
+
return hidden;
|
|
547
|
+
}
|
|
548
|
+
/** How long a robot stands where it worked before walking home. The activity hold, so the mark and the body agree. */
|
|
549
|
+
export const ROBOT_REST_MS = 2600;
|
|
550
|
+
/** The robots, one per agent participant. */
|
|
551
|
+
export function useRobots() {
|
|
552
|
+
return useGraview().robots;
|
|
553
|
+
}
|
|
554
|
+
/** Where something is drawn right now, from the live frame. See `GraviewContextValue.whereIs`. */
|
|
555
|
+
export function useWhereIs() {
|
|
556
|
+
return useGraview().whereIs;
|
|
557
|
+
}
|
|
558
|
+
const NO_POINT = () => null;
|
|
559
|
+
/**
|
|
560
|
+
* The pointer over the scene, in scene coordinates, or null while it is
|
|
561
|
+
* not over the scene. Subscribing is what turns the scene's listener on;
|
|
562
|
+
* a component that stops rendering this turns it off again.
|
|
563
|
+
*/
|
|
564
|
+
export function useScenePointer() {
|
|
565
|
+
const { pointer } = useGraview();
|
|
566
|
+
return useSyncExternalStore(pointer.subscribe, pointer.snapshot, NO_POINT);
|
|
567
|
+
}
|
|
568
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"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"}
|
package/dist/drawn.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type Measure } from "@graview/layout";
|
|
2
|
+
import { type RefObject } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* WHAT A DRAWING CAN HONESTLY CLAIM TO BE, at the size it was actually given.
|
|
5
|
+
*
|
|
6
|
+
* A scalable drawing is written once in its own units and handed whatever
|
|
7
|
+
* room the page has. That is the right way round, and it hides a question
|
|
8
|
+
* nobody asks: at THIS size, is what I am drawing still a thing a person
|
|
9
|
+
* can read, or press?
|
|
10
|
+
*
|
|
11
|
+
* A product's site plan answered no on both counts and said nothing. The
|
|
12
|
+
* scene laid its panel out at 136 pixels on a phone; the canvas — a thousand
|
|
13
|
+
* units wide — resolved to 138 by 2 and the drawing did not scale down, it
|
|
14
|
+
* ESCAPED, painting names nine hundred pixels off the side of a 390-pixel
|
|
15
|
+
* screen. Every marker on it was a one-by-one target carrying a keyboard
|
|
16
|
+
* stop and an ARIA label, which is not an accessible control; it is an
|
|
17
|
+
* inaccessible control that has been described. And the whole canvas said
|
|
18
|
+
* `role="img"`, promising a screen reader that the controls inside it were
|
|
19
|
+
* decoration.
|
|
20
|
+
*
|
|
21
|
+
* There is no radius or font size that fixes any of that. At that scale a
|
|
22
|
+
* 24-pixel target is a sixth of the whole picture and twenty of them are one
|
|
23
|
+
* mush. The only honest answer is for the drawing to stop claiming to be a
|
|
24
|
+
* control surface when it is too small to be one, and for something beside
|
|
25
|
+
* it — a list, a key — to become the way in.
|
|
26
|
+
*/
|
|
27
|
+
export interface DrawnSize {
|
|
28
|
+
/** Rendered pixels per drawing unit. 1 until the first measurement. */
|
|
29
|
+
readonly scale: number;
|
|
30
|
+
/** The rendered width, in real pixels. */
|
|
31
|
+
readonly width: number;
|
|
32
|
+
/** Whether a mark of `target` units clears the 24px floor once drawn. */
|
|
33
|
+
readonly touchable: boolean;
|
|
34
|
+
/** Whether there is enough room for the drawing to say anything at all. */
|
|
35
|
+
readonly legible: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface DrawnOptions {
|
|
38
|
+
/** The width of the drawing in its own units — an SVG viewBox width. */
|
|
39
|
+
readonly units: number;
|
|
40
|
+
/** The width of the smallest thing meant to be pressed, in those units. */
|
|
41
|
+
readonly target?: number;
|
|
42
|
+
/** Below this many real pixels, a drawing of any complexity says nothing. */
|
|
43
|
+
readonly legibleAt?: number;
|
|
44
|
+
}
|
|
45
|
+
export declare function useDrawnSize(ref: RefObject<Element | null>, { units, target, legibleAt }: DrawnOptions): DrawnSize;
|
|
46
|
+
/**
|
|
47
|
+
* A TEXT MEASURER THAT MEASURES, where there is something to measure with.
|
|
48
|
+
*
|
|
49
|
+
* `fitLabel` takes a `Measure` because the honest answer depends on where
|
|
50
|
+
* you are. In a browser it is a 2D canvas context: synchronous, no layout,
|
|
51
|
+
* the same engine that will draw the SVG. The alternative is
|
|
52
|
+
* `getComputedTextLength`, which means rendering wrong once and correcting
|
|
53
|
+
* in an effect every time anything moves.
|
|
54
|
+
*
|
|
55
|
+
* The face matters. Pass the CSS variable the text is actually drawn in —
|
|
56
|
+
* a display serif and a body sans measure very differently, and guessing an
|
|
57
|
+
* average advance for both is what let three names overflow a plan.
|
|
58
|
+
*/
|
|
59
|
+
export declare function useTextMeasure(faceVariable?: string, fallback?: string): Measure;
|
|
60
|
+
//# sourceMappingURL=drawn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawn.d.ts","sourceRoot":"","sources":["../src/drawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAC1B,GAAG,EAAE,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,EAC9B,EAAE,KAAK,EAAE,MAAU,EAAE,SAAe,EAAE,EAAE,YAAY,GACnD,SAAS,CAcX;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,YAAY,SAAwB,EAAE,QAAQ,SAAe,GAAG,OAAO,CAsBrG"}
|