@graview/primitives 0.1.49 → 0.1.51

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.
Files changed (42) hide show
  1. package/dist/bar-suggested.d.ts.map +1 -1
  2. package/dist/bar-suggested.js +5 -3
  3. package/dist/bar-suggested.js.map +1 -1
  4. package/dist/chat.d.ts.map +1 -1
  5. package/dist/chat.js +7 -4
  6. package/dist/chat.js.map +1 -1
  7. package/dist/dismissals.d.ts +10 -0
  8. package/dist/dismissals.d.ts.map +1 -0
  9. package/dist/dismissals.js +60 -0
  10. package/dist/dismissals.js.map +1 -0
  11. package/dist/editable.d.ts.map +1 -1
  12. package/dist/editable.js +1 -1
  13. package/dist/editable.js.map +1 -1
  14. package/dist/here.d.ts.map +1 -1
  15. package/dist/here.js +2 -2
  16. package/dist/here.js.map +1 -1
  17. package/dist/kind-shape.js +1 -1
  18. package/dist/kind-shape.js.map +1 -1
  19. package/dist/live-prose-editor.d.ts +17 -0
  20. package/dist/live-prose-editor.d.ts.map +1 -0
  21. package/dist/live-prose-editor.js +260 -0
  22. package/dist/live-prose-editor.js.map +1 -0
  23. package/dist/live-text.d.ts +48 -0
  24. package/dist/live-text.d.ts.map +1 -0
  25. package/dist/live-text.js +164 -0
  26. package/dist/live-text.js.map +1 -0
  27. package/dist/prose-editor.d.ts +8 -2
  28. package/dist/prose-editor.d.ts.map +1 -1
  29. package/dist/prose-editor.js +17 -12
  30. package/dist/prose-editor.js.map +1 -1
  31. package/dist/suggested.d.ts +14 -4
  32. package/dist/suggested.d.ts.map +1 -1
  33. package/dist/suggested.js +58 -24
  34. package/dist/suggested.js.map +1 -1
  35. package/dist/workbench/activity.d.ts +7 -1
  36. package/dist/workbench/activity.d.ts.map +1 -1
  37. package/dist/workbench/activity.js +10 -6
  38. package/dist/workbench/activity.js.map +1 -1
  39. package/dist/workbench/agent-seat.d.ts.map +1 -1
  40. package/dist/workbench/agent-seat.js +7 -4
  41. package/dist/workbench/agent-seat.js.map +1 -1
  42. package/package.json +6 -6
@@ -0,0 +1,260 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { presenceName } from "@graview/core";
3
+ import { useGraview, useNode } from "@graview/react/provider";
4
+ import { useEffect, useLayoutEffect, useRef, useState } from "react";
5
+ import { caretHere, carriedOver, carrySelection, diffText, inputSplice, runToPutBack, runToTakeBack } from "./live-text.js";
6
+ import { TextBody } from "./text-body.js";
7
+ import "./frame.js"; // A door: tied to what the page drew first (TIED DOORS, packages/primitives/src/frame.ts).
8
+ /*
9
+ * THE LIVE EDITOR (Roadmap f-collab-text, phase 4): a field typed together,
10
+ * edited where a served store can carry it a keystroke at a time. Fetched
11
+ * only once somebody opens such a field, with the typing it sends through.
12
+ *
13
+ * There is no draft and nothing to save: each keystroke is the field's, at
14
+ * once, here and — a run at a time — for everybody else. "Done" closes it,
15
+ * and so does Escape, which puts nothing back: what was typed was already
16
+ * everybody's. Ctrl or ⌘ Z takes back this person's own last run of typing
17
+ * into the field, never somebody else's, though they typed after it.
18
+ *
19
+ * Somebody else's typing lands in the text area as it arrives, and the
20
+ * person's selection is carried over it, so they keep typing on the word
21
+ * they were on. While an input method composes a word nothing is sent, and
22
+ * what others type waits; the word and theirs meet once it is chosen.
23
+ *
24
+ * Everybody else typing here is drawn where their caret stands: a thin line
25
+ * in their hue, their name on it, laid on a copy of the text that wraps as
26
+ * the text area does. Nothing else is drawn.
27
+ */
28
+ export default function LiveProseEditor(props) {
29
+ const { store } = useGraview();
30
+ const { live, nodeId, field } = props;
31
+ /*
32
+ * Whether the declaration types the field together is read once the
33
+ * host's typing has arrived, with `@graview/core/typing`: a field written
34
+ * whole keeps its draft and Save. Until then the text area is read only.
35
+ */
36
+ const [typing, setTyping] = useState(null);
37
+ useEffect(() => {
38
+ let open = true;
39
+ void live.typing(nodeId, field).then((one) => open && setTyping(one));
40
+ return () => {
41
+ open = false;
42
+ };
43
+ // The host's typing, asked once: `live` is new each time somebody else moves.
44
+ }, [nodeId, field]);
45
+ if (typing && !store.collaborative(nodeId, field))
46
+ return _jsx(_Fragment, { children: props.writtenWhole });
47
+ return _jsx(LiveEditor, { ...props, typing: typing });
48
+ }
49
+ function LiveEditor({ nodeId, field, label, markdown, live, onDone, typing, }) {
50
+ const { store, principal } = useGraview();
51
+ const node = useNode(nodeId);
52
+ const value = textOf(node?.[field]);
53
+ const [preview, setPreview] = useState(false);
54
+ const area = useRef(null);
55
+ /** The field's text as the text area last showed it: what a keystroke is read against. */
56
+ const shown = useRef(value);
57
+ const composing = useRef(false);
58
+ /** The host's typing as it is now: the same channel, a new object each time who is here changes. */
59
+ const said = useRef(live);
60
+ said.current = live;
61
+ const textNow = () => textOf(store.graph.getNode(nodeId)?.[field]);
62
+ useEffect(() => area.current?.focus(), [preview, typing]);
63
+ /*
64
+ * Says where this person's caret stands, while the text area holds the
65
+ * keyboard: read when it is said, at most every `CARET_MS`, so a run of
66
+ * keystrokes is one word on the wire, not one each.
67
+ */
68
+ const caretSaid = useRef(undefined);
69
+ const sayCaret = () => {
70
+ if (caretSaid.current !== undefined)
71
+ return;
72
+ caretSaid.current = setTimeout(() => {
73
+ caretSaid.current = undefined;
74
+ const element = area.current;
75
+ if (!element || element.ownerDocument.activeElement !== element)
76
+ return;
77
+ const backward = element.selectionDirection === "backward";
78
+ said.current.sayCaret({ node: nodeId, field, anchor: backward ? element.selectionEnd : element.selectionStart, head: backward ? element.selectionStart : element.selectionEnd, rev: store.log.length });
79
+ }, CARET_MS);
80
+ };
81
+ // Once, as it closes: `live` is new each time somebody else moves, and that is no reason to say the caret has gone.
82
+ useEffect(() => () => {
83
+ clearTimeout(caretSaid.current);
84
+ said.current.sayCaret(null);
85
+ }, []);
86
+ /** The text area shows the field as it stands, the person's selection carried over what changed. */
87
+ const showNow = (now) => {
88
+ const element = area.current;
89
+ if (!element)
90
+ return;
91
+ if (element.value !== now) {
92
+ const selection = carrySelection({ start: element.selectionStart, end: element.selectionEnd }, diffText(element.value, now));
93
+ const direction = element.selectionDirection ?? "none";
94
+ element.value = now;
95
+ element.setSelectionRange(selection.start, selection.end, direction);
96
+ }
97
+ shown.current = now;
98
+ };
99
+ /** A keystroke: what it changed in the text the area showed, carried over whatever landed since, sent. */
100
+ const typed = () => {
101
+ const element = area.current;
102
+ if (!element || !typing || composing.current)
103
+ return;
104
+ const before = shown.current;
105
+ const now = textNow();
106
+ const mine = inputSplice(before, element.value, element.selectionEnd);
107
+ if (mine.removed === "" && mine.inserted === "")
108
+ return showNow(now);
109
+ const over = before === now ? mine : carriedOver(mine, diffText(before, now));
110
+ try {
111
+ typing.splice(over.at, over.removed.length, over.inserted);
112
+ }
113
+ catch {
114
+ // Refused here: the field stands as it was, and so does the area.
115
+ }
116
+ const after = textNow();
117
+ if (element.value !== after) {
118
+ element.value = after;
119
+ const caret = Math.min(after.length, over.at + over.inserted.length);
120
+ element.setSelectionRange(caret, caret);
121
+ }
122
+ shown.current = after;
123
+ sayCaret();
124
+ };
125
+ // Somebody else's typing, an undo, a reload: shown at once — unless a word is being composed, when it waits for the word.
126
+ useLayoutEffect(() => {
127
+ if (!composing.current)
128
+ showNow(value);
129
+ }, [value]);
130
+ const takeBack = async (again) => {
131
+ if (!typing)
132
+ return;
133
+ typing.flush();
134
+ // A run still on its way is taken back once the server has it.
135
+ for (let tries = 0; typing.waiting() > 0 && tries < 100; tries++)
136
+ await new Promise((resolve) => setTimeout(resolve, 30));
137
+ const batch = again ? runToPutBack(store, principal, nodeId, field) : runToTakeBack(store, principal, nodeId, field);
138
+ if (!batch)
139
+ return;
140
+ try {
141
+ if (again)
142
+ store.redo(batch, { author: principal });
143
+ else
144
+ store.undo(batch, { author: principal });
145
+ }
146
+ catch {
147
+ // Refused: nothing changed, and nothing is said over the person's typing.
148
+ }
149
+ };
150
+ const done = (left) => {
151
+ typing?.flush();
152
+ live.sayCaret(null);
153
+ onDone(left);
154
+ };
155
+ const others = [...live.who.values()].filter((one) => one.caret?.node === nodeId && one.caret.field === field);
156
+ return (_jsxs("div", { style: { display: "grid", gap: 8, minWidth: 0 }, "data-graview-live": field, children: [preview ? (_jsx("div", { "data-graview-preview": field, "aria-label": `${label}, as it will read`, role: "region", style: PREVIEW, children: _jsx(TextBody, { text: value, markdown: true }) })) : (_jsxs("div", { style: { position: "relative", minWidth: 0 }, children: [_jsx("textarea", { ref: area, "aria-label": label, "data-graview-field": field, defaultValue: value, readOnly: !typing, rows: 3, onInput: typed, onCompositionStart: () => {
157
+ composing.current = true;
158
+ }, onCompositionEnd: () => {
159
+ composing.current = false;
160
+ typed();
161
+ }, onSelect: sayCaret, onFocus: sayCaret, onPointerDown: () => typing?.flush(), onKeyDown: (event) => {
162
+ const key = event.key;
163
+ if (key === "Escape") {
164
+ event.preventDefault();
165
+ done(false);
166
+ }
167
+ else if ((event.metaKey || event.ctrlKey) && !event.altKey && key.toLowerCase() === "z") {
168
+ // The store's undo, not the text area's: it knows whose typing is whose.
169
+ event.preventDefault();
170
+ void takeBack(event.shiftKey);
171
+ }
172
+ else if ((event.metaKey || event.ctrlKey) && key === "Enter") {
173
+ event.preventDefault();
174
+ done(false);
175
+ }
176
+ else if (key === "Enter" || CARET_KEYS.has(key)) {
177
+ // A new line, or the caret moved: the run so far ends here.
178
+ typing?.flush();
179
+ }
180
+ }, onKeyUp: sayCaret, onBlur: (event) => {
181
+ typing?.flush();
182
+ live.sayCaret(null);
183
+ // Moving to the editor's own buttons is not leaving it.
184
+ const next = event.relatedTarget;
185
+ if (next instanceof Node && event.currentTarget.closest("[data-graview-live]")?.contains(next))
186
+ return;
187
+ done(true);
188
+ }, style: TEXT_AREA }), others.length > 0 ? _jsx(Carets, { text: value, others: others, area: area, log: store.log.all() }) : null] })), _jsxs("div", { style: { display: "flex", flexWrap: "wrap", alignItems: "center", gap: 8 }, children: [_jsx("button", { type: "button", onClick: () => done(false), style: BUTTON, children: "Done" }), markdown ? (_jsx("button", { type: "button", "aria-pressed": preview, onClick: () => setPreview(!preview), style: BUTTON, children: preview ? "Write" : "Preview" })) : null, _jsx("span", { style: { fontSize: "0.75rem", color: "var(--graview-ink-faint)" }, children: "Saved as you type \u00B7 Ctrl or \u2318 Z takes back your typing" })] })] }));
189
+ }
190
+ /**
191
+ * OTHERS' CARETS, ON A COPY OF THE TEXT: the same box, font and wrapping as
192
+ * the text area, its words transparent, laid over it; a caret is a line at
193
+ * its place in the copy, so it stands where the text area draws that place.
194
+ */
195
+ function Carets({ text, others, area, log }) {
196
+ const copy = useRef(null);
197
+ useLayoutEffect(() => {
198
+ const element = area.current;
199
+ const mirror = copy.current;
200
+ if (!element || !mirror)
201
+ return;
202
+ const follow = () => {
203
+ mirror.scrollTop = element.scrollTop;
204
+ };
205
+ follow();
206
+ element.addEventListener("scroll", follow);
207
+ return () => element.removeEventListener("scroll", follow);
208
+ });
209
+ const placed = others
210
+ .map((one) => ({ one, at: caretHere(one.caret, one.participant, log, text.length).end }))
211
+ .sort((a, b) => a.at - b.at);
212
+ const parts = [];
213
+ let from = 0;
214
+ for (const { one, at } of placed) {
215
+ parts.push(text.slice(from, at));
216
+ from = at;
217
+ const name = presenceName(one) || "Somebody";
218
+ parts.push(_jsx("span", { "data-graview-caret": one.participant, title: `${name} is typing here`, style: { borderLeft: `2px solid hsl(${Math.round(one.hue)} 55% 52%)`, marginLeft: -1, marginRight: -1, pointerEvents: "auto" } }, one.participant));
219
+ }
220
+ // A last line that is empty is still a line.
221
+ parts.push(`${text.slice(from)}​`);
222
+ return (_jsx("div", { ref: copy, "aria-hidden": "true", style: COPY, children: parts }));
223
+ }
224
+ /** How often a caret moved while typing is said, at most. */
225
+ const CARET_MS = 120;
226
+ const textOf = (value) => (typeof value === "string" ? value : "");
227
+ /** Keys that move the caret without typing: each ends the run before it. */
228
+ const CARET_KEYS = new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End", "PageUp", "PageDown"]);
229
+ const PREVIEW = { minHeight: "7.5em", padding: "8px 10px", border: "1px dashed var(--graview-edge-bright)", borderRadius: 6, lineHeight: 1.6, minWidth: 0 };
230
+ const BUTTON = { font: "inherit", fontSize: "0.8125rem", minHeight: 28, padding: "2px 12px" };
231
+ const BOX = {
232
+ font: "inherit",
233
+ lineHeight: 1.5,
234
+ width: "100%",
235
+ boxSizing: "border-box",
236
+ minHeight: "7.5em",
237
+ padding: "8px 10px",
238
+ borderRadius: 6,
239
+ };
240
+ const TEXT_AREA = {
241
+ ...BOX,
242
+ resize: "vertical",
243
+ fieldSizing: "content",
244
+ color: "var(--graview-ink)",
245
+ background: "var(--graview-panel, transparent)",
246
+ border: "1px solid var(--graview-edge-bright)",
247
+ };
248
+ const COPY = {
249
+ ...BOX,
250
+ position: "absolute",
251
+ inset: 0,
252
+ height: "100%",
253
+ border: "1px solid transparent",
254
+ color: "transparent",
255
+ whiteSpace: "pre-wrap",
256
+ overflowWrap: "break-word",
257
+ overflow: "hidden",
258
+ pointerEvents: "none",
259
+ };
260
+ //# sourceMappingURL=live-prose-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-prose-editor.js","sourceRoot":"","sources":["../src/live-prose-editor.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { type AnySchema, type Operation, type PresenceCaret, type Principal, type Store, type TextSplice } from "@graview/core";
2
+ /**
3
+ * THE KEYSTROKE AN INPUT MADE: `before` turned into `after`, the caret left
4
+ * at `caret` in `after`. What the two share at either end is left alone, as
5
+ * `diffSplice` does, but the end kept is never left of the caret — so a
6
+ * letter typed into a run of the same letter ("aa" → "aaa") is put where
7
+ * the caret says it was typed, not at the end of the run, and lands where
8
+ * the person typed it among what others type.
9
+ */
10
+ export declare function inputSplice(before: string, after: string, caret: number): TextSplice;
11
+ /** The one splice that turns `before` into `after`: `diffSplice`'s answer, the shared start kept first, never half of a pair. */
12
+ export declare function diffText(before: string, after: string): TextSplice;
13
+ /**
14
+ * THE PERSON'S KEYSTROKE, CARRIED OVER SOMEBODY ELSE'S TEXT that landed
15
+ * while it was typed (`transformSplices`' rule, theirs the earlier): apart,
16
+ * it moves by what theirs changed; touching, it takes out what both took
17
+ * out and puts in both, theirs first where they meet.
18
+ */
19
+ export declare function carriedOver(mine: TextSplice, theirs: TextSplice): TextSplice;
20
+ /** A selection in a text, as a text area holds it. */
21
+ export interface Selection {
22
+ readonly start: number;
23
+ readonly end: number;
24
+ }
25
+ /**
26
+ * WHERE A PERSON'S OWN SELECTION GOES WHEN SOMEBODY ELSE'S TEXT LANDS: each
27
+ * end carried over the splice, and a caret that text was inserted at stays
28
+ * before it — the person keeps typing where they were, and the other's
29
+ * words appear after their caret, not under it.
30
+ */
31
+ export declare function carrySelection(selection: Selection, splice: TextSplice): Selection;
32
+ /**
33
+ * WHERE ANOTHER PERSON'S CARET STANDS IN THIS PAGE'S TEXT: said against
34
+ * their log at `rev`, carried over every splice into the field this page's
35
+ * log took since that they did not make (what they made, their caret had
36
+ * already moved with), and kept inside the text.
37
+ */
38
+ export declare function caretHere(caret: PresenceCaret, participant: string, log: readonly Operation[], length: number): Selection;
39
+ /**
40
+ * THE RUN OF TYPING ⌘Z TAKES BACK: this person's latest run into this field
41
+ * that is not taken back already and that the log lets go of on its own —
42
+ * never somebody else's, though they typed after it. Ctrl or ⌘ Z again
43
+ * takes the one before it.
44
+ */
45
+ export declare function runToTakeBack(store: Store<AnySchema>, principal: Principal | undefined, node: string, field: string): string | undefined;
46
+ /** The take-back ⌘⇧Z puts back: this person's latest change to this field, when it was taking a run back. */
47
+ export declare function runToPutBack(store: Store<AnySchema>, principal: Principal | undefined, node: string, field: string): string | undefined;
48
+ //# sourceMappingURL=live-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-text.d.ts","sourceRoot":"","sources":["../src/live-text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAc,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AA0BvJ;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAWpF;AAED,iIAAiI;AACjI,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CASlE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,CAU5E;AAED,sDAAsD;AACtD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,CAIlF;AASD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAazH;AAoBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQxI;AAED,6GAA6G;AAC7G,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASvI"}
@@ -0,0 +1,164 @@
1
+ import { TYPE_TEXT } from "@graview/core";
2
+ /*
3
+ * THE LIVE EDITOR'S ARITHMETIC (Roadmap f-collab-text, phase 4), apart from
4
+ * its drawing so each rule can be held by a test: what a keystroke was, where
5
+ * a caret goes when somebody else's text lands, where another person's caret
6
+ * stands in this page's text, and which run of typing is this person's to
7
+ * take back. Fetched with the live editor, never in a first load.
8
+ */
9
+ /*
10
+ * Read here, not from `@graview/core`: whatever a chunk fetched later takes
11
+ * from the main entry, the first load carries.
12
+ */
13
+ /** Where a caret goes over a splice (`transformCaret`'s rule): before it stays, past it moves, on it keeps the side `before` says. */
14
+ function caretOver(caret, splice, before = false) {
15
+ if (caret < splice.at || (caret === splice.at && before))
16
+ return caret;
17
+ const end = splice.at + splice.removed.length;
18
+ if (caret >= end)
19
+ return caret + splice.inserted.length - splice.removed.length;
20
+ return before ? splice.at : splice.at + splice.inserted.length;
21
+ }
22
+ const high = (code) => code >= 0xd800 && code <= 0xdbff;
23
+ const low = (code) => code >= 0xdc00 && code <= 0xdfff;
24
+ /**
25
+ * THE KEYSTROKE AN INPUT MADE: `before` turned into `after`, the caret left
26
+ * at `caret` in `after`. What the two share at either end is left alone, as
27
+ * `diffSplice` does, but the end kept is never left of the caret — so a
28
+ * letter typed into a run of the same letter ("aa" → "aaa") is put where
29
+ * the caret says it was typed, not at the end of the run, and lands where
30
+ * the person typed it among what others type.
31
+ */
32
+ export function inputSplice(before, after, caret) {
33
+ const most = Math.min(before.length, after.length);
34
+ let tail = 0;
35
+ const tailMost = Math.max(0, Math.min(most, after.length - caret));
36
+ while (tail < tailMost && before.charCodeAt(before.length - 1 - tail) === after.charCodeAt(after.length - 1 - tail))
37
+ tail++;
38
+ let head = 0;
39
+ while (head < most - tail && before.charCodeAt(head) === after.charCodeAt(head))
40
+ head++;
41
+ // Never half of a pair: an emoji is typed or taken out whole.
42
+ if (head > 0 && high(before.charCodeAt(head - 1)))
43
+ head--;
44
+ if (tail > 0 && low(before.charCodeAt(before.length - tail)))
45
+ tail--;
46
+ return { at: head, removed: before.slice(head, before.length - tail), inserted: after.slice(head, after.length - tail) };
47
+ }
48
+ /** The one splice that turns `before` into `after`: `diffSplice`'s answer, the shared start kept first, never half of a pair. */
49
+ export function diffText(before, after) {
50
+ const most = Math.min(before.length, after.length);
51
+ let head = 0;
52
+ while (head < most && before.charCodeAt(head) === after.charCodeAt(head))
53
+ head++;
54
+ if (head > 0 && high(before.charCodeAt(head - 1)))
55
+ head--;
56
+ let tail = 0;
57
+ while (tail < most - head && before.charCodeAt(before.length - 1 - tail) === after.charCodeAt(after.length - 1 - tail))
58
+ tail++;
59
+ if (tail > 0 && low(before.charCodeAt(before.length - tail)))
60
+ tail--;
61
+ return { at: head, removed: before.slice(head, before.length - tail), inserted: after.slice(head, after.length - tail) };
62
+ }
63
+ /**
64
+ * THE PERSON'S KEYSTROKE, CARRIED OVER SOMEBODY ELSE'S TEXT that landed
65
+ * while it was typed (`transformSplices`' rule, theirs the earlier): apart,
66
+ * it moves by what theirs changed; touching, it takes out what both took
67
+ * out and puts in both, theirs first where they meet.
68
+ */
69
+ export function carriedOver(mine, theirs) {
70
+ const end = (one) => one.at + one.removed.length;
71
+ if (end(mine) < theirs.at)
72
+ return mine;
73
+ if (mine.at > end(theirs))
74
+ return { ...mine, at: mine.at + theirs.inserted.length - theirs.removed.length };
75
+ const from = Math.min(mine.at, theirs.at);
76
+ const past = end(mine) - end(theirs);
77
+ const removed = mine.removed.slice(0, theirs.at - from) + theirs.inserted + (past > 0 ? mine.removed.slice(mine.removed.length - past) : "");
78
+ const inserted = theirs.at <= mine.at ? theirs.inserted + mine.inserted : mine.inserted + theirs.inserted;
79
+ const said = diffText(removed, inserted);
80
+ return { ...said, at: from + said.at };
81
+ }
82
+ /**
83
+ * WHERE A PERSON'S OWN SELECTION GOES WHEN SOMEBODY ELSE'S TEXT LANDS: each
84
+ * end carried over the splice, and a caret that text was inserted at stays
85
+ * before it — the person keeps typing where they were, and the other's
86
+ * words appear after their caret, not under it.
87
+ */
88
+ export function carrySelection(selection, splice) {
89
+ const start = caretOver(selection.start, splice, true);
90
+ const end = selection.end === selection.start ? start : caretOver(selection.end, splice);
91
+ return { start, end: Math.max(start, end) };
92
+ }
93
+ /** Whether an op was made by the participant a presence names (`kind:id:session`): their kind and id, and their tab when the op says one. */
94
+ function madeBy(op, participant) {
95
+ const { kind, id, session } = op.author;
96
+ const own = `${kind}:${id ?? ""}:`;
97
+ return participant.startsWith(own) && (!session || participant.slice(own.length) === session);
98
+ }
99
+ /**
100
+ * WHERE ANOTHER PERSON'S CARET STANDS IN THIS PAGE'S TEXT: said against
101
+ * their log at `rev`, carried over every splice into the field this page's
102
+ * log took since that they did not make (what they made, their caret had
103
+ * already moved with), and kept inside the text.
104
+ */
105
+ export function caretHere(caret, participant, log, length) {
106
+ let anchor = caret.anchor;
107
+ let head = caret.head;
108
+ for (const op of log) {
109
+ if (op.seq < caret.rev || madeBy(op, participant))
110
+ continue;
111
+ for (const one of op.primitives) {
112
+ if (one.op !== "splice-text" || one.id !== caret.node || one.field !== caret.field)
113
+ continue;
114
+ anchor = caretOver(anchor, one);
115
+ head = caretOver(head, one);
116
+ }
117
+ }
118
+ const kept = (at) => Math.max(0, Math.min(length, at));
119
+ return { start: kept(anchor), end: kept(head) };
120
+ }
121
+ /** Whether a batch is a run of typing into this one field. */
122
+ const typedInto = (batch, node, field) => batch.ops.length > 0 &&
123
+ batch.ops.every((op) => {
124
+ const args = op.mutation?.args;
125
+ return op.mutation?.name === TYPE_TEXT && args?.node === node && args.field === field;
126
+ });
127
+ /** Whether a batch takes back runs of typing into this one field. */
128
+ const takesTypingBack = (store, batch, node, field) => batch.ops.length > 0 &&
129
+ batch.ops.every((op) => op.undoes !== undefined) &&
130
+ store.batches().some((one) => batch.ops.some((op) => op.undoes === one.id || op.undoes === one.ops[0]?.id) && typedInto(one, node, field));
131
+ /** A batch this person made: a human author who is this principal (the rule the way back and Activity use for "you"). */
132
+ const isMine = (batch, principal) => batch.author.kind === "human" && (principal?.id === undefined || batch.author.id === undefined || batch.author.id === principal.id);
133
+ /**
134
+ * THE RUN OF TYPING ⌘Z TAKES BACK: this person's latest run into this field
135
+ * that is not taken back already and that the log lets go of on its own —
136
+ * never somebody else's, though they typed after it. Ctrl or ⌘ Z again
137
+ * takes the one before it.
138
+ */
139
+ export function runToTakeBack(store, principal, node, field) {
140
+ const batches = store.batches();
141
+ for (let at = batches.length - 1; at >= 0; at--) {
142
+ const batch = batches[at];
143
+ if (!isMine(batch, principal) || batch.undone || !typedInto(batch, node, field))
144
+ continue;
145
+ if (store.canUndo(batch.id).ok)
146
+ return batch.id;
147
+ }
148
+ return undefined;
149
+ }
150
+ /** The take-back ⌘⇧Z puts back: this person's latest change to this field, when it was taking a run back. */
151
+ export function runToPutBack(store, principal, node, field) {
152
+ const batches = store.batches();
153
+ for (let at = batches.length - 1; at >= 0; at--) {
154
+ const batch = batches[at];
155
+ if (!isMine(batch, principal))
156
+ continue;
157
+ if (typedInto(batch, node, field))
158
+ return undefined;
159
+ if (takesTypingBack(store, batch, node, field))
160
+ return batch.undone ? undefined : batch.id;
161
+ }
162
+ return undefined;
163
+ }
164
+ //# sourceMappingURL=live-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-text.js","sourceRoot":"","sources":["../src/live-text.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  import "./frame.js";
2
- export default function ProseEditor({ field, label, value, markdown, onSave, onCancel, }: {
2
+ interface ProseEditorProps {
3
+ /** The record, where the field may be typed together (Roadmap f-collab-text). */
4
+ readonly nodeId?: string;
3
5
  readonly field: string;
4
6
  readonly label: string;
5
7
  readonly value: string;
@@ -8,5 +10,9 @@ export default function ProseEditor({ field, label, value, markdown, onSave, onC
8
10
  /** `left`: the person moved the keyboard elsewhere, and it stays there. */
9
11
  readonly onSave: (draft: string, left: boolean) => void;
10
12
  readonly onCancel: () => void;
11
- }): import("react").JSX.Element;
13
+ /** The live editor closed: `left`, the keyboard went elsewhere. Without it, `onCancel`. */
14
+ readonly onDone?: (left: boolean) => void;
15
+ }
16
+ export default function ProseEditor(props: ProseEditorProps): import("react").JSX.Element;
17
+ export {};
12
18
  //# sourceMappingURL=prose-editor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prose-editor.d.ts","sourceRoot":"","sources":["../src/prose-editor.tsx"],"names":[],"mappings":"AAEA,OAAO,YAAY,CAAC;AAcpB,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,KAAK,EACL,KAAK,EACL,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC/B,+BAuEA"}
1
+ {"version":3,"file":"prose-editor.d.ts","sourceRoot":"","sources":["../src/prose-editor.tsx"],"names":[],"mappings":"AAGA,OAAO,YAAY,CAAC;AAcpB,UAAU,gBAAgB;IACxB,iFAAiF;IACjF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;IAC9B,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC3C;AASD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,KAAK,EAAE,gBAAgB,+BAgB1D"}
@@ -1,20 +1,25 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useLayoutEffect, useRef, useState } from "react";
2
+ import { TypingContext } from "@graview/react/provider";
3
+ import { lazy, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
3
4
  import { TextBody } from "./text-body.js";
4
5
  import "./frame.js"; // A door: tied to what the page drew first (TIED DOORS, packages/primitives/src/frame.ts).
5
6
  /*
6
- * THE TEXT AREA PROSE IS CHANGED IN (FR-147), fetched the first time a
7
- * person opens one: every record draws prose, few are edited, and a page's
8
- * first load carries the drawing, not the editor.
9
- *
10
- * As tall as what it holds (`field-sizing: content`, measured where an
11
- * engine lacks it). Enter is a new line; Ctrl or ⌘ with Enter saves, as
12
- * does leaving it; Escape puts it back. Named for the field.
13
- *
14
- * Markdown (FR-180) is written as Markdown, and "Preview" shows it as the
15
- * record will draw it — "Write" goes back to the words, where they were.
7
+ * TYPED TOGETHER, LIVE (Roadmap f-collab-text, phase 4): under a host that
8
+ * can carry typing (a served store), the live editor is fetched as prose is
9
+ * opened, with `@graview/core/typing`, which says whether the declaration
10
+ * types the field together; it is edited live when it does. Anywhere else,
11
+ * and for a field written whole, the draft and its Save, as before.
16
12
  */
17
- export default function ProseEditor({ field, label, value, markdown, onSave, onCancel, }) {
13
+ export default function ProseEditor(props) {
14
+ const live = useContext(TypingContext);
15
+ const draft = _jsx(DraftProseEditor, { ...props });
16
+ if (!live || props.nodeId === undefined)
17
+ return draft;
18
+ // Whether the field is typed together is read with `@graview/core/typing`, which comes with the live editor.
19
+ return (_jsx(LiveProseEditor, { nodeId: props.nodeId, field: props.field, label: props.label, ...(props.markdown ? { markdown: true } : {}), live: live, onDone: (left) => (props.onDone ? props.onDone(left) : props.onCancel()), writtenWhole: draft }));
20
+ }
21
+ const LiveProseEditor = lazy(() => import("./live-prose-editor.js"));
22
+ function DraftProseEditor({ field, label, value, markdown, onSave, onCancel }) {
18
23
  const [draft, setDraft] = useState(value);
19
24
  const [preview, setPreview] = useState(false);
20
25
  const area = useRef(null);
@@ -1 +1 @@
1
- {"version":3,"file":"prose-editor.js","sourceRoot":"","sources":["../src/prose-editor.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prose-editor.js","sourceRoot":"","sources":["../src/prose-editor.tsx"],"names":[],"mappings":"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"}
@@ -1,13 +1,23 @@
1
1
  import "./frame.js";
2
+ /**
3
+ * WHAT THE APP'S OWN ACTOR LEFT WHILE A PERSON WAS AWAY, in a line: "3
4
+ * suggestions waiting · tidied 12 things while you were away", or undefined
5
+ * when there is nothing to say.
6
+ */
7
+ export declare function awayWords(waiting: number, tidied: number): string | undefined;
2
8
  /**
3
9
  * THE SUGGESTED TRAY: what the app's own actor proposed and did not make
4
10
  * (`suggest`, `@graview/core/tidying`), waiting for a person — quietly, on the bar beside
5
11
  * Activity, never in the way of anything. Each says what it would do, who
6
12
  * suggested it, what it was based on and how sure, and the records it
7
- * names; Accept makes it as the person, carrying its lineage, and Decline
8
- * keeps the decline in the log, so it is never suggested again. Fetched
9
- * when the log holds a suggestion (`BarSuggested`), so a page with none
10
- * carries none of it; drawn while one still waits for this seat.
13
+ * names; Accept makes it as the person, carrying its lineage, Decline
14
+ * keeps the decline in the log, so it is never suggested again, and Not now
15
+ * puts it out of this person's sight until tomorrow — kept where the host
16
+ * keeps their own state (`dismissals`), so nobody else is told and the
17
+ * actor is held to nothing. Fetched when the log holds a suggestion, or
18
+ * the host said what was done while the person was away (`BarSuggested`),
19
+ * so a page with neither carries none of it; drawn while one still waits
20
+ * for this person, or there is something to say of their time away.
11
21
  */
12
22
  export declare function SuggestedTray(): import("react").JSX.Element | null;
13
23
  //# sourceMappingURL=suggested.d.ts.map