@agent-factory-platform/docs-react 0.11.1 → 0.11.2

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 CHANGED
@@ -12,9 +12,10 @@ Use the exact Agent Factory version across packages in one application.
12
12
 
13
13
  ## Scope
14
14
 
15
- Owns the rich-document editor, durable JSON serialization, and transient image
16
- projection. Storage, authentication, autosave/CAS and provider credentials belong
17
- to the consuming product; the editor does not upload directly to a cloud account.
15
+ Owns the rich-document editor, durable JSON serialization, transient image
16
+ projection, and the shared CAS autosave coordinator. Storage, authentication and
17
+ provider credentials belong to the consuming product; the editor does not upload
18
+ directly to a cloud account.
18
19
 
19
20
  Import the public styles before generating the application's Tailwind utilities,
20
21
  so component utility defaults cannot override application responsive variants:
@@ -69,6 +70,12 @@ queued across transient failures; explicit disconnect makes `flush` and `checkpo
69
70
  fail until that adapter reconnects. Use `disconnect` for a temporary React unmount and
70
71
  `destroy` only when the editor session is finished.
71
72
 
73
+ `DocsAutosaveController` debounces a host-supplied CAS persist callback, serializes
74
+ checkpoints, and immediately follows an in-flight save when newer edits exist. It
75
+ retains dirty state across offline and failed saves, exposes retry and observable
76
+ `dirty`/`saving`/`saved`/`offline`/`error`/`denied` states, and only carries a
77
+ server-returned `updatedAt` value into the saved snapshot.
78
+
72
79
  One collaboration update is limited to 65,536 bytes. An oversized local Yjs update
73
80
  fails `flush`/`checkpoint` without sending partial state, keeps the local document,
74
81
  and can recover after the document is reduced below the limit. Invalid input and
@@ -0,0 +1,39 @@
1
+ export type DocsAutosaveStatus = "clean" | "dirty" | "saving" | "saved" | "offline" | "error" | "denied";
2
+ export type DocsAutosaveSnapshot<Revision> = {
3
+ status: DocsAutosaveStatus;
4
+ revision: Revision;
5
+ updatedAt?: number;
6
+ error?: unknown;
7
+ };
8
+ export type DocsAutosaveResult<Revision> = {
9
+ revision: Revision;
10
+ updatedAt?: number;
11
+ };
12
+ /** Debounces one CAS-backed Docs mutation while preserving edits made during a save. */
13
+ export declare class DocsAutosaveController<Revision> {
14
+ private readonly persist;
15
+ private readonly delayMs;
16
+ private snapshot;
17
+ private generation;
18
+ private savedGeneration;
19
+ private online;
20
+ private writable;
21
+ private timer?;
22
+ private saving?;
23
+ private readonly listeners;
24
+ constructor(revision: Revision, persist: (expectedRevision: Revision) => Promise<DocsAutosaveResult<Revision>>, delayMs?: number);
25
+ getSnapshot: () => DocsAutosaveSnapshot<Revision>;
26
+ subscribe: (listener: () => void) => () => boolean;
27
+ markDirty(): void;
28
+ setOnline(online: boolean): void;
29
+ setWritable(writable: boolean): void;
30
+ retry(): Promise<void>;
31
+ flush(): Promise<void>;
32
+ destroy(): void;
33
+ private drain;
34
+ private hasPending;
35
+ private schedule;
36
+ private clearTimer;
37
+ private publish;
38
+ private emit;
39
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { RICH_DOCUMENT_SCHEMA, RichDocument, RichDocument as RichDocumentEditor, applyDocumentAssistantOutput, commitDocumentAssistantRollback, documentAssistantConflict, durableRichDocumentContent, emptyRichDocument, looksLikeMarkdown, parseRichDocument, replaceAssistantMarkdown, rollbackAssistantRange, replaceDocumentContent, richDocumentExtensions, selectionInsideTable, type RichDocumentContent, type RichDocumentProps, type DocumentAssistantCommit, type DocumentAssistantConflict, type RichDocumentLabels, } from "./rich-document";
2
2
  export { DocsWorkbench, DocsWorkbenchController, PublishedDocs, PublishedDocsController, useDocsWorkbench, usePublishedDocs, type DocsWorkbenchList, type DocsWorkbenchState, type DocsWorkbenchTransport, type PublishedDocsState, type PublishedDocsTransport } from "./workbench";
3
3
  export { DocsCollaboration, DocsCollaborationController, YjsDocsCollaborationAdapter, useDocsCollaboration, type DocsCollaborationState, type DocsCollaborationTransport } from "./collaboration";
4
+ export { DocsAutosaveController, type DocsAutosaveResult, type DocsAutosaveSnapshot, type DocsAutosaveStatus } from "./autosave";
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  var Gt = Object.defineProperty;
2
2
  var Qt = (s, e, t) => e in s ? Gt(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
- var f = (s, e, t) => Qt(s, typeof e != "symbol" ? e + "" : e, t);
4
- import { jsx as r, jsxs as h, Fragment as Ee } from "react/jsx-runtime";
3
+ var u = (s, e, t) => Qt(s, typeof e != "symbol" ? e + "" : e, t);
4
+ import { jsx as r, jsxs as p, Fragment as Ee } from "react/jsx-runtime";
5
5
  import { Node as Zt, mergeAttributes as es, getSchema as ts } from "@tiptap/core";
6
6
  import ss from "@tiptap/extension-collaboration";
7
7
  import ns from "@tiptap/extension-collaboration-caret";
@@ -19,8 +19,8 @@ import { Slice as Ct } from "@tiptap/pm/model";
19
19
  import { useEditor as vs, EditorContent as bs } from "@tiptap/react";
20
20
  import { FloatingMenu as ws, BubbleMenu as Xe } from "@tiptap/react/menus";
21
21
  import ys from "@tiptap/starter-kit";
22
- import { Toolbar as xe, ToolbarSeparator as V, Input as Re, IconTip as Ue, Pressable as P, MenuChoiceGroup as oe, MenuCommandItem as M, Popover as We, ToolbarButton as ae, Button as z, Modal as ks, StateView as j, CardLabel as q, CardTitle as B, Card as Y, Tag as $, NativeSelect as Ss } from "@agent-factory-platform/ui-kit";
23
- import { Heading1 as Ye, Heading2 as Ge, Heading3 as Qe, List as Ze, ListOrdered as et, ListChecks as tt, Quote as st, SquareCode as nt, MessageSquareWarning as it, Table2 as De, Pilcrow as rt, Bold as ot, Italic as at, Underline as ct, Strikethrough as lt, Code2 as dt, Link2 as ut, Plus as xs, Sparkles as ht, ImagePlus as pt, Palette as ft, AlignLeft as mt, AlignCenter as Ds, AlignRight as Cs, Minus as Is, ChevronDown as Ns, WandSparkles as Ps, BetweenHorizontalStart as Ts, BetweenHorizontalEnd as As, Rows3 as Es, BetweenVerticalStart as zs, BetweenVerticalEnd as Rs, Columns3 as Us, TableCellsMerge as Ls, TableCellsSplit as Ms, Trash2 as It, BookOpen as Os, ShieldCheck as _s, RefreshCw as qs, Languages as Bs } from "lucide-react";
22
+ import { Toolbar as xe, ToolbarSeparator as V, Input as Re, IconTip as Ue, Pressable as N, MenuChoiceGroup as oe, MenuCommandItem as M, Popover as We, ToolbarButton as ae, Button as z, Modal as ks, StateView as j, CardLabel as q, CardTitle as B, Card as Y, Tag as $, NativeSelect as Ss } from "@agent-factory-platform/ui-kit";
23
+ import { Heading1 as Ye, Heading2 as Ge, Heading3 as Qe, List as Ze, ListOrdered as et, ListChecks as tt, Quote as st, SquareCode as nt, MessageSquareWarning as it, Table2 as De, Pilcrow as rt, Bold as ot, Italic as at, Underline as ct, Strikethrough as lt, Code2 as dt, Link2 as ut, Plus as xs, Sparkles as ht, ImagePlus as pt, Palette as ft, AlignLeft as mt, AlignCenter as Ds, AlignRight as Cs, Minus as Is, ChevronDown as Ps, WandSparkles as Ns, BetweenHorizontalStart as Ts, BetweenHorizontalEnd as As, Rows3 as Es, BetweenVerticalStart as zs, BetweenVerticalEnd as Rs, Columns3 as Us, TableCellsMerge as Ls, TableCellsSplit as Ms, Trash2 as It, BookOpen as Os, ShieldCheck as _s, RefreshCw as qs, Languages as Bs } from "lucide-react";
24
24
  import { useMemo as js, useState as T, useSyncExternalStore as pe, useRef as Ce, useEffect as Ie, useLayoutEffect as Hs, useCallback as Vs } from "react";
25
25
  import { docsV1 as G, isRetryableRpcError as Le } from "@agent-factory-platform/client";
26
26
  import { prosemirrorJSONToYXmlFragment as $s, yXmlFragmentToProsemirrorJSON as Fs } from "@tiptap/y-tiptap";
@@ -50,7 +50,7 @@ async function Ys(s, e, t) {
50
50
  return s.view.dispatch(s.state.tr.replaceRange(e.range.from, e.range.to, e.original)), { value: c, revision: d };
51
51
  }
52
52
  function Gs(s, e, t, n) {
53
- if (!Nt(s, e, t))
53
+ if (!Pt(s, e, t))
54
54
  try {
55
55
  const i = Ct.fromJSON(s.schema, t.originalSlice), c = Xs(s, t.range, n);
56
56
  return { range: c, original: i, generated: s.state.doc.slice(c.from, c.to) };
@@ -58,7 +58,7 @@ function Gs(s, e, t, n) {
58
58
  return;
59
59
  }
60
60
  }
61
- function Nt(s, e, t) {
61
+ function Pt(s, e, t) {
62
62
  if (e.documentId !== t.documentId || e.nodeId !== t.nodeId) return "identity";
63
63
  if (e.baseRevision !== t.baseRevision) return "revision";
64
64
  if (!t.originalSlice) return "missing_original";
@@ -82,16 +82,16 @@ const Qs = Zt.create({
82
82
  var s;
83
83
  return { ...(s = this.parent) == null ? void 0 : s.call(this), asset_id: { default: null, parseHTML: (e) => e.getAttribute("data-asset-id"), renderHTML: (e) => e.asset_id ? { "data-asset-id": e.asset_id } : {} } };
84
84
  }
85
- }), en = ["var(--color-ink)", "var(--color-graphite)", "var(--color-rust)", "var(--color-data-blue)", "var(--color-success)", "var(--color-warning)", "var(--color-danger)"], de = ["var(--color-surface-muted)", "var(--color-surface-warm)", "var(--color-surface-cool)", "var(--color-data-4)", "var(--color-data-5)"], Pt = () => ({
85
+ }), en = ["var(--color-ink)", "var(--color-graphite)", "var(--color-rust)", "var(--color-data-blue)", "var(--color-success)", "var(--color-warning)", "var(--color-danger)"], de = ["var(--color-surface-muted)", "var(--color-surface-warm)", "var(--color-surface-cool)", "var(--color-data-4)", "var(--color-data-5)"], Nt = () => ({
86
86
  default: null,
87
87
  parseHTML: (s) => de.includes(s.style.backgroundColor) ? s.style.backgroundColor : null,
88
88
  renderHTML: ({ backgroundColor: s }) => s && de.includes(s) ? { style: `background-color: ${s}` } : {}
89
89
  }), tn = cs.extend({ addAttributes() {
90
90
  var s;
91
- return { ...(s = this.parent) == null ? void 0 : s.call(this), backgroundColor: Pt() };
91
+ return { ...(s = this.parent) == null ? void 0 : s.call(this), backgroundColor: Nt() };
92
92
  } }), sn = ls.extend({ addAttributes() {
93
93
  var s;
94
- return { ...(s = this.parent) == null ? void 0 : s.call(this), backgroundColor: Pt() };
94
+ return { ...(s = this.parent) == null ? void 0 : s.call(this), backgroundColor: Nt() };
95
95
  } }), vt = () => ({ schema: fe, doc: { type: "doc", content: [{ type: "paragraph" }] } });
96
96
  function Me(s) {
97
97
  const e = (t) => {
@@ -155,10 +155,10 @@ const rn = (s) => {
155
155
  ...e ? [ss.configure({ document: e.document, field: e.field ?? "prosemirror" })] : [],
156
156
  ...e != null && e.awareness ? [ns.configure({ provider: { awareness: e.awareness }, user: e.user ?? {} })] : []
157
157
  ];
158
- function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i = "Link address", saveLabel: c = "Save", surface: d = "panel", source: u, documentId: w = (u == null ? void 0 : u.id) ?? "", nodeId: I = (u == null ? void 0 : u.id) ?? "", baseRevision: v = "", collaboration: C, assistant: k, assistantInstructions: A = {}, onChange: m, onAssistantCommit: U, onImageUpload: E, resolveImage: me, labels: qt = {} }) {
158
+ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i = "Link address", saveLabel: c = "Save", surface: d = "panel", source: h, documentId: w = (h == null ? void 0 : h.id) ?? "", nodeId: I = (h == null ? void 0 : h.id) ?? "", baseRevision: v = "", collaboration: C, assistant: k, assistantInstructions: A = {}, onChange: m, onAssistantCommit: U, onImageUpload: E, resolveImage: me, labels: qt = {} }) {
159
159
  var Je;
160
160
  if (k && !U) throw new Error("RichDocument assistant requires onAssistantCommit");
161
- const l = (a) => qt[a] ?? Js(a), Bt = js(() => Tt(t, C), [C, t]), [jt, _e] = T(!1), [qe, ge] = T(!1), [J, _] = T(null), [Be, ve] = T(!1), [Ht, se] = T(!1), [je, be] = T(""), [ne, R] = T(""), [Vt, H] = T(), [K, we] = T(), [He, ie] = T(!1), [$t, Ft] = T(0), x = pe((k == null ? void 0 : k.subscribe) ?? Ks, (k == null ? void 0 : k.getSnapshot) ?? (() => gt), (k == null ? void 0 : k.getSnapshot) ?? (() => gt)), ye = Ce(null), X = Ce(null), W = Ce(!1), ke = async (a, p) => {
161
+ const l = (a) => qt[a] ?? Js(a), Bt = js(() => Tt(t, C), [C, t]), [jt, _e] = T(!1), [qe, ge] = T(!1), [J, _] = T(null), [Be, ve] = T(!1), [Ht, se] = T(!1), [je, be] = T(""), [ne, R] = T(""), [Vt, H] = T(), [K, we] = T(), [He, ie] = T(!1), [$t, Ft] = T(0), x = pe((k == null ? void 0 : k.subscribe) ?? Ks, (k == null ? void 0 : k.getSnapshot) ?? (() => gt), (k == null ? void 0 : k.getSnapshot) ?? (() => gt)), ye = Ce(null), X = Ce(null), W = Ce(!1), ke = async (a, f) => {
162
162
  const g = X.current;
163
163
  if (!g || !E) return;
164
164
  let y;
@@ -168,7 +168,7 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
168
168
  return;
169
169
  }
170
170
  const D = { type: "image", attrs: { src: y.url, asset_id: y.assetId } };
171
- p !== void 0 ? g.chain().focus().insertContentAt(p, D).run() : g.chain().focus().setImage(D.attrs).run();
171
+ f !== void 0 ? g.chain().focus().insertContentAt(f, D).run() : g.chain().focus().setImage(D.attrs).run();
172
172
  }, o = vs({
173
173
  extensions: Bt,
174
174
  content: C ? void 0 : (s ?? vt()).doc,
@@ -177,30 +177,30 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
177
177
  immediatelyRender: !1,
178
178
  editorProps: {
179
179
  attributes: { class: d === "document" ? "docs-prose min-h-[520px] max-w-none px-0 pb-20 pt-5 outline-none" : "docs-prose min-h-[420px] max-w-none px-5 py-5 outline-none", "aria-label": n, role: e ? "textbox" : "document", "aria-multiline": e ? "true" : "false" },
180
- handlePaste: (a, p) => {
181
- var D, N, S;
182
- const g = [...((D = p.clipboardData) == null ? void 0 : D.files) ?? []].find((L) => L.type.startsWith("image/"));
180
+ handlePaste: (a, f) => {
181
+ var D, P, S;
182
+ const g = [...((D = f.clipboardData) == null ? void 0 : D.files) ?? []].find((L) => L.type.startsWith("image/"));
183
183
  if (g && E)
184
184
  return ke(g), !0;
185
- const y = ((N = p.clipboardData) == null ? void 0 : N.getData("text/plain")) ?? "";
185
+ const y = ((P = f.clipboardData) == null ? void 0 : P.getData("text/plain")) ?? "";
186
186
  return cn(y) ? ((S = X.current) == null || S.commands.insertContent(y, { contentType: "markdown" }), !0) : !1;
187
187
  },
188
- handleDrop: (a, p) => {
189
- var D, N;
190
- const g = [...((D = p.dataTransfer) == null ? void 0 : D.files) ?? []].find((S) => S.type.startsWith("image/"));
188
+ handleDrop: (a, f) => {
189
+ var D, P;
190
+ const g = [...((D = f.dataTransfer) == null ? void 0 : D.files) ?? []].find((S) => S.type.startsWith("image/"));
191
191
  if (!g || !E) return !1;
192
- const y = (N = a.posAtCoords({ left: p.clientX, top: p.clientY })) == null ? void 0 : N.pos;
192
+ const y = (P = a.posAtCoords({ left: f.clientX, top: f.clientY })) == null ? void 0 : P.pos;
193
193
  return ke(g, y), !0;
194
194
  },
195
- handleKeyDown: (a, p) => {
196
- if (!e || !(p.metaKey || p.ctrlKey) || p.key.toLowerCase() !== "k") return !1;
197
- p.preventDefault(), p.stopPropagation();
195
+ handleKeyDown: (a, f) => {
196
+ if (!e || !(f.metaKey || f.ctrlKey) || f.key.toLowerCase() !== "k") return !1;
197
+ f.preventDefault(), f.stopPropagation();
198
198
  const g = X.current;
199
199
  return be(String((g == null ? void 0 : g.getAttributes("link").href) ?? "https://")), se(!0), !0;
200
200
  }
201
201
  },
202
- onUpdate: ({ editor: a, transaction: p }) => {
203
- _e(a.state.doc.textBetween(Math.max(0, a.state.doc.content.size - 2), a.state.doc.content.size, " ").endsWith("/")), !W.current && !p.getMeta("docsAssetProjection") && (m == null || m(Me(a.getJSON())));
202
+ onUpdate: ({ editor: a, transaction: f }) => {
203
+ _e(a.state.doc.textBetween(Math.max(0, a.state.doc.content.size - 2), a.state.doc.content.size, " ").endsWith("/")), !W.current && !f.getMeta("docsAssetProjection") && (m == null || m(Me(a.getJSON())));
204
204
  }
205
205
  });
206
206
  Ie(() => (X.current = o, () => {
@@ -220,25 +220,25 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
220
220
  }
221
221
  }, [C, o, s]), Ie(() => {
222
222
  if (!o || !me) return;
223
- let a = !1, p;
223
+ let a = !1, f;
224
224
  const g = [];
225
225
  return o.state.doc.descendants((y, D) => {
226
- const N = y.type.name === "image" ? String(y.attrs.asset_id ?? "") : "";
227
- N && g.push({ assetId: N, position: D });
226
+ const P = y.type.name === "image" ? String(y.attrs.asset_id ?? "") : "";
227
+ P && g.push({ assetId: P, position: D });
228
228
  }), Promise.allSettled(g.map(async (y) => ({ ...y, ...await me(y.assetId) }))).then((y) => {
229
229
  if (a) return;
230
- let D = o.state.tr, N = Number.POSITIVE_INFINITY;
230
+ let D = o.state.tr, P = Number.POSITIVE_INFINITY;
231
231
  for (const S of y) {
232
232
  if (S.status !== "fulfilled" || !S.value.url) continue;
233
233
  const L = D.doc.nodeAt(S.value.position);
234
234
  if (!(!L || String(L.attrs.asset_id ?? "") !== S.value.assetId) && (D = D.setNodeMarkup(S.value.position, void 0, { ...L.attrs, src: S.value.url }), S.value.expiresAt !== void 0)) {
235
235
  const Ke = new Date(S.value.expiresAt).getTime();
236
- Number.isFinite(Ke) && (N = Math.min(N, Ke));
236
+ Number.isFinite(Ke) && (P = Math.min(P, Ke));
237
237
  }
238
238
  }
239
- D.docChanged && o.view.dispatch(D.setMeta("docsAssetProjection", !0).setMeta("addToHistory", !1)), Number.isFinite(N) && (p = setTimeout(() => Ft((S) => S + 1), Math.max(1e3, N - Date.now() - 3e4)));
239
+ D.docChanged && o.view.dispatch(D.setMeta("docsAssetProjection", !0).setMeta("addToHistory", !1)), Number.isFinite(P) && (f = setTimeout(() => Ft((S) => S + 1), Math.max(1e3, P - Date.now() - 3e4)));
240
240
  }), () => {
241
- a = !0, p && clearTimeout(p);
241
+ a = !0, f && clearTimeout(f);
242
242
  };
243
243
  }, [o, $t, me, s]);
244
244
  const re = (a) => {
@@ -251,46 +251,46 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
251
251
  a ? o.chain().focus().extendMarkRange("link").setLink({ href: a }).run() : o.chain().focus().unsetLink().run(), se(!1);
252
252
  }, Se = (a) => {
253
253
  if (!o || !k) return;
254
- const { from: p, to: g } = o.state.selection, y = o.state.doc.textBetween(p, g, `
254
+ const { from: f, to: g } = o.state.selection, y = o.state.doc.textBetween(f, g, `
255
255
  `), D = [];
256
- o.state.doc.nodesBetween(p, Math.max(p + 1, g), (S) => {
256
+ o.state.doc.nodesBetween(f, Math.max(f + 1, g), (S) => {
257
257
  if (S.type.name !== "image") return;
258
258
  const L = String(S.attrs.asset_id ?? "");
259
259
  L && D.push({ assetId: L });
260
260
  });
261
- const N = A[a] ?? `${a === "explain" ? "Explain" : a === "rewrite" ? "Rewrite" : "Continue"} the selected document content.`;
261
+ const P = A[a] ?? `${a === "explain" ? "Explain" : a === "rewrite" ? "Rewrite" : "Continue"} the selected document content.`;
262
262
  R(""), H(void 0), we(void 0), k.submit({
263
263
  version: 2,
264
264
  operation: a,
265
265
  documentId: w,
266
266
  nodeId: I,
267
267
  baseRevision: String(v),
268
- range: { from: p, to: g },
268
+ range: { from: f, to: g },
269
269
  selection: y,
270
- instruction: N,
270
+ instruction: P,
271
271
  context: `${o.getText({ blockSeparator: `
272
272
  ` }).slice(-12e3)}${D.length ? `
273
273
 
274
274
  [Selected images: ${D.map((S) => S.assetId).join(", ")}]` : ""}`,
275
- originalSlice: o.state.doc.slice(p, g).toJSON(),
275
+ originalSlice: o.state.doc.slice(f, g).toJSON(),
276
276
  images: D,
277
- source: u
277
+ source: h
278
278
  }).catch((S) => R(S instanceof Error ? S.message : String(S)));
279
279
  }, Kt = async () => {
280
280
  if (!o || !x.operation || !x.output) return;
281
- const a = Nt(o, { documentId: w, nodeId: I, baseRevision: String(v) }, x.operation);
281
+ const a = Pt(o, { documentId: w, nodeId: I, baseRevision: String(v) }, x.operation);
282
282
  if (a) {
283
283
  H(a), R(l("richDocument.aiConflict"));
284
284
  return;
285
285
  }
286
286
  W.current = !0;
287
- let p;
287
+ let f;
288
288
  try {
289
- p = Gs(o, { documentId: w, nodeId: I, baseRevision: String(v) }, x.operation, x.output);
289
+ f = Gs(o, { documentId: w, nodeId: I, baseRevision: String(v) }, x.operation, x.output);
290
290
  } finally {
291
291
  W.current = !1;
292
292
  }
293
- if (!p) {
293
+ if (!f) {
294
294
  H("invalid_slice"), R(l("richDocument.aiConflict"));
295
295
  return;
296
296
  }
@@ -298,9 +298,9 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
298
298
  ie(!0), o.setEditable(!1);
299
299
  try {
300
300
  const y = String(await U({ kind: "apply", value: g, nodeId: I, expectedRevision: String(v) }));
301
- R(""), H(void 0), we({ ...p, revision: y }), m == null || m(g, y);
301
+ R(""), H(void 0), we({ ...f, revision: y }), m == null || m(g, y);
302
302
  } catch {
303
- Ws(o, p.range, p.original, p.generated), R(l("richDocument.aiConflict"));
303
+ Ws(o, f.range, f.original, f.generated), R(l("richDocument.aiConflict"));
304
304
  } finally {
305
305
  o.setEditable(e), ie(!1);
306
306
  }
@@ -308,7 +308,7 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
308
308
  if (!(!o || !K)) {
309
309
  ie(!0), o.setEditable(!1);
310
310
  try {
311
- const a = await Ys(o, K, (p) => U({ kind: "rollback", value: p, nodeId: I, expectedRevision: K.revision }));
311
+ const a = await Ys(o, K, (f) => U({ kind: "rollback", value: f, nodeId: I, expectedRevision: K.revision }));
312
312
  if (!a) {
313
313
  H("selection"), R(l("richDocument.aiConflict"));
314
314
  return;
@@ -320,7 +320,7 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
320
320
  o.setEditable(e), ie(!1);
321
321
  }
322
322
  }
323
- }, b = (a, p, g, y) => /* @__PURE__ */ r(ae, { title: a, "aria-label": a, "aria-pressed": g, className: "aria-pressed:bg-surface-raised aria-pressed:text-ink", onClick: y, children: p }), $e = (a, p, g) => /* @__PURE__ */ r(ae, { title: p, "aria-label": p, "aria-expanded": J === a, onMouseDown: (y) => y.preventDefault(), onClick: () => _((y) => y === a ? null : a), children: g }), Wt = (a) => {
323
+ }, b = (a, f, g, y) => /* @__PURE__ */ r(ae, { title: a, "aria-label": a, "aria-pressed": g, className: "aria-pressed:bg-surface-raised aria-pressed:text-ink", onClick: y, children: f }), $e = (a, f, g) => /* @__PURE__ */ r(ae, { title: f, "aria-label": f, "aria-expanded": J === a, onMouseDown: (y) => y.preventDefault(), onClick: () => _((y) => y === a ? null : a), children: g }), Wt = (a) => {
324
324
  a(), ge(!1), o == null || o.commands.focus();
325
325
  }, Fe = o ? [
326
326
  [l("richDocument.heading1"), /* @__PURE__ */ r(Ye, { size: 15, "aria-hidden": !0 }, "h1"), () => o.chain().focus().toggleHeading({ level: 1 }).run()],
@@ -337,8 +337,8 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
337
337
  [l("richDocument.paragraph"), /* @__PURE__ */ r(rt, { size: 15, "aria-hidden": !0 }, "p"), () => o.chain().focus().setParagraph().run()],
338
338
  ...Fe.slice(0, 8)
339
339
  ] : [];
340
- return /* @__PURE__ */ h("div", { className: d === "document" ? "relative min-w-0" : "relative min-w-0 overflow-hidden rounded-xl border border-border bg-pure-white", "data-rich-document": !0, "data-document-id": w || void 0, "data-node-id": I || void 0, "data-base-revision": String(v) || void 0, "data-editable": e || void 0, "data-surface": d, onDragOver: (a) => E && a.preventDefault(), children: [
341
- e && o && /* @__PURE__ */ h(xe, { label: n, density: "compact", variant: d === "document" ? "bare" : "framed", className: d === "document" ? "sticky top-0 z-20 h-auto min-h-control-compact w-full flex-wrap border-b border-divider bg-pure-white py-1" : "h-auto min-h-control-compact flex-wrap rounded-none border-x-0 border-t-0", children: [
340
+ return /* @__PURE__ */ p("div", { className: d === "document" ? "relative min-w-0" : "relative min-w-0 overflow-hidden rounded-xl border border-border bg-pure-white", "data-rich-document": !0, "data-document-id": w || void 0, "data-node-id": I || void 0, "data-base-revision": String(v) || void 0, "data-editable": e || void 0, "data-surface": d, onDragOver: (a) => E && a.preventDefault(), children: [
341
+ e && o && /* @__PURE__ */ p(xe, { label: n, density: "compact", variant: d === "document" ? "bare" : "framed", className: d === "document" ? "sticky top-0 z-20 h-auto min-h-control-compact w-full flex-wrap border-b border-divider bg-pure-white py-1" : "h-auto min-h-control-compact flex-wrap rounded-none border-x-0 border-t-0", children: [
342
342
  b(l("richDocument.heading1"), /* @__PURE__ */ r(Ye, { size: 15, "aria-hidden": !0 }), o.isActive("heading", { level: 1 }), () => o.chain().focus().toggleHeading({ level: 1 }).run()),
343
343
  b(l("richDocument.heading2"), /* @__PURE__ */ r(Ge, { size: 15, "aria-hidden": !0 }), o.isActive("heading", { level: 2 }), () => o.chain().focus().toggleHeading({ level: 2 }).run()),
344
344
  b(l("richDocument.heading3"), /* @__PURE__ */ r(Qe, { size: 15, "aria-hidden": !0 }), o.isActive("heading", { level: 3 }), () => o.chain().focus().toggleHeading({ level: 3 }).run()),
@@ -365,18 +365,18 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
365
365
  ] }),
366
366
  E && /* @__PURE__ */ r(Re, { ref: ye, type: "file", accept: "image/png,image/jpeg,image/webp,image/gif", className: "sr-only", tabIndex: -1, onChange: (a) => {
367
367
  var g;
368
- const p = (g = a.target.files) == null ? void 0 : g[0];
369
- p && ke(p), a.currentTarget.value = "";
368
+ const f = (g = a.target.files) == null ? void 0 : g[0];
369
+ f && ke(f), a.currentTarget.value = "";
370
370
  } }),
371
- e && o && /* @__PURE__ */ r(ws, { editor: o, options: { placement: "left-start" }, className: "z-40", children: /* @__PURE__ */ h("div", { className: "relative flex items-start gap-1", children: [
372
- /* @__PURE__ */ r(Ue, { label: l("richDocument.insertBlock"), children: /* @__PURE__ */ r(P, { type: "button", "aria-label": l("richDocument.insertBlock"), "aria-expanded": qe, onMouseDown: (a) => a.preventDefault(), onClick: () => ge((a) => !a), className: "grid size-8 place-items-center rounded-control border border-border bg-pure-white text-graphite shadow-soft hover:-translate-y-px hover:bg-surface-hover hover:text-ink", children: /* @__PURE__ */ r(xs, { size: 16, "aria-hidden": !0 }) }) }),
373
- k && /* @__PURE__ */ r(Ue, { label: l("richDocument.aiContinue"), children: /* @__PURE__ */ r(P, { type: "button", "aria-label": l("richDocument.aiContinue"), onMouseDown: (a) => a.preventDefault(), onClick: () => Se("continue"), className: "grid size-8 place-items-center rounded-control border border-border bg-pure-white text-rust shadow-soft hover:-translate-y-px hover:bg-surface-hover", children: /* @__PURE__ */ r(ht, { size: 15, "aria-hidden": !0 }) }) }),
374
- qe && /* @__PURE__ */ h(oe, { label: l("richDocument.insertBlock"), className: "absolute left-10 top-0 grid w-52 gap-1 rounded-panel border border-border bg-surface-raised p-1 shadow-pop", children: [
375
- Fe.map(([a, p, g]) => /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ h(P, { type: "button", onMouseDown: (y) => y.preventDefault(), onClick: () => Wt(g), className: "flex min-h-10 items-center gap-2 rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", children: [
376
- p,
371
+ e && o && /* @__PURE__ */ r(ws, { editor: o, options: { placement: "left-start" }, className: "z-40", children: /* @__PURE__ */ p("div", { className: "relative flex items-start gap-1", children: [
372
+ /* @__PURE__ */ r(Ue, { label: l("richDocument.insertBlock"), children: /* @__PURE__ */ r(N, { type: "button", "aria-label": l("richDocument.insertBlock"), "aria-expanded": qe, onMouseDown: (a) => a.preventDefault(), onClick: () => ge((a) => !a), className: "grid size-8 place-items-center rounded-control border border-border bg-pure-white text-graphite shadow-soft hover:-translate-y-px hover:bg-surface-hover hover:text-ink", children: /* @__PURE__ */ r(xs, { size: 16, "aria-hidden": !0 }) }) }),
373
+ k && /* @__PURE__ */ r(Ue, { label: l("richDocument.aiContinue"), children: /* @__PURE__ */ r(N, { type: "button", "aria-label": l("richDocument.aiContinue"), onMouseDown: (a) => a.preventDefault(), onClick: () => Se("continue"), className: "grid size-8 place-items-center rounded-control border border-border bg-pure-white text-rust shadow-soft hover:-translate-y-px hover:bg-surface-hover", children: /* @__PURE__ */ r(ht, { size: 15, "aria-hidden": !0 }) }) }),
374
+ qe && /* @__PURE__ */ p(oe, { label: l("richDocument.insertBlock"), className: "absolute left-10 top-0 grid w-52 gap-1 rounded-panel border border-border bg-surface-raised p-1 shadow-pop", children: [
375
+ Fe.map(([a, f, g]) => /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ p(N, { type: "button", onMouseDown: (y) => y.preventDefault(), onClick: () => Wt(g), className: "flex min-h-10 items-center gap-2 rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", children: [
376
+ f,
377
377
  /* @__PURE__ */ r("span", { children: a })
378
378
  ] }) }, a)),
379
- E && /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ h(P, { type: "button", onMouseDown: (a) => a.preventDefault(), onClick: () => {
379
+ E && /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ p(N, { type: "button", onMouseDown: (a) => a.preventDefault(), onClick: () => {
380
380
  var a;
381
381
  ge(!1), (a = ye.current) == null || a.click();
382
382
  }, className: "flex min-h-10 items-center gap-2 rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", children: [
@@ -385,11 +385,11 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
385
385
  ] }) })
386
386
  ] })
387
387
  ] }) }),
388
- e && o && /* @__PURE__ */ r(Xe, { editor: o, pluginKey: "richTextSelectionMenu", shouldShow: ({ editor: a, from: p, to: g }) => p !== g && !(a.state.selection instanceof ze), options: { placement: "top" }, className: "z-40 shadow-pop", children: /* @__PURE__ */ h("div", { className: "relative", children: [
389
- /* @__PURE__ */ h(xe, { label: l("richDocument.formatSelection"), density: "compact", className: "max-w-[calc(100vw-2rem)] overflow-x-auto bg-surface-raised", children: [
390
- $e("block", l("richDocument.paragraphStyle"), /* @__PURE__ */ h(Ee, { children: [
388
+ e && o && /* @__PURE__ */ r(Xe, { editor: o, pluginKey: "richTextSelectionMenu", shouldShow: ({ editor: a, from: f, to: g }) => f !== g && !(a.state.selection instanceof ze), options: { placement: "top" }, className: "z-40 shadow-pop", children: /* @__PURE__ */ p("div", { className: "relative", children: [
389
+ /* @__PURE__ */ p(xe, { label: l("richDocument.formatSelection"), density: "compact", className: "max-w-[calc(100vw-2rem)] overflow-x-auto bg-surface-raised", children: [
390
+ $e("block", l("richDocument.paragraphStyle"), /* @__PURE__ */ p(Ee, { children: [
391
391
  /* @__PURE__ */ r(rt, { size: 15, "aria-hidden": !0 }),
392
- /* @__PURE__ */ r(Ns, { size: 11, "aria-hidden": !0 })
392
+ /* @__PURE__ */ r(Ps, { size: 11, "aria-hidden": !0 })
393
393
  ] })),
394
394
  $e("align", l("richDocument.alignment"), /* @__PURE__ */ r(mt, { size: 15, "aria-hidden": !0 })),
395
395
  /* @__PURE__ */ r(V, {}),
@@ -398,38 +398,38 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
398
398
  b(l("richDocument.underline"), /* @__PURE__ */ r(ct, { size: 15, "aria-hidden": !0 }), o.isActive("underline"), () => o.chain().focus().toggleUnderline().run()),
399
399
  b(l("richDocument.strike"), /* @__PURE__ */ r(lt, { size: 15, "aria-hidden": !0 }), o.isActive("strike"), () => o.chain().focus().toggleStrike().run()),
400
400
  b(l("richDocument.code"), /* @__PURE__ */ r(dt, { size: 15, "aria-hidden": !0 }), o.isActive("code"), () => o.chain().focus().toggleCode().run()),
401
- /* @__PURE__ */ h(We, { title: l("richDocument.colors"), open: J === "color", onOpenChange: (a) => _(a ? "color" : null), side: "bottom", align: "end", trigger: /* @__PURE__ */ r(ae, { title: l("richDocument.colors"), "aria-label": l("richDocument.colors"), "aria-expanded": J === "color", onMouseDown: (a) => a.preventDefault(), children: /* @__PURE__ */ r(ft, { size: 15, "aria-hidden": !0 }) }), children: [
402
- /* @__PURE__ */ r(Ne, { label: l("richDocument.textColor"), values: en, onChoose: (a) => {
401
+ /* @__PURE__ */ p(We, { title: l("richDocument.colors"), open: J === "color", onOpenChange: (a) => _(a ? "color" : null), side: "bottom", align: "end", trigger: /* @__PURE__ */ r(ae, { title: l("richDocument.colors"), "aria-label": l("richDocument.colors"), "aria-expanded": J === "color", onMouseDown: (a) => a.preventDefault(), children: /* @__PURE__ */ r(ft, { size: 15, "aria-hidden": !0 }) }), children: [
402
+ /* @__PURE__ */ r(Pe, { label: l("richDocument.textColor"), values: en, onChoose: (a) => {
403
403
  o.chain().focus().setColor(a).run(), _(null);
404
404
  } }),
405
- /* @__PURE__ */ r(Ne, { label: l("richDocument.backgroundColor"), values: de, onChoose: (a) => {
405
+ /* @__PURE__ */ r(Pe, { label: l("richDocument.backgroundColor"), values: de, onChoose: (a) => {
406
406
  o.chain().focus().setBackgroundColor(a).run(), _(null);
407
407
  } }),
408
- /* @__PURE__ */ r(P, { type: "button", onMouseDown: (a) => a.preventDefault(), onClick: () => {
408
+ /* @__PURE__ */ r(N, { type: "button", onMouseDown: (a) => a.preventDefault(), onClick: () => {
409
409
  o.chain().focus().unsetColor().unsetBackgroundColor().run(), _(null);
410
410
  }, className: "mt-2 min-h-9 w-full rounded-control text-caption text-graphite hover:bg-surface-hover hover:text-ink", children: l("richDocument.resetColors") })
411
411
  ] }),
412
412
  b(l("richDocument.link"), /* @__PURE__ */ r(ut, { size: 15, "aria-hidden": !0 }), o.isActive("link"), Ve),
413
- k && /* @__PURE__ */ h(Ee, { children: [
413
+ k && /* @__PURE__ */ p(Ee, { children: [
414
414
  /* @__PURE__ */ r(V, {}),
415
415
  b(l("richDocument.aiExplain"), /* @__PURE__ */ r(ht, { size: 15, "aria-hidden": !0 }), !1, () => Se("explain")),
416
- b(l("richDocument.aiRewrite"), /* @__PURE__ */ r(Ps, { size: 15, "aria-hidden": !0 }), !1, () => Se("rewrite"))
416
+ b(l("richDocument.aiRewrite"), /* @__PURE__ */ r(Ns, { size: 15, "aria-hidden": !0 }), !1, () => Se("rewrite"))
417
417
  ] })
418
418
  ] }),
419
- J === "block" && /* @__PURE__ */ r(oe, { label: l("richDocument.paragraphStyle"), className: "af-layer-overlay absolute left-0 top-full mt-1 grid w-48 gap-1 rounded-panel border border-border bg-surface-raised p-1 shadow-pop", children: Yt.map(([a, p, g]) => /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ h(P, { type: "button", onMouseDown: (y) => y.preventDefault(), onClick: () => {
419
+ J === "block" && /* @__PURE__ */ r(oe, { label: l("richDocument.paragraphStyle"), className: "af-layer-overlay absolute left-0 top-full mt-1 grid w-48 gap-1 rounded-panel border border-border bg-surface-raised p-1 shadow-pop", children: Yt.map(([a, f, g]) => /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ p(N, { type: "button", onMouseDown: (y) => y.preventDefault(), onClick: () => {
420
420
  g(), _(null);
421
421
  }, className: "flex min-h-10 items-center gap-2 rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", children: [
422
- p,
422
+ f,
423
423
  /* @__PURE__ */ r("span", { children: a })
424
424
  ] }) }, a)) }),
425
- J === "align" && /* @__PURE__ */ r(oe, { label: l("richDocument.alignment"), className: "af-layer-overlay absolute left-9 top-full mt-1 grid w-40 gap-1 rounded-panel border border-border bg-surface-raised p-1 shadow-pop", children: [["left", l("richDocument.alignLeft"), /* @__PURE__ */ r(mt, { size: 15, "aria-hidden": !0 }, "left")], ["center", l("richDocument.alignCenter"), /* @__PURE__ */ r(Ds, { size: 15, "aria-hidden": !0 }, "center")], ["right", l("richDocument.alignRight"), /* @__PURE__ */ r(Cs, { size: 15, "aria-hidden": !0 }, "right")]].map(([a, p, g]) => /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ h(P, { type: "button", onMouseDown: (y) => y.preventDefault(), onClick: () => {
425
+ J === "align" && /* @__PURE__ */ r(oe, { label: l("richDocument.alignment"), className: "af-layer-overlay absolute left-9 top-full mt-1 grid w-40 gap-1 rounded-panel border border-border bg-surface-raised p-1 shadow-pop", children: [["left", l("richDocument.alignLeft"), /* @__PURE__ */ r(mt, { size: 15, "aria-hidden": !0 }, "left")], ["center", l("richDocument.alignCenter"), /* @__PURE__ */ r(Ds, { size: 15, "aria-hidden": !0 }, "center")], ["right", l("richDocument.alignRight"), /* @__PURE__ */ r(Cs, { size: 15, "aria-hidden": !0 }, "right")]].map(([a, f, g]) => /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ p(N, { type: "button", onMouseDown: (y) => y.preventDefault(), onClick: () => {
426
426
  o.chain().focus().setTextAlign(String(a)).run(), _(null);
427
427
  }, className: "flex min-h-10 items-center gap-2 rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", children: [
428
428
  g,
429
- /* @__PURE__ */ r("span", { children: p })
429
+ /* @__PURE__ */ r("span", { children: f })
430
430
  ] }) }, String(a))) })
431
431
  ] }) }),
432
- e && o && /* @__PURE__ */ r(Xe, { editor: o, pluginKey: "richTableMenu", shouldShow: ({ editor: a, from: p, to: g }) => (p === g || a.state.selection instanceof ze) && rn(a), options: { placement: "top" }, className: "z-40 shadow-pop", children: /* @__PURE__ */ r("div", { className: "relative", children: /* @__PURE__ */ h(xe, { label: l("richDocument.tableActions"), density: "compact", className: "max-w-[calc(100vw-2rem)] overflow-x-auto bg-surface-raised", children: [
432
+ e && o && /* @__PURE__ */ r(Xe, { editor: o, pluginKey: "richTableMenu", shouldShow: ({ editor: a, from: f, to: g }) => (f === g || a.state.selection instanceof ze) && rn(a), options: { placement: "top" }, className: "z-40 shadow-pop", children: /* @__PURE__ */ r("div", { className: "relative", children: /* @__PURE__ */ p(xe, { label: l("richDocument.tableActions"), density: "compact", className: "max-w-[calc(100vw-2rem)] overflow-x-auto bg-surface-raised", children: [
433
433
  b(l("richDocument.addRowBefore"), /* @__PURE__ */ r(Ts, { size: 15, "aria-hidden": !0 }), !1, () => o.chain().focus().addRowBefore().run()),
434
434
  b(l("richDocument.addRowAfter"), /* @__PURE__ */ r(As, { size: 15, "aria-hidden": !0 }), !1, () => o.chain().focus().addRowAfter().run()),
435
435
  b(l("richDocument.deleteRow"), /* @__PURE__ */ r(Es, { size: 15, "aria-hidden": !0 }), !1, () => o.chain().focus().deleteRow().run()),
@@ -440,11 +440,11 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
440
440
  /* @__PURE__ */ r(V, {}),
441
441
  b(l("richDocument.mergeCells"), /* @__PURE__ */ r(Ls, { size: 15, "aria-hidden": !0 }), !1, () => o.chain().focus().mergeCells().run()),
442
442
  b(l("richDocument.splitCell"), /* @__PURE__ */ r(Ms, { size: 15, "aria-hidden": !0 }), !1, () => o.chain().focus().splitCell().run()),
443
- /* @__PURE__ */ h(We, { title: l("richDocument.cellBackgroundColor"), open: Be, onOpenChange: ve, side: "bottom", align: "end", trigger: /* @__PURE__ */ r(ae, { title: l("richDocument.cellBackgroundColor"), "aria-label": l("richDocument.cellBackgroundColor"), "aria-expanded": Be, onMouseDown: (a) => a.preventDefault(), children: /* @__PURE__ */ r(ft, { size: 15, "aria-hidden": !0 }) }), children: [
444
- /* @__PURE__ */ r(Ne, { label: l("richDocument.cellBackgroundColor"), values: de, onChoose: (a) => {
443
+ /* @__PURE__ */ p(We, { title: l("richDocument.cellBackgroundColor"), open: Be, onOpenChange: ve, side: "bottom", align: "end", trigger: /* @__PURE__ */ r(ae, { title: l("richDocument.cellBackgroundColor"), "aria-label": l("richDocument.cellBackgroundColor"), "aria-expanded": Be, onMouseDown: (a) => a.preventDefault(), children: /* @__PURE__ */ r(ft, { size: 15, "aria-hidden": !0 }) }), children: [
444
+ /* @__PURE__ */ r(Pe, { label: l("richDocument.cellBackgroundColor"), values: de, onChoose: (a) => {
445
445
  o.chain().focus().setCellAttribute("backgroundColor", a).run(), ve(!1);
446
446
  } }),
447
- /* @__PURE__ */ r(P, { type: "button", onMouseDown: (a) => a.preventDefault(), onClick: () => {
447
+ /* @__PURE__ */ r(N, { type: "button", onMouseDown: (a) => a.preventDefault(), onClick: () => {
448
448
  o.chain().focus().setCellAttribute("backgroundColor", null).run(), ve(!1);
449
449
  }, className: "mt-2 min-h-9 w-full rounded-control text-caption text-graphite hover:bg-surface-hover hover:text-ink", children: l("richDocument.resetCellBackground") })
450
450
  ] }),
@@ -453,38 +453,38 @@ function an({ value: s, editable: e, placeholder: t, ariaLabel: n, linkLabel: i
453
453
  ] }) }) }),
454
454
  /* @__PURE__ */ r(bs, { editor: o }),
455
455
  k && !x.operation && ne && /* @__PURE__ */ r("div", { role: "alert", className: "m-4 text-caption text-danger", children: ne }),
456
- k && x.operation && /* @__PURE__ */ h("aside", { "data-testid": "document-assistant-operation", "data-run-id": x.runId, "data-status": x.status, "data-document-id": x.operation.documentId, "data-node-id": x.operation.nodeId, "data-base-revision": x.operation.baseRevision, "data-error-code": Vt, className: "m-4 space-y-3 rounded-panel border border-border bg-surface-muted p-4", "aria-live": "polite", children: [
457
- /* @__PURE__ */ h("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
456
+ k && x.operation && /* @__PURE__ */ p("aside", { "data-testid": "document-assistant-operation", "data-run-id": x.runId, "data-status": x.status, "data-document-id": x.operation.documentId, "data-node-id": x.operation.nodeId, "data-base-revision": x.operation.baseRevision, "data-error-code": Vt, className: "m-4 space-y-3 rounded-panel border border-border bg-surface-muted p-4", "aria-live": "polite", children: [
457
+ /* @__PURE__ */ p("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
458
458
  /* @__PURE__ */ r("strong", { className: "font-sohne text-body-sm text-ink", children: l(`richDocument.ai.${x.operation.operation}`) }),
459
459
  /* @__PURE__ */ r("span", { className: "text-caption text-graphite", children: x.status })
460
460
  ] }),
461
461
  x.output && /* @__PURE__ */ r("div", { "data-testid": "document-assistant-output", className: "whitespace-pre-wrap text-body-sm text-ink", children: x.output }),
462
- /* @__PURE__ */ h("div", { className: "flex flex-wrap gap-2", children: [
462
+ /* @__PURE__ */ p("div", { className: "flex flex-wrap gap-2", children: [
463
463
  x.status === "waiting_for_input" && /* @__PURE__ */ r(z, { size: "compact", onClick: () => void k.resolvePending().catch((a) => R(a instanceof Error ? a.message : String(a))), children: l("richDocument.aiResume") }),
464
464
  x.status === "completed" && x.operation.operation !== "explain" && x.output && !K && /* @__PURE__ */ r(z, { size: "compact", disabled: He, onClick: () => void Kt(), children: l("richDocument.aiApply") }),
465
465
  K && /* @__PURE__ */ r(z, { size: "compact", variant: "secondary", disabled: He, onClick: () => void Xt(), children: l("richDocument.aiRollback") })
466
466
  ] }),
467
467
  (ne || x.error) && /* @__PURE__ */ r("div", { role: "alert", className: "text-caption text-danger", children: ne || ((Je = x.error) == null ? void 0 : Je.message) })
468
468
  ] }),
469
- e && jt && o && /* @__PURE__ */ h(oe, { label: l("richDocument.slashCommands"), className: "absolute left-0 top-12 z-30 grid min-w-44 gap-1 rounded-panel border border-border bg-surface-raised p-1 shadow-pop", children: [
470
- /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ r(P, { className: "h-row-default rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", onClick: () => re(() => o.chain().deleteRange({ from: o.state.selection.from - 1, to: o.state.selection.from }).toggleHeading({ level: 2 }).run()), children: l("richDocument.heading") }) }),
471
- /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ r(P, { className: "h-row-default rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", onClick: () => re(() => o.chain().deleteRange({ from: o.state.selection.from - 1, to: o.state.selection.from }).toggleTaskList().run()), children: l("richDocument.taskList") }) }),
472
- /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ r(P, { className: "h-row-default rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", onClick: () => re(() => o.chain().deleteRange({ from: o.state.selection.from - 1, to: o.state.selection.from }).wrapIn("callout").run()), children: l("richDocument.callout") }) }),
473
- /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ r(P, { className: "h-row-default rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", onClick: () => re(() => o.chain().deleteRange({ from: o.state.selection.from - 1, to: o.state.selection.from }).insertTable({ rows: 3, cols: 3, withHeaderRow: !0 }).run()), children: l("richDocument.table") }) })
469
+ e && jt && o && /* @__PURE__ */ p(oe, { label: l("richDocument.slashCommands"), className: "absolute left-0 top-12 z-30 grid min-w-44 gap-1 rounded-panel border border-border bg-surface-raised p-1 shadow-pop", children: [
470
+ /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ r(N, { className: "h-row-default rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", onClick: () => re(() => o.chain().deleteRange({ from: o.state.selection.from - 1, to: o.state.selection.from }).toggleHeading({ level: 2 }).run()), children: l("richDocument.heading") }) }),
471
+ /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ r(N, { className: "h-row-default rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", onClick: () => re(() => o.chain().deleteRange({ from: o.state.selection.from - 1, to: o.state.selection.from }).toggleTaskList().run()), children: l("richDocument.taskList") }) }),
472
+ /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ r(N, { className: "h-row-default rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", onClick: () => re(() => o.chain().deleteRange({ from: o.state.selection.from - 1, to: o.state.selection.from }).wrapIn("callout").run()), children: l("richDocument.callout") }) }),
473
+ /* @__PURE__ */ r(M, { asChild: !0, children: /* @__PURE__ */ r(N, { className: "h-row-default rounded-control px-3 text-left font-sohne text-body-sm text-ink hover:bg-surface-hover", onClick: () => re(() => o.chain().deleteRange({ from: o.state.selection.from - 1, to: o.state.selection.from }).insertTable({ rows: 3, cols: 3, withHeaderRow: !0 }).run()), children: l("richDocument.table") }) })
474
474
  ] }),
475
- /* @__PURE__ */ r(ks, { open: Ht, onClose: () => se(!1), title: i, closeLabel: l("common.close"), children: /* @__PURE__ */ h("div", { className: "space-y-4", children: [
475
+ /* @__PURE__ */ r(ks, { open: Ht, onClose: () => se(!1), title: i, closeLabel: l("common.close"), children: /* @__PURE__ */ p("div", { className: "space-y-4", children: [
476
476
  /* @__PURE__ */ r(Re, { autoFocus: !0, type: "url", "aria-label": i, value: je, onChange: (a) => be(a.target.value), placeholder: "https://" }),
477
- /* @__PURE__ */ r("div", { className: "flex justify-end", children: /* @__PURE__ */ r(P, { type: "button", onClick: Jt, className: "min-h-11 rounded-full bg-ink px-5 font-sohne text-caption text-pure-white", children: c }) })
477
+ /* @__PURE__ */ r("div", { className: "flex justify-end", children: /* @__PURE__ */ r(N, { type: "button", onClick: Jt, className: "min-h-11 rounded-full bg-ink px-5 font-sohne text-caption text-pure-white", children: c }) })
478
478
  ] }) })
479
479
  ] });
480
480
  }
481
481
  const cn = (s) => /(^|\n)(#{1,3} |[-*+] |\d+\. |> |```|---(?:\n|$)|- \[[ xX]\] )|\|.+\|\n\|(?:\s*:?-+:?\s*\|)+|\*\*[^*]+\*\*|~~[^~]+~~|`[^`]+`|\[[^\]]+\]\(https?:\/\/[^)]+\)/m.test(s);
482
- function Ne({ label: s, values: e, onChoose: t }) {
483
- return /* @__PURE__ */ h("fieldset", { className: "mb-2", children: [
482
+ function Pe({ label: s, values: e, onChoose: t }) {
483
+ return /* @__PURE__ */ p("fieldset", { className: "mb-2", children: [
484
484
  /* @__PURE__ */ r("legend", { className: "mb-1 font-sohne text-caption text-graphite", children: s }),
485
485
  /* @__PURE__ */ r("div", { className: "flex flex-wrap gap-1", children: e.map((n, i) => {
486
486
  const c = `${s} ${i + 1}`;
487
- return /* @__PURE__ */ r(Ue, { label: c, children: /* @__PURE__ */ r(P, { type: "button", "aria-label": c, onMouseDown: (d) => d.preventDefault(), onClick: () => t(n), className: "size-8 rounded-control border border-border transition-transform hover:-translate-y-px hover:ring-2 hover:ring-rust/35", style: { backgroundColor: n } }) }, n);
487
+ return /* @__PURE__ */ r(Ue, { label: c, children: /* @__PURE__ */ r(N, { type: "button", "aria-label": c, onMouseDown: (d) => d.preventDefault(), onClick: () => t(n), className: "size-8 rounded-control border border-border transition-transform hover:-translate-y-px hover:ring-2 hover:ring-rust/35", style: { backgroundColor: n } }) }, n);
488
488
  }) })
489
489
  ] });
490
490
  }
@@ -504,61 +504,61 @@ const bt = (s, e) => {
504
504
  };
505
505
  class wi {
506
506
  constructor(e, t = "") {
507
- f(this, "state");
508
- f(this, "listeners", /* @__PURE__ */ new Set());
509
- f(this, "generation", 0);
510
- f(this, "getSnapshot", () => this.state);
511
- f(this, "subscribe", (e) => (this.listeners.add(e), () => this.listeners.delete(e)));
512
- f(this, "createSpace", (e) => this.run(async () => ({ spaces: [await this.transport.createSpace(e), ...this.state.spaces] })));
513
- f(this, "updateSpace", (e) => this.run(async () => {
507
+ u(this, "state");
508
+ u(this, "listeners", /* @__PURE__ */ new Set());
509
+ u(this, "generation", 0);
510
+ u(this, "getSnapshot", () => this.state);
511
+ u(this, "subscribe", (e) => (this.listeners.add(e), () => this.listeners.delete(e)));
512
+ u(this, "createSpace", (e) => this.run(async () => ({ spaces: [await this.transport.createSpace(e), ...this.state.spaces] })));
513
+ u(this, "updateSpace", (e) => this.run(async () => {
514
514
  const t = await this.transport.updateSpace(e);
515
515
  return { spaces: this.state.spaces.map((n) => n.id === t.id ? t : n) };
516
516
  }));
517
- f(this, "archiveSpace", (e) => this.run(async () => {
517
+ u(this, "archiveSpace", (e) => this.run(async () => {
518
518
  const t = await this.transport.archiveSpace(e);
519
519
  return { spacePermissions: void 0, nodePermissions: void 0, spaces: this.state.spaces.map((n) => n.id === t.id ? t : n) };
520
520
  }));
521
- f(this, "leaveSpace", (e) => this.run(async () => (await this.transport.leaveSpace(e), { spacePermissions: void 0, nodePermissions: void 0, spaces: this.state.spaces.filter((t) => t.id !== e.spaceId) })));
522
- f(this, "createNode", (e) => this.run(async () => {
521
+ u(this, "leaveSpace", (e) => this.run(async () => (await this.transport.leaveSpace(e), { spacePermissions: void 0, nodePermissions: void 0, spaces: this.state.spaces.filter((t) => t.id !== e.spaceId) })));
522
+ u(this, "createNode", (e) => this.run(async () => {
523
523
  const t = await this.transport.createNode(e);
524
524
  return { nodes: [...this.state.nodes, t], documents: t.kind === G.NodeKind.DOCUMENT ? [...this.state.documents, t] : this.state.documents };
525
525
  }));
526
- f(this, "updateNode", (e) => this.run(async () => {
526
+ u(this, "updateNode", (e) => this.run(async () => {
527
527
  const t = await this.transport.updateNode(e);
528
528
  return this.replaceNode(t);
529
529
  }));
530
- f(this, "moveNode", (e) => this.run(async () => {
530
+ u(this, "moveNode", (e) => this.run(async () => {
531
531
  const t = await this.transport.moveNode(e);
532
532
  return this.replaceNode(t);
533
533
  }));
534
- f(this, "deleteNode", (e) => this.run(async () => {
534
+ u(this, "deleteNode", (e) => this.run(async () => {
535
535
  const t = this.state.documents.find((n) => n.id === e.nodeId) ?? this.state.nodes.find((n) => n.id === e.nodeId);
536
536
  return await this.transport.deleteNode(e), { nodes: this.state.nodes.filter((n) => n.id !== e.nodeId), documents: this.state.documents.filter((n) => n.id !== e.nodeId), trash: t ? [...this.state.trash, t] : this.state.trash };
537
537
  }));
538
- f(this, "restoreNode", (e) => this.run(async () => {
538
+ u(this, "restoreNode", (e) => this.run(async () => {
539
539
  const t = await this.transport.restoreNode(e);
540
540
  return { nodes: [...this.state.nodes, t], documents: t.kind === G.NodeKind.DOCUMENT ? [...this.state.documents, t] : this.state.documents, trash: this.state.trash.filter((n) => n.id !== t.id) };
541
541
  }));
542
- f(this, "restoreRevision", async (e) => {
542
+ u(this, "restoreRevision", async (e) => {
543
543
  const t = e.nodeId;
544
544
  if (!t) throw new Error("node ID is required");
545
545
  const n = this.generation, i = await this.transport.restoreRevision(e);
546
546
  return n === this.generation && await this.openNode(t), i;
547
547
  });
548
- f(this, "setAcl", (e) => this.run(async () => {
548
+ u(this, "setAcl", (e) => this.run(async () => {
549
549
  const t = await this.transport.setAcl(e);
550
550
  return { spacePermissions: void 0, nodePermissions: void 0, acl: [...this.state.acl.filter((n) => n.id !== t.id), t] };
551
551
  }));
552
- f(this, "revokeAcl", (e) => this.run(async () => {
552
+ u(this, "revokeAcl", (e) => this.run(async () => {
553
553
  await this.transport.revokeAcl(e);
554
554
  const t = bt(e.resource, e.spaceId ?? "");
555
555
  return { spacePermissions: void 0, nodePermissions: void 0, acl: this.state.acl.filter((n) => n.subjectId !== e.subjectId || bt(n.resource, n.spaceId) !== t) };
556
556
  }));
557
- f(this, "createInvite", (e) => this.run(async () => {
557
+ u(this, "createInvite", (e) => this.run(async () => {
558
558
  const t = await this.transport.createInvite(e);
559
559
  return { invites: [...this.state.invites, t] };
560
560
  }));
561
- f(this, "revokeInvite", (e) => this.run(async () => (await this.transport.revokeInvite(e), { invites: this.state.invites.filter((t) => t.id !== e.inviteId) })));
561
+ u(this, "revokeInvite", (e) => this.run(async () => (await this.transport.revokeInvite(e), { invites: this.state.invites.filter((t) => t.id !== e.inviteId) })));
562
562
  this.transport = e, this.state = { ...wt, scope: t };
563
563
  }
564
564
  setScope(e) {
@@ -595,7 +595,7 @@ class wi {
595
595
  }), await this.run(async () => {
596
596
  const i = await this.transport.getResourcePermissions({ spaceId: e });
597
597
  if (t !== this.generation) return {};
598
- const [c, d, u] = await Promise.all([
598
+ const [c, d, h] = await Promise.all([
599
599
  this.transport.listChildren({ spaceId: e, pageSize: 50 }),
600
600
  this.transport.listDocuments({ spaceId: e, pageSize: 50 }),
601
601
  this.transport.listTrash({ spaceId: e, pageSize: 50 })
@@ -604,8 +604,8 @@ class wi {
604
604
  spacePermissions: i,
605
605
  nodes: c.nodes,
606
606
  documents: d.nodes,
607
- trash: u.nodes,
608
- nextPageTokens: { ...this.state.nextPageTokens, nodes: c.nextPageToken, documents: d.nextPageToken, trash: u.nextPageToken }
607
+ trash: h.nodes,
608
+ nextPageTokens: { ...this.state.nextPageTokens, nodes: c.nextPageToken, documents: d.nextPageToken, trash: h.nextPageToken }
609
609
  };
610
610
  }), t === this.generation && ((n = this.state.spacePermissions) != null && n.manage))
611
611
  try {
@@ -638,12 +638,12 @@ class wi {
638
638
  this.transport.getNode({ nodeId: e }),
639
639
  this.transport.listRevisions({ nodeId: e, pageSize: 50 }),
640
640
  this.transport.getResourcePermissions({ resource: { target: { case: "nodeId", value: e } } })
641
- ]), d = i.revisions.find((w) => w.number === n.revision), u = d && t === this.generation ? await this.transport.getRevisionIndexStatus({ nodeId: e, revisionId: d.id }) : void 0;
641
+ ]), d = i.revisions.find((w) => w.number === n.revision), h = d && t === this.generation ? await this.transport.getRevisionIndexStatus({ nodeId: e, revisionId: d.id }) : void 0;
642
642
  return {
643
643
  selectedNode: n,
644
644
  nodePermissions: c,
645
645
  revisions: i.revisions,
646
- index: u,
646
+ index: h,
647
647
  nextPageTokens: { ...this.state.nextPageTokens, revisions: i.nextPageToken }
648
648
  };
649
649
  });
@@ -655,47 +655,47 @@ class wi {
655
655
  const n = this.state.selectedSpaceId, i = (c = this.state.selectedNode) == null ? void 0 : c.id;
656
656
  return this.run(async () => {
657
657
  const d = { spaceId: n, nodeId: i, pageToken: t, pageSize: 50 };
658
- let u, w;
658
+ let h, w;
659
659
  switch (e) {
660
660
  case "spaces": {
661
661
  const v = await this.transport.listSpaces(d);
662
- u = v.spaces, w = v.nextPageToken;
662
+ h = v.spaces, w = v.nextPageToken;
663
663
  break;
664
664
  }
665
665
  case "nodes": {
666
666
  const v = await this.transport.listChildren(d);
667
- u = v.nodes, w = v.nextPageToken;
667
+ h = v.nodes, w = v.nextPageToken;
668
668
  break;
669
669
  }
670
670
  case "documents": {
671
671
  const v = await this.transport.listDocuments(d);
672
- u = v.nodes, w = v.nextPageToken;
672
+ h = v.nodes, w = v.nextPageToken;
673
673
  break;
674
674
  }
675
675
  case "trash": {
676
676
  const v = await this.transport.listTrash(d);
677
- u = v.nodes, w = v.nextPageToken;
677
+ h = v.nodes, w = v.nextPageToken;
678
678
  break;
679
679
  }
680
680
  case "revisions": {
681
681
  const v = await this.transport.listRevisions(d);
682
- u = v.revisions, w = v.nextPageToken;
682
+ h = v.revisions, w = v.nextPageToken;
683
683
  break;
684
684
  }
685
685
  case "acl": {
686
686
  const v = await this.transport.listAcl(d);
687
- u = v.entries, w = v.nextPageToken;
687
+ h = v.entries, w = v.nextPageToken;
688
688
  break;
689
689
  }
690
690
  case "invites": {
691
691
  const v = await this.transport.listInvites(d);
692
- u = v.invites, w = v.nextPageToken;
692
+ h = v.invites, w = v.nextPageToken;
693
693
  break;
694
694
  }
695
695
  }
696
696
  if (w === t) throw new Error("server repeated a page token");
697
697
  const I = new Map(this.state[e].map((v) => [v.id, v]));
698
- for (const v of u) I.set(v.id, v);
698
+ for (const v of h) I.set(v.id, v);
699
699
  return { [e]: [...I.values()], nextPageTokens: { ...this.state.nextPageTokens, [e]: w } };
700
700
  });
701
701
  }
@@ -706,8 +706,8 @@ class wi {
706
706
  const d = await this.transport.saveRevision({ nodeId: i.id, expectedRevision: i.revision, schema: e, contentJson: t, name: n });
707
707
  return c === this.generation && await this.openNode(i.id), d;
708
708
  } catch (d) {
709
- const u = d instanceof Error ? d : new Error(String(d));
710
- throw c === this.generation && this.update({ loading: !1, conflict: u, error: void 0, spacePermissions: void 0, nodePermissions: void 0 }), u;
709
+ const h = d instanceof Error ? d : new Error(String(d));
710
+ throw c === this.generation && this.update({ loading: !1, conflict: h, error: void 0, spacePermissions: void 0, nodePermissions: void 0 }), h;
711
711
  }
712
712
  }
713
713
  async saveAsCopy(e) {
@@ -715,10 +715,10 @@ class wi {
715
715
  if (!t || !n) throw new Error("a selected space and local draft are required");
716
716
  const i = this.state.selectedNode, c = this.state.scope;
717
717
  return this.run(async () => {
718
- var u;
718
+ var h;
719
719
  const d = await this.transport.createNode({
720
720
  node: { id: crypto.randomUUID(), spaceId: t, parentId: (i == null ? void 0 : i.parentId) ?? "", kind: G.NodeKind.DOCUMENT, title: e, slug: "", locale: (i == null ? void 0 : i.locale) ?? "" },
721
- expectedTreeVersion: ((u = this.state.spaces.find((w) => w.id === t)) == null ? void 0 : u.treeVersion) ?? 0n,
721
+ expectedTreeVersion: ((h = this.state.spaces.find((w) => w.id === t)) == null ? void 0 : h.treeVersion) ?? 0n,
722
722
  commandId: crypto.randomUUID()
723
723
  });
724
724
  if (c !== this.state.scope) throw new Error("account scope changed during save");
@@ -768,58 +768,58 @@ function yi({ controller: s }) {
768
768
  const e = dn(s), [t, n] = T(""), [i, c] = T("1.0.0"), d = e.documents.filter((m) => {
769
769
  var U;
770
770
  return m.id !== ((U = e.selectedNode) == null ? void 0 : U.id);
771
- }), u = d.find((m) => m.id === t) ?? d[0];
772
- return e.error && !e.spaces.length ? /* @__PURE__ */ r(j, { title: "Docs unavailable", description: e.error.message, action: { label: "Retry", onClick: () => void s.refresh() } }) : /* @__PURE__ */ h("section", { className: "af-docs-workbench", "aria-label": "Docs workbench", children: [
773
- /* @__PURE__ */ h("header", { children: [
774
- /* @__PURE__ */ h("div", { children: [
775
- /* @__PURE__ */ h(q, { children: [
771
+ }), h = d.find((m) => m.id === t) ?? d[0];
772
+ return e.error && !e.spaces.length ? /* @__PURE__ */ r(j, { title: "Docs unavailable", description: e.error.message, action: { label: "Retry", onClick: () => void s.refresh() } }) : /* @__PURE__ */ p("section", { className: "af-docs-workbench", "aria-label": "Docs workbench", children: [
773
+ /* @__PURE__ */ p("header", { children: [
774
+ /* @__PURE__ */ p("div", { children: [
775
+ /* @__PURE__ */ p(q, { children: [
776
776
  /* @__PURE__ */ r(Os, { size: 14, "aria-hidden": !0 }),
777
777
  " Docs repository"
778
778
  ] }),
779
- /* @__PURE__ */ h(B, { children: [
779
+ /* @__PURE__ */ p(B, { children: [
780
780
  e.spaces.length,
781
781
  " spaces"
782
782
  ] })
783
783
  ] }),
784
784
  /* @__PURE__ */ r(z, { size: "compact", variant: "secondary", disabled: e.loading, onClick: () => void s.refresh(), children: e.loading ? "Loading…" : "Refresh" })
785
785
  ] }),
786
- e.spaces.length ? /* @__PURE__ */ r("div", { className: "af-docs-workbench__list", children: e.spaces.map((m) => /* @__PURE__ */ h(Y, { as: "article", children: [
787
- /* @__PURE__ */ h("div", { children: [
786
+ e.spaces.length ? /* @__PURE__ */ r("div", { className: "af-docs-workbench__list", children: e.spaces.map((m) => /* @__PURE__ */ p(Y, { as: "article", children: [
787
+ /* @__PURE__ */ p("div", { children: [
788
788
  /* @__PURE__ */ r(q, { children: m.locale || "default locale" }),
789
789
  /* @__PURE__ */ r(B, { children: m.name }),
790
790
  /* @__PURE__ */ r("p", { children: m.id })
791
791
  ] }),
792
792
  /* @__PURE__ */ r(z, { size: "compact", onClick: () => void s.openSpace(m.id), children: "Open" })
793
793
  ] }, m.id)) }) : /* @__PURE__ */ r(j, { size: "sm", title: "No document spaces", description: "Accessible spaces appear here." }),
794
- e.selectedSpaceId && /* @__PURE__ */ h("div", { className: "af-docs-workbench__summary", children: [
795
- /* @__PURE__ */ h($, { tone: "cool", children: [
794
+ e.selectedSpaceId && /* @__PURE__ */ p("div", { className: "af-docs-workbench__summary", children: [
795
+ /* @__PURE__ */ p($, { tone: "cool", children: [
796
796
  e.nodes.length,
797
797
  " root nodes · ",
798
798
  e.documents.length,
799
799
  " documents"
800
800
  ] }),
801
- /* @__PURE__ */ h($, { tone: "neutral", children: [
801
+ /* @__PURE__ */ p($, { tone: "neutral", children: [
802
802
  /* @__PURE__ */ r(It, { size: 12, "aria-hidden": !0 }),
803
803
  " ",
804
804
  e.trash.length,
805
805
  " trash"
806
806
  ] }),
807
- ((w = e.spacePermissions) == null ? void 0 : w.manage) && /* @__PURE__ */ h(Ee, { children: [
808
- /* @__PURE__ */ h($, { tone: "neutral", children: [
807
+ ((w = e.spacePermissions) == null ? void 0 : w.manage) && /* @__PURE__ */ p(Ee, { children: [
808
+ /* @__PURE__ */ p($, { tone: "neutral", children: [
809
809
  /* @__PURE__ */ r(_s, { size: 12, "aria-hidden": !0 }),
810
810
  " ",
811
811
  e.acl.length,
812
812
  " grants"
813
813
  ] }),
814
- /* @__PURE__ */ h($, { tone: "neutral", children: [
814
+ /* @__PURE__ */ p($, { tone: "neutral", children: [
815
815
  e.invites.length,
816
816
  " invites"
817
817
  ] })
818
818
  ] })
819
819
  ] }),
820
- e.documents.length > 0 && /* @__PURE__ */ r("div", { className: "af-docs-workbench__list", children: e.documents.map((m) => /* @__PURE__ */ h(Y, { as: "article", children: [
821
- /* @__PURE__ */ h("div", { children: [
822
- /* @__PURE__ */ h(q, { children: [
820
+ e.documents.length > 0 && /* @__PURE__ */ r("div", { className: "af-docs-workbench__list", children: e.documents.map((m) => /* @__PURE__ */ p(Y, { as: "article", children: [
821
+ /* @__PURE__ */ p("div", { children: [
822
+ /* @__PURE__ */ p(q, { children: [
823
823
  "Revision ",
824
824
  m.revision.toString(),
825
825
  " · ",
@@ -830,41 +830,41 @@ function yi({ controller: s }) {
830
830
  ] }),
831
831
  /* @__PURE__ */ r(z, { size: "compact", variant: "secondary", onClick: () => void s.openNode(m.id), children: "Manage" })
832
832
  ] }, m.id)) }),
833
- e.selectedNode && /* @__PURE__ */ h(Y, { as: "section", children: [
834
- /* @__PURE__ */ h("header", { children: [
835
- /* @__PURE__ */ h("div", { children: [
833
+ e.selectedNode && /* @__PURE__ */ p(Y, { as: "section", children: [
834
+ /* @__PURE__ */ p("header", { children: [
835
+ /* @__PURE__ */ p("div", { children: [
836
836
  /* @__PURE__ */ r(q, { children: "Selected document" }),
837
837
  /* @__PURE__ */ r(B, { children: e.selectedNode.title })
838
838
  ] }),
839
839
  /* @__PURE__ */ r($, { tone: ((I = e.index) == null ? void 0 : I.status) === G.RevisionIndexStatus.READY ? "success" : "warning", children: G.RevisionIndexStatus[((v = e.index) == null ? void 0 : v.status) ?? 0] })
840
840
  ] }),
841
- /* @__PURE__ */ h("p", { children: [
841
+ /* @__PURE__ */ p("p", { children: [
842
842
  e.revisions.length,
843
843
  " immutable revisions"
844
844
  ] }),
845
- /* @__PURE__ */ h("div", { className: "af-docs-workbench__actions", children: [
846
- /* @__PURE__ */ h(z, { size: "compact", variant: "secondary", disabled: !((C = e.nodePermissions) != null && C.write), onClick: () => void s.retryIndex(), children: [
845
+ /* @__PURE__ */ p("div", { className: "af-docs-workbench__actions", children: [
846
+ /* @__PURE__ */ p(z, { size: "compact", variant: "secondary", disabled: !((C = e.nodePermissions) != null && C.write), onClick: () => void s.retryIndex(), children: [
847
847
  /* @__PURE__ */ r(qs, { size: 14, "aria-hidden": !0 }),
848
848
  " Retry index"
849
849
  ] }),
850
- d.length > 0 && /* @__PURE__ */ r(Ss, { label: "Translation target", value: (u == null ? void 0 : u.id) ?? "", options: d.map((m) => ({ value: m.id, label: `${m.title} · ${m.locale}` })), onChange: n }),
851
- /* @__PURE__ */ h(z, { size: "compact", variant: "ghost", disabled: !u || !((k = e.nodePermissions) != null && k.write), onClick: () => u && void s.requestTranslation(u.id, u.locale), children: [
850
+ d.length > 0 && /* @__PURE__ */ r(Ss, { label: "Translation target", value: (h == null ? void 0 : h.id) ?? "", options: d.map((m) => ({ value: m.id, label: `${m.title} · ${m.locale}` })), onChange: n }),
851
+ /* @__PURE__ */ p(z, { size: "compact", variant: "ghost", disabled: !h || !((k = e.nodePermissions) != null && k.write), onClick: () => h && void s.requestTranslation(h.id, h.locale), children: [
852
852
  /* @__PURE__ */ r(Bs, { size: 14, "aria-hidden": !0 }),
853
853
  " Translation workflow"
854
854
  ] })
855
855
  ] }),
856
- /* @__PURE__ */ h("div", { className: "af-docs-workbench__actions", children: [
856
+ /* @__PURE__ */ p("div", { className: "af-docs-workbench__actions", children: [
857
857
  /* @__PURE__ */ r(Re, { "aria-label": "Release version", value: i, onChange: (m) => c(m.target.value) }),
858
- /* @__PURE__ */ r(z, { size: "compact", disabled: !u || !i || !((A = e.spacePermissions) != null && A.writeTree), onClick: () => u && void s.publishBundle(i, e.selectedNode.locale, [{ locale: u.locale, nodes: [{ sourceNodeId: e.selectedNode.id, targetNodeId: u.id }] }]), children: "Publish locale bundle" })
858
+ /* @__PURE__ */ r(z, { size: "compact", disabled: !h || !i || !((A = e.spacePermissions) != null && A.writeTree), onClick: () => h && void s.publishBundle(i, e.selectedNode.locale, [{ locale: h.locale, nodes: [{ sourceNodeId: e.selectedNode.id, targetNodeId: h.id }] }]), children: "Publish locale bundle" })
859
859
  ] }),
860
- e.conflict && /* @__PURE__ */ h("div", { role: "alert", children: [
860
+ e.conflict && /* @__PURE__ */ p("div", { role: "alert", children: [
861
861
  /* @__PURE__ */ r("strong", { children: "Concurrent save rejected." }),
862
862
  " Local draft retained for retry or Save as copy."
863
863
  ] })
864
864
  ] }),
865
865
  e.managementError && /* @__PURE__ */ r("p", { role: "status", children: "Management data unavailable. Refresh to check your current access." }),
866
866
  e.error && e.spaces.length > 0 && /* @__PURE__ */ r("p", { role: "alert", children: e.error.message }),
867
- /* @__PURE__ */ r("div", { className: "af-docs-workbench__actions", children: Object.keys(e.nextPageTokens).filter((m) => e.nextPageTokens[m]).map((m) => /* @__PURE__ */ h(z, { size: "compact", variant: "secondary", disabled: e.loading, onClick: () => void s.loadMore(m), children: [
867
+ /* @__PURE__ */ r("div", { className: "af-docs-workbench__actions", children: Object.keys(e.nextPageTokens).filter((m) => e.nextPageTokens[m]).map((m) => /* @__PURE__ */ p(z, { size: "compact", variant: "secondary", disabled: e.loading, onClick: () => void s.loadMore(m), children: [
868
868
  "Load more ",
869
869
  m
870
870
  ] }, m)) })
@@ -872,13 +872,13 @@ function yi({ controller: s }) {
872
872
  }
873
873
  class ki {
874
874
  constructor(e) {
875
- f(this, "state", { loading: !1 });
876
- f(this, "listeners", /* @__PURE__ */ new Set());
877
- f(this, "generation", 0);
878
- f(this, "target", "");
879
- f(this, "tenantId", "");
880
- f(this, "getSnapshot", () => this.state);
881
- f(this, "subscribe", (e) => (this.listeners.add(e), () => this.listeners.delete(e)));
875
+ u(this, "state", { loading: !1 });
876
+ u(this, "listeners", /* @__PURE__ */ new Set());
877
+ u(this, "generation", 0);
878
+ u(this, "target", "");
879
+ u(this, "tenantId", "");
880
+ u(this, "getSnapshot", () => this.state);
881
+ u(this, "subscribe", (e) => (this.listeners.add(e), () => this.listeners.delete(e)));
882
882
  this.transport = e;
883
883
  }
884
884
  async load(e, t, n) {
@@ -888,8 +888,8 @@ class ki {
888
888
  const d = await this.transport.getLatestPublishedRelease({ tenantId: e, spaceId: t, locale: n });
889
889
  i === this.generation && c === this.target && (this.tenantId = e, this.update({ release: d, loading: !1 }));
890
890
  } catch (d) {
891
- const u = d instanceof Error ? d : new Error(String(d));
892
- throw i === this.generation && c === this.target && this.update({ loading: !1, error: u }), u;
891
+ const h = d instanceof Error ? d : new Error(String(d));
892
+ throw i === this.generation && c === this.target && this.update({ loading: !1, error: h }), h;
893
893
  }
894
894
  }
895
895
  async resolveImage(e, t) {
@@ -906,16 +906,16 @@ class ki {
906
906
  const un = (s) => pe(s.subscribe, s.getSnapshot, s.getSnapshot);
907
907
  function Si({ controller: s }) {
908
908
  const e = un(s);
909
- return e.loading ? /* @__PURE__ */ r(j, { title: "Loading published documentation" }) : e.error ? /* @__PURE__ */ r(j, { title: "Published documentation unavailable", description: e.error.message }) : e.release ? /* @__PURE__ */ h("main", { className: "af-docs-workbench", "aria-label": "Published documentation", children: [
910
- /* @__PURE__ */ r("header", { children: /* @__PURE__ */ h("div", { children: [
911
- /* @__PURE__ */ h(q, { children: [
909
+ return e.loading ? /* @__PURE__ */ r(j, { title: "Loading published documentation" }) : e.error ? /* @__PURE__ */ r(j, { title: "Published documentation unavailable", description: e.error.message }) : e.release ? /* @__PURE__ */ p("main", { className: "af-docs-workbench", "aria-label": "Published documentation", children: [
910
+ /* @__PURE__ */ r("header", { children: /* @__PURE__ */ p("div", { children: [
911
+ /* @__PURE__ */ p(q, { children: [
912
912
  e.release.locale,
913
913
  " · ",
914
914
  e.release.version
915
915
  ] }),
916
916
  /* @__PURE__ */ r(B, { children: "Published documentation" })
917
917
  ] }) }),
918
- e.release.nodes.map((t) => /* @__PURE__ */ r(Y, { as: "article", children: /* @__PURE__ */ h("div", { children: [
918
+ e.release.nodes.map((t) => /* @__PURE__ */ r(Y, { as: "article", children: /* @__PURE__ */ p("div", { children: [
919
919
  /* @__PURE__ */ r(q, { children: t.slug }),
920
920
  /* @__PURE__ */ r(B, { children: t.title }),
921
921
  /* @__PURE__ */ r(hn, { node: t, controller: s })
@@ -975,7 +975,7 @@ const Sn = () => new kn(), xn = (s) => {
975
975
  ue(s, Oe[n]);
976
976
  } else
977
977
  An(s, yn(e));
978
- }, Nn = (s, e) => {
978
+ }, Pn = (s, e) => {
979
979
  const t = unescape(encodeURIComponent(e)), n = t.length;
980
980
  F(s, n);
981
981
  for (let i = 0; i < n; i++)
@@ -984,8 +984,8 @@ const Sn = () => new kn(), xn = (s) => {
984
984
  /** @type {number} */
985
985
  t.codePointAt(i)
986
986
  );
987
- }, Pn = te && /** @type {any} */
988
- te.encodeInto ? In : Nn, Tn = (s, e) => {
987
+ }, Nn = te && /** @type {any} */
988
+ te.encodeInto ? In : Pn, Tn = (s, e) => {
989
989
  const t = s.cbuf.length, n = s.cpos, i = pn(t - n, e.length), c = e.length - i;
990
990
  s.cbuf.set(e.subarray(0, i), n), s.cpos += i, c > 0 && (s.bufs.push(s.cbuf), s.cbuf = new Uint8Array(fn(t * 2, c)), s.cbuf.set(e.subarray(i)), s.cpos = c);
991
991
  }, An = (s, e) => {
@@ -1036,13 +1036,13 @@ const Un = (s) => new Rn(s), Ln = (s, e) => {
1036
1036
  }, _n = (s) => (
1037
1037
  /** @type any */
1038
1038
  Q.decode(Mn(s))
1039
- ), qn = Q ? _n : On, he = Date.now, Pe = () => /* @__PURE__ */ new Map(), Bn = (s, e, t) => {
1039
+ ), qn = Q ? _n : On, he = Date.now, Ne = () => /* @__PURE__ */ new Map(), Bn = (s, e, t) => {
1040
1040
  let n = s.get(e);
1041
1041
  return n === void 0 && s.set(e, n = t()), n;
1042
1042
  };
1043
1043
  class jn {
1044
1044
  constructor() {
1045
- this._observers = Pe();
1045
+ this._observers = Ne();
1046
1046
  }
1047
1047
  /**
1048
1048
  * @param {N} name
@@ -1079,10 +1079,10 @@ class jn {
1079
1079
  * @param {Array<any>} args The arguments that are applied to the event listener.
1080
1080
  */
1081
1081
  emit(e, t) {
1082
- return vn((this._observers.get(e) || Pe()).values()).forEach((n) => n(...t));
1082
+ return vn((this._observers.get(e) || Ne()).values()).forEach((n) => n(...t));
1083
1083
  }
1084
1084
  destroy() {
1085
- this._observers = Pe();
1085
+ this._observers = Ne();
1086
1086
  }
1087
1087
  }
1088
1088
  const kt = Symbol("Equality"), Hn = Object.keys, St = (s) => Hn(s).length, Vn = (s, e) => Object.prototype.hasOwnProperty.call(s, e), ee = (s, e) => {
@@ -1176,8 +1176,8 @@ class Rt extends jn {
1176
1176
  clock: i,
1177
1177
  lastUpdated: he()
1178
1178
  });
1179
- const d = [], u = [], w = [], I = [];
1180
- e === null ? I.push(t) : c == null ? e != null && d.push(t) : (u.push(t), ee(c, e) || w.push(t)), (d.length > 0 || w.length > 0 || I.length > 0) && this.emit("change", [{ added: d, updated: w, removed: I }, "local"]), this.emit("update", [{ added: d, updated: u, removed: I }, "local"]);
1179
+ const d = [], h = [], w = [], I = [];
1180
+ e === null ? I.push(t) : c == null ? e != null && d.push(t) : (h.push(t), ee(c, e) || w.push(t)), (d.length > 0 || w.length > 0 || I.length > 0) && this.emit("change", [{ added: d, updated: w, removed: I }, "local"]), this.emit("update", [{ added: d, updated: h, removed: I }, "local"]);
1181
1181
  }
1182
1182
  /**
1183
1183
  * @param {string} field
@@ -1220,15 +1220,15 @@ const Ut = (s, e, t) => {
1220
1220
  const n = e.length, i = Sn();
1221
1221
  F(i, n);
1222
1222
  for (let c = 0; c < n; c++) {
1223
- const d = e[c], u = t.get(d) || null, w = (
1223
+ const d = e[c], h = t.get(d) || null, w = (
1224
1224
  /** @type {MetaClientState} */
1225
1225
  s.meta.get(d).clock
1226
1226
  );
1227
- F(i, d), F(i, w), Pn(i, JSON.stringify(u));
1227
+ F(i, d), F(i, w), Nn(i, JSON.stringify(h));
1228
1228
  }
1229
1229
  return Dn(i);
1230
1230
  }, Mt = (s, e, t) => {
1231
- const n = Un(e), i = he(), c = [], d = [], u = [], w = [], I = Z(n);
1231
+ const n = Un(e), i = he(), c = [], d = [], h = [], w = [], I = Z(n);
1232
1232
  for (let v = 0; v < I; v++) {
1233
1233
  const C = Z(n);
1234
1234
  let k = Z(n);
@@ -1236,11 +1236,11 @@ const Ut = (s, e, t) => {
1236
1236
  (E < k || E === k && A === null && s.states.has(C)) && (A === null ? C === s.clientID && s.getLocalState() != null ? k++ : s.states.delete(C) : s.states.set(C, A), s.meta.set(C, {
1237
1237
  clock: k,
1238
1238
  lastUpdated: i
1239
- }), m === void 0 && A !== null ? c.push(C) : m !== void 0 && A === null ? w.push(C) : A !== null && (ee(A, U) || u.push(C), d.push(C)));
1239
+ }), m === void 0 && A !== null ? c.push(C) : m !== void 0 && A === null ? w.push(C) : A !== null && (ee(A, U) || h.push(C), d.push(C)));
1240
1240
  }
1241
- (c.length > 0 || u.length > 0 || w.length > 0) && s.emit("change", [{
1241
+ (c.length > 0 || h.length > 0 || w.length > 0) && s.emit("change", [{
1242
1242
  added: c,
1243
- updated: u,
1243
+ updated: h,
1244
1244
  removed: w
1245
1245
  }, t]), (c.length > 0 || d.length > 0 || w.length > 0) && s.emit("update", [{
1246
1246
  added: c,
@@ -1257,14 +1257,14 @@ const Ut = (s, e, t) => {
1257
1257
  };
1258
1258
  class xi {
1259
1259
  constructor(e) {
1260
- f(this, "state", xt);
1261
- f(this, "listeners", /* @__PURE__ */ new Set());
1262
- f(this, "generation", 0);
1263
- f(this, "desired");
1264
- f(this, "pendingUpdates", /* @__PURE__ */ new Map());
1265
- f(this, "reconnecting");
1266
- f(this, "getSnapshot", () => this.state);
1267
- f(this, "subscribe", (e) => (this.listeners.add(e), () => this.listeners.delete(e)));
1260
+ u(this, "state", xt);
1261
+ u(this, "listeners", /* @__PURE__ */ new Set());
1262
+ u(this, "generation", 0);
1263
+ u(this, "desired");
1264
+ u(this, "pendingUpdates", /* @__PURE__ */ new Map());
1265
+ u(this, "reconnecting");
1266
+ u(this, "getSnapshot", () => this.state);
1267
+ u(this, "subscribe", (e) => (this.listeners.add(e), () => this.listeners.delete(e)));
1268
1268
  this.transport = e;
1269
1269
  }
1270
1270
  async connect(e, t, n = 0n) {
@@ -1434,22 +1434,22 @@ class xi {
1434
1434
  const Dt = Symbol("docs-collaboration-remote"), le = Symbol("docs-collaboration-presence"), Ae = 64 * 1024;
1435
1435
  class Di {
1436
1436
  constructor(e, t, n, i = "prosemirror") {
1437
- f(this, "document", new O.Doc());
1438
- f(this, "awareness", new Rt(this.document));
1439
- f(this, "user");
1440
- f(this, "editorCollaboration");
1441
- f(this, "unsubscribe");
1442
- f(this, "presenceClients", /* @__PURE__ */ new Map());
1443
- f(this, "appliedPresence", /* @__PURE__ */ new Map());
1444
- f(this, "clockClientId", crypto.randomUUID());
1445
- f(this, "clientClock", 0n);
1446
- f(this, "appliedSequence", 0n);
1447
- f(this, "queuedUpdates", []);
1448
- f(this, "pumping");
1449
- f(this, "presencePending", Promise.resolve());
1450
- f(this, "terminalUpdateError");
1451
- f(this, "oversizedUpdate", !1);
1452
- f(this, "applyRemoteUpdates", () => {
1437
+ u(this, "document", new O.Doc());
1438
+ u(this, "awareness", new Rt(this.document));
1439
+ u(this, "user");
1440
+ u(this, "editorCollaboration");
1441
+ u(this, "unsubscribe");
1442
+ u(this, "presenceClients", /* @__PURE__ */ new Map());
1443
+ u(this, "appliedPresence", /* @__PURE__ */ new Map());
1444
+ u(this, "clockClientId", crypto.randomUUID());
1445
+ u(this, "clientClock", 0n);
1446
+ u(this, "appliedSequence", 0n);
1447
+ u(this, "queuedUpdates", []);
1448
+ u(this, "pumping");
1449
+ u(this, "presencePending", Promise.resolve());
1450
+ u(this, "terminalUpdateError");
1451
+ u(this, "oversizedUpdate", !1);
1452
+ u(this, "applyRemoteUpdates", () => {
1453
1453
  for (const t of this.controller.getSnapshot().updates)
1454
1454
  t.serverSequence <= this.appliedSequence || (O.applyUpdate(this.document, t.update, Dt), this.appliedSequence = t.serverSequence);
1455
1455
  const e = this.controller.getSnapshot().cursors;
@@ -1457,8 +1457,8 @@ class Di {
1457
1457
  e[t] || (Ut(this.awareness, [...this.presenceClients.get(t) ?? []], le), this.presenceClients.delete(t), this.appliedPresence.delete(t));
1458
1458
  for (const [t, n] of Object.entries(e)) {
1459
1459
  if (n.cursor.length === 0 || $n(this.appliedPresence.get(t), n.cursor)) continue;
1460
- const i = /* @__PURE__ */ new Set(), c = ({ added: d, updated: u }) => {
1461
- for (const w of [...d, ...u]) i.add(w);
1460
+ const i = /* @__PURE__ */ new Set(), c = ({ added: d, updated: h }) => {
1461
+ for (const w of [...d, ...h]) i.add(w);
1462
1462
  };
1463
1463
  this.awareness.on("update", c);
1464
1464
  try {
@@ -1471,7 +1471,7 @@ class Di {
1471
1471
  i.size > 0 && this.presenceClients.set(t, i), this.appliedPresence.set(t, n.cursor);
1472
1472
  }
1473
1473
  });
1474
- f(this, "pushLocalUpdate", (e, t) => {
1474
+ u(this, "pushLocalUpdate", (e, t) => {
1475
1475
  var d;
1476
1476
  if (t === Dt) return;
1477
1477
  const n = this.oversizedUpdate ? O.encodeStateAsUpdate(this.document) : e;
@@ -1481,9 +1481,9 @@ class Di {
1481
1481
  }
1482
1482
  this.oversizedUpdate = !1, this.terminalUpdateError = void 0;
1483
1483
  const i = this.queuedUpdates.at(-1), c = i && i.clock === void 0 ? O.mergeUpdates([i.bytes, n]) : n;
1484
- i && i.clock === void 0 && c.length <= Ae ? i.bytes = c : this.queuedUpdates.push({ bytes: n }), (d = this.ensurePump()) == null || d.catch((u) => this.controller.reportError(u));
1484
+ i && i.clock === void 0 && c.length <= Ae ? i.bytes = c : this.queuedUpdates.push({ bytes: n }), (d = this.ensurePump()) == null || d.catch((h) => this.controller.reportError(h));
1485
1485
  });
1486
- f(this, "pushLocalPresence", (e, t) => {
1486
+ u(this, "pushLocalPresence", (e, t) => {
1487
1487
  if (t === le || !this.controller.getSnapshot().connected) return;
1488
1488
  const n = Lt(this.awareness, [this.awareness.clientID]);
1489
1489
  this.presencePending = this.presencePending.catch(() => {
@@ -1581,15 +1581,15 @@ function Jn(s, e) {
1581
1581
  const Kn = (s) => new Promise((e) => setTimeout(e, s)), Xn = (s) => pe(s.subscribe, s.getSnapshot, s.getSnapshot);
1582
1582
  function Ci({ controller: s }) {
1583
1583
  const e = Xn(s);
1584
- return e.error ? /* @__PURE__ */ r(j, { size: "sm", title: "Live editing unavailable", description: e.error.message }) : /* @__PURE__ */ h(Y, { as: "section", children: [
1585
- /* @__PURE__ */ h("header", { children: [
1586
- /* @__PURE__ */ h("div", { children: [
1584
+ return e.error ? /* @__PURE__ */ r(j, { size: "sm", title: "Live editing unavailable", description: e.error.message }) : /* @__PURE__ */ p(Y, { as: "section", children: [
1585
+ /* @__PURE__ */ p("header", { children: [
1586
+ /* @__PURE__ */ p("div", { children: [
1587
1587
  /* @__PURE__ */ r(q, { children: "Live document" }),
1588
1588
  /* @__PURE__ */ r(B, { children: e.nodeId ?? "No document selected" })
1589
1589
  ] }),
1590
1590
  /* @__PURE__ */ r($, { tone: e.connected ? "success" : "neutral", children: e.connecting ? "Connecting" : e.connected ? "Connected" : "Disconnected" })
1591
1591
  ] }),
1592
- /* @__PURE__ */ h("p", { children: [
1592
+ /* @__PURE__ */ p("p", { children: [
1593
1593
  Object.keys(e.cursors).length,
1594
1594
  " remote editors · durable sequence ",
1595
1595
  e.serverSequence.toString()
@@ -1598,7 +1598,71 @@ function Ci({ controller: s }) {
1598
1598
  (e.connected || e.connecting) && /* @__PURE__ */ r(z, { size: "compact", variant: "secondary", onClick: () => s.disconnect(), children: "Disconnect" })
1599
1599
  ] });
1600
1600
  }
1601
+ class Ii {
1602
+ constructor(e, t, n = 800) {
1603
+ u(this, "snapshot");
1604
+ u(this, "generation", 0);
1605
+ u(this, "savedGeneration", 0);
1606
+ u(this, "online", !0);
1607
+ u(this, "writable", !0);
1608
+ u(this, "timer");
1609
+ u(this, "saving");
1610
+ u(this, "listeners", /* @__PURE__ */ new Set());
1611
+ u(this, "getSnapshot", () => this.snapshot);
1612
+ u(this, "subscribe", (e) => (this.listeners.add(e), () => this.listeners.delete(e)));
1613
+ this.persist = t, this.delayMs = n, this.snapshot = { status: "clean", revision: e };
1614
+ }
1615
+ markDirty() {
1616
+ this.generation += 1, this.publish({ status: this.writable ? this.online ? "dirty" : "offline" : "denied" }), this.schedule();
1617
+ }
1618
+ setOnline(e) {
1619
+ this.online = e, e ? this.hasPending() && (this.publish({ status: "dirty", error: void 0 }), this.schedule()) : (this.clearTimer(), this.hasPending() && this.publish({ status: "offline" }));
1620
+ }
1621
+ setWritable(e) {
1622
+ this.writable = e, e ? this.hasPending() && (this.publish({ status: this.online ? "dirty" : "offline", error: void 0 }), this.schedule()) : (this.clearTimer(), this.publish({ status: "denied" }));
1623
+ }
1624
+ retry() {
1625
+ return this.hasPending() ? (this.publish({ status: this.online ? "dirty" : "offline", error: void 0 }), this.flush()) : Promise.resolve();
1626
+ }
1627
+ flush() {
1628
+ return this.clearTimer(), !this.online || !this.writable || !this.hasPending() ? this.saving ?? Promise.resolve() : (this.saving || (this.saving = this.drain().finally(() => {
1629
+ this.saving = void 0;
1630
+ })), this.saving);
1631
+ }
1632
+ destroy() {
1633
+ this.clearTimer(), this.listeners.clear();
1634
+ }
1635
+ async drain() {
1636
+ for (; this.online && this.writable && this.hasPending(); ) {
1637
+ const e = this.generation;
1638
+ this.publish({ status: "saving", error: void 0 });
1639
+ try {
1640
+ const t = await this.persist(this.snapshot.revision);
1641
+ this.savedGeneration = e, this.snapshot = { status: this.hasPending() ? "dirty" : "saved", revision: t.revision, updatedAt: t.updatedAt }, this.emit();
1642
+ } catch (t) {
1643
+ this.publish({ status: "error", error: t });
1644
+ return;
1645
+ }
1646
+ }
1647
+ }
1648
+ hasPending() {
1649
+ return this.generation > this.savedGeneration;
1650
+ }
1651
+ schedule() {
1652
+ this.clearTimer(), this.online && this.writable && this.hasPending() && (this.timer = setTimeout(() => void this.flush(), this.delayMs));
1653
+ }
1654
+ clearTimer() {
1655
+ this.timer && clearTimeout(this.timer), this.timer = void 0;
1656
+ }
1657
+ publish(e) {
1658
+ this.snapshot = { ...this.snapshot, ...e }, this.emit();
1659
+ }
1660
+ emit() {
1661
+ for (const e of this.listeners) e();
1662
+ }
1663
+ }
1601
1664
  export {
1665
+ Ii as DocsAutosaveController,
1602
1666
  Ci as DocsCollaboration,
1603
1667
  xi as DocsCollaborationController,
1604
1668
  yi as DocsWorkbench,
@@ -1611,7 +1675,7 @@ export {
1611
1675
  Di as YjsDocsCollaborationAdapter,
1612
1676
  Gs as applyDocumentAssistantOutput,
1613
1677
  Ys as commitDocumentAssistantRollback,
1614
- Nt as documentAssistantConflict,
1678
+ Pt as documentAssistantConflict,
1615
1679
  Me as durableRichDocumentContent,
1616
1680
  vt as emptyRichDocument,
1617
1681
  cn as looksLikeMarkdown,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-factory-platform/docs-react",
3
- "version": "0.11.1",
3
+ "version": "0.11.2",
4
4
  "description": "Product-neutral rich document editor and repository bindings.",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "repository": {
@@ -30,8 +30,8 @@
30
30
  "react-dom": "^19.0.0"
31
31
  },
32
32
  "dependencies": {
33
- "@agent-factory-platform/client": "0.11.1",
34
- "@agent-factory-platform/ui-kit": "0.11.1",
33
+ "@agent-factory-platform/client": "0.11.2",
34
+ "@agent-factory-platform/ui-kit": "0.11.2",
35
35
  "@tiptap/core": "3.30.5",
36
36
  "@tiptap/extension-bubble-menu": "3.30.5",
37
37
  "@tiptap/extension-collaboration": "3.30.5",