@ai-matrx/office 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/collab/sheets/transform/types.ts","../src/collab/sheets/transform/registry.ts","../src/collab/sheets/transform/transform.ts","../src/collab/sheets/transform/axis.ts"],"sourcesContent":["/**\n * Sheet co-editing transforms (C5a): the shapes. Pure data; no Univer import.\n *\n * Convention (COLLAB-DESIGN §6.4): `transform(x, y, side)` returns `x` rewritten to apply AFTER `y`, where\n * `side` is x's side. The later-committed op always takes \"left\": it wins overwrites and sits first on\n * position ties.\n */\n\n/** One allowlisted Univer mutation as it travels: no `unitId` (the receiver re-addresses to its own unit). */\nexport interface SheetMutation {\n readonly id: string;\n readonly params: Readonly<Record<string, unknown>>;\n}\n\n/** A top-level command's mutations, applied in order. The unit the transformer works on. */\nexport type SheetGroup = readonly SheetMutation[];\n\nexport type Side = \"left\" | \"right\";\n\nexport interface Barrier {\n readonly barrier: true;\n readonly reason: string;\n}\n\nexport interface Transformed {\n /** x rewritten to apply after y; `[]` when nothing of x survives. */\n readonly op: SheetMutation[];\n /** Parts of the OTHER op (y) that x overrode: y's author is told (\"Sam changed B4 at the same time\"). */\n readonly lost: string[];\n /** Parts of x itself that cannot apply after y (an edit inside rows y removed): x's author is told. */\n readonly dropped: string[];\n}\n\nexport type TransformResult = Transformed | Barrier;\n\nexport const isBarrier = (r: TransformResult): r is Barrier => (r as Barrier).barrier === true;\n\nexport interface SheetRange {\n startRow: number;\n endRow: number;\n startColumn: number;\n endColumn: number;\n rangeType?: number;\n [k: string]: unknown;\n}\n","/**\n * The sheet mutation registry (COLLAB-DESIGN §10): every mutation id Univer 1.0.4 can emit into a workbook\n * is declared here exactly once, as covered (with its params allowlist), never-travels, or a barrier.\n * `census.test.ts` fails when an emitted id is missing or a declared id is stale.\n *\n * Covered in C5a: cell values and styles, row/column insert, remove and move, merge/unmerge, row height,\n * column width, worksheet name. Formulas are C5b, ranged resources C5c; both are barriers until then.\n */\n\nexport type SheetFamily = \"cell\" | \"structure\" | \"merge\" | \"size\" | \"name\";\n\nexport interface CoveredEntry {\n readonly kind: \"covered\";\n readonly family: SheetFamily;\n /** The params that travel. `unitId` never travels. */\n readonly allow: readonly string[];\n}\nexport interface NeverEntry {\n readonly kind: \"never-travels\";\n readonly reason: string;\n}\nexport interface BarrierEntry {\n readonly kind: \"barrier\";\n /** The unit that owns its transform (C5b formulas, C5c resources) or \"X\" (no unit yet). */\n readonly until: \"C5b\" | \"C5c\" | \"X\";\n readonly reason: string;\n}\nexport type RegistryEntry = CoveredEntry | NeverEntry | BarrierEntry;\n\nconst covered = (family: SheetFamily, ...allow: string[]): CoveredEntry => ({ kind: \"covered\", family, allow: [\"subUnitId\", ...allow] });\nconst never = (reason: string): NeverEntry => ({ kind: \"never-travels\", reason });\nconst barrier = (until: BarrierEntry[\"until\"], reason: string): BarrierEntry => ({ kind: \"barrier\", until, reason });\n\nconst FORMULA_RESULT = \"formula engine output; every seat computes it (dropped at capture)\";\nconst FORMULA = \"formula state; C5b rewrites references\";\nconst RESOURCE = \"ranged resource keyed by id; C5c\";\nconst UNIVER_COMMENTS = \"Univer's own thread-comment store; our comments anchor elsewhere (design §8)\";\n\nexport const SHEET_MUTATIONS: Readonly<Record<string, RegistryEntry>> = {\n // ── covered (C5a) ────────────────────────────────────────────────────────────────────────────────\n \"sheet.mutation.set-range-values\": covered(\"cell\", \"cellValue\"),\n \"sheet.mutation.insert-row\": covered(\"structure\", \"range\", \"rowInfo\"),\n \"sheet.mutation.remove-rows\": covered(\"structure\", \"range\"),\n \"sheet.mutation.insert-col\": covered(\"structure\", \"range\", \"colInfo\"),\n \"sheet.mutation.remove-col\": covered(\"structure\", \"range\"),\n \"sheet.mutation.move-rows\": covered(\"structure\", \"sourceRange\", \"targetRange\"),\n \"sheet.mutation.move-columns\": covered(\"structure\", \"sourceRange\", \"targetRange\"),\n \"sheet.mutation.add-worksheet-merge\": covered(\"merge\", \"ranges\"),\n \"sheet.mutation.remove-worksheet-merge\": covered(\"merge\", \"ranges\"),\n \"sheet.mutation.set-worksheet-row-height\": covered(\"size\", \"ranges\", \"rowHeight\"),\n \"sheet.mutation.set-worksheet-row-is-auto-height\": covered(\"size\", \"ranges\", \"autoHeightInfo\"),\n \"sheet.mutation.set-worksheet-row-auto-height\": covered(\"size\", \"rowsAutoHeightInfo\"),\n \"sheet.mutation.set-worksheet-col-width\": covered(\"size\", \"ranges\", \"colWidth\"),\n \"sheet.mutation.set-worksheet-name\": covered(\"name\", \"name\"),\n\n // ── never travels ────────────────────────────────────────────────────────────────────────────────\n \"formula.mutation.set-formula-calculation-start\": never(FORMULA_RESULT),\n \"formula.mutation.set-trigger-formula-calculation-start\": never(FORMULA_RESULT),\n \"formula.mutation.set-formula-calculation-stop\": never(FORMULA_RESULT),\n \"formula.mutation.set-formula-calculation-notification\": never(FORMULA_RESULT),\n \"formula.mutation.set-formula-calculation-result\": never(FORMULA_RESULT),\n \"formula.mutation.set-array-formula-data\": never(FORMULA_RESULT),\n \"formula.mutation.set-formula-data\": never(FORMULA_RESULT),\n \"formula.mutation.set-image-formula-data\": never(FORMULA_RESULT),\n \"formula.mutation.set-formula-string-batch-calculation\": never(FORMULA_RESULT),\n \"formula.mutation.set-formula-string-batch-calculation-result\": never(FORMULA_RESULT),\n \"formula.mutation.set-formula-dependency-calculation\": never(FORMULA_RESULT),\n \"formula.mutation.set-formula-dependency-calculation-result\": never(FORMULA_RESULT),\n \"formula.mutation.set-cell-formula-dependency-calculation\": never(FORMULA_RESULT),\n \"formula.mutation.set-cell-formula-dependency-calculation-result\": never(FORMULA_RESULT),\n \"formula.mutation.set-query-formula-dependency\": never(FORMULA_RESULT),\n \"formula.mutation.set-query-formula-dependency-result\": never(FORMULA_RESULT),\n \"formula.mutation.set-query-formula-dependency-all\": never(FORMULA_RESULT),\n \"formula.mutation.set-query-formula-dependency-all-result\": never(FORMULA_RESULT),\n \"formula.mutation.register-function\": never(\"registers a function body on this seat's engine\"),\n \"sheet.mutation.data-validation-formula-mark-dirty\": never(\"dirty mark\"),\n \"sheet.mutation.mark-dirty-filter-change\": never(\"dirty mark\"),\n \"sheet.mutation.re-calc-filter\": never(\"filter recalculation result\"),\n \"sheet.mutation.toggle-note-popup\": never(\"popup state\"),\n \"sheet.operation.clear-drawing-transformer\": never(\"drawing selection handles (declared as a mutation)\"),\n \"sheet.mutation.copy-worksheet-end\": never(\"end marker of a copy; the copy travels as insert-sheet\"),\n \"sheet.mutation.empty\": never(\"no content\"),\n \"thread-comment.mutation.add-comment\": never(UNIVER_COMMENTS),\n \"thread-comment.mutation.update-comment\": never(UNIVER_COMMENTS),\n \"thread-comment.mutation.update-comment-ref\": never(UNIVER_COMMENTS),\n \"thread-comment.mutation.resolve-comment\": never(UNIVER_COMMENTS),\n \"thread-comment.mutation.delete-comment\": never(UNIVER_COMMENTS),\n\n // ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────\n \"sheet.mutation.reorder-range\": barrier(\"X\", \"sort: a permutation, not transformed yet\"),\n \"sheet.mutation.set-worksheet-row-count\": barrier(\"X\", \"absolute row count; needs delta semantics\"),\n \"sheet.mutation.set-worksheet-column-count\": barrier(\"X\", \"absolute column count; needs delta semantics\"),\n \"sheet.mutation.set-worksheet-order\": barrier(\"X\", \"absolute sheet order; needs move semantics\"),\n \"sheet.mutation.move-range\": barrier(\"X\", \"cut-paste carries the sender's cell matrices\"),\n \"sheet.mutation.insert-sheet\": barrier(\"X\", \"sheet add: not in C5a\"),\n \"sheet.mutation.remove-sheet\": barrier(\"X\", \"sheet remove: not in C5a\"),\n \"sheet.mutation.set-worksheet-hidden\": barrier(\"X\", \"sheet-level setting: not in C5a\"),\n \"sheet.mutation.set-tab-color\": barrier(\"X\", \"sheet-level setting: not in C5a\"),\n \"sheet.mutation.set-workbook-name\": barrier(\"X\", \"workbook-level setting: not in C5a\"),\n \"sheet.mutation.set-worksheet-right-to-left\": barrier(\"X\", \"sheet-level setting: not in C5a\"),\n \"sheet.mutation.toggle-gridlines\": barrier(\"X\", \"sheet-level setting: not in C5a\"),\n \"sheet.mutation.set-gridlines-color\": barrier(\"X\", \"sheet-level setting: not in C5a\"),\n \"sheet.mutation.set-worksheet-default-style\": barrier(\"X\", \"sheet-level setting: not in C5a\"),\n \"sheet.mutation.set-frozen\": barrier(\"X\", \"absolute frozen indices: not in C5a\"),\n \"sheet.mutation.set-row-data\": barrier(\"X\", \"row properties by index: not in C5a\"),\n \"sheet.mutation.set-col-data\": barrier(\"X\", \"column properties by index: not in C5a\"),\n \"sheet.mutation.set-row-hidden\": barrier(\"X\", \"row visibility: not in C5a\"),\n \"sheet.mutation.set-row-visible\": barrier(\"X\", \"row visibility: not in C5a\"),\n \"sheet.mutation.set-col-hidden\": barrier(\"X\", \"column visibility: not in C5a\"),\n \"sheet.mutation.set-col-visible\": barrier(\"X\", \"column visibility: not in C5a\"),\n \"sheet.mutation.set.numfmt\": barrier(\"X\", \"number formats by range: not in C5a\"),\n \"sheet.mutation.remove.numfmt\": barrier(\"X\", \"number formats by range: not in C5a\"),\n \"sheet.mutation.add-range-protection\": barrier(\"X\", \"permissions: not in C5a\"),\n \"sheet.mutation.set-range-protection\": barrier(\"X\", \"permissions: not in C5a\"),\n \"sheet.mutation.delete-range-protection\": barrier(\"X\", \"permissions: not in C5a\"),\n \"sheet.mutation.add-worksheet-protection\": barrier(\"X\", \"permissions: not in C5a\"),\n \"sheet.mutation.set-worksheet-protection\": barrier(\"X\", \"permissions: not in C5a\"),\n \"sheet.mutation.delete-worksheet-protection\": barrier(\"X\", \"permissions: not in C5a\"),\n \"sheet.mutation.set-worksheet-permission-points\": barrier(\"X\", \"permissions: not in C5a\"),\n\n // ── barriers until C5b (formulas) ────────────────────────────────────────────────────────────────\n \"formula.mutation.set-defined-name\": barrier(\"C5b\", FORMULA),\n \"formula.mutation.remove-defined-name\": barrier(\"C5b\", FORMULA),\n \"formula.mutation.set-feature-calculation\": barrier(\"C5b\", FORMULA),\n \"formula.mutation.remove-feature-calculation\": barrier(\"C5b\", FORMULA),\n \"formula.mutation.set-other-formula\": barrier(\"C5b\", FORMULA),\n \"formula.mutation.remove-other-formula\": barrier(\"C5b\", FORMULA),\n \"formula.mutation.set-super-table\": barrier(\"C5b\", FORMULA),\n \"formula.mutation.remove-super-table\": barrier(\"C5b\", FORMULA),\n \"formula.mutation.set-super-table-option\": barrier(\"C5b\", FORMULA),\n\n // ── barriers until C5c (ranged resources) ────────────────────────────────────────────────────────\n \"sheet.mutation.add-conditional-rule\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.set-conditional-rule\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.delete-conditional-rule\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.move-conditional-rule\": barrier(\"C5c\", \"conditional-format priority (ordered list)\"),\n \"data-validation.mutation.addRule\": barrier(\"C5c\", RESOURCE),\n \"data-validation.mutation.updateRule\": barrier(\"C5c\", RESOURCE),\n \"data-validation.mutation.removeRule\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.set-filter-range\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.set-filter-criteria\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.remove-filter\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.add-table\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.delete-table\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.set-sheet-table\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.set-table-filter\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.move-table\": barrier(\"C5c\", RESOURCE),\n \"sheets.mutation.add-hyper-link\": barrier(\"C5c\", RESOURCE),\n \"sheets.mutation.remove-hyper-link\": barrier(\"C5c\", RESOURCE),\n \"sheets.mutation.update-hyper-link\": barrier(\"C5c\", RESOURCE),\n \"sheets.mutation.update-hyper-link-ref\": barrier(\"C5c\", RESOURCE),\n \"sheets.mutation.update-rich-hyper-link\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.update-note\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.remove-note\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.update-note-position\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.set-drawing-apply\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.set-worksheet-background-image\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.add-range-theme\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.set-range-theme\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.remove-range-theme\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.set-worksheet-range-theme-style\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.remove-worksheet-range-theme-style\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.register-worksheet-range-theme-style\": barrier(\"C5c\", RESOURCE),\n \"sheet.mutation.unregister-worksheet-range-theme-style\": barrier(\"C5c\", RESOURCE),\n};\n\n/** Keep only the allowlisted params of a covered id; anything else returns null (it does not travel). */\nexport function allowParams(id: string, params: Readonly<Record<string, unknown>>): Record<string, unknown> | null {\n const entry = SHEET_MUTATIONS[id];\n if (!entry || entry.kind !== \"covered\") return null;\n const out: Record<string, unknown> = {};\n for (const f of entry.allow) if (params[f] !== undefined) out[f] = params[f];\n return out;\n}\n","/**\n * The C5a sheet transformer: `transformGroup(x, y, side)` rewrites command group x to apply after group y.\n * Pure: no Univer runtime, no DOM. One rule (COLLAB-DESIGN §6.4): the later-committed op takes \"left\"; it\n * wins overwrites and sits first on position ties. Anything without a proven transform is a Barrier.\n *\n * Covered families: cell values and styles (set-range-values), row/column insert, remove and move,\n * merge/unmerge, row height / column width, worksheet name. See `registry.ts` for every other id.\n *\n * Merges: Univer moves merges two ways when rows or columns change. A listener in MergeCellController shifts\n * merges that sit wholly after the change on EVERY seat (no mutation travels); the command adds explicit\n * remove-merge / add-merge fixups for merges the change cuts through. `mergeThrough` reproduces both, so a\n * merge added concurrently is moved exactly as the command would have moved it.\n */\nimport { adjustRangeOnMutation } from \"@univerjs/sheets\";\nimport { type Axis, type AxisOp, mapIndex, runs, transformAxis } from \"./axis\";\nimport { SHEET_MUTATIONS } from \"./registry\";\nimport { type Barrier, type SheetGroup, type SheetMutation, type SheetRange, type Side, type TransformResult, type Transformed, isBarrier } from \"./types\";\n\nexport const SHEET_TRANSFORMER_VERSION = \"c5a-1\";\n\nconst ID = {\n values: \"sheet.mutation.set-range-values\",\n insertRow: \"sheet.mutation.insert-row\",\n removeRows: \"sheet.mutation.remove-rows\",\n insertCol: \"sheet.mutation.insert-col\",\n removeCol: \"sheet.mutation.remove-col\",\n moveRows: \"sheet.mutation.move-rows\",\n moveCols: \"sheet.mutation.move-columns\",\n addMerge: \"sheet.mutation.add-worksheet-merge\",\n removeMerge: \"sheet.mutation.remove-worksheet-merge\",\n rowHeight: \"sheet.mutation.set-worksheet-row-height\",\n rowIsAuto: \"sheet.mutation.set-worksheet-row-is-auto-height\",\n rowAutoHeight: \"sheet.mutation.set-worksheet-row-auto-height\",\n colWidth: \"sheet.mutation.set-worksheet-col-width\",\n name: \"sheet.mutation.set-worksheet-name\",\n} as const;\n\n/**\n * Pairs the fuzz proved divergent (or that have no transform yet), as unordered mutation-id pairs, with the\n * failing seed. Each returns a Barrier until it has its own correct transform under a new proto.\n */\nexport const PAIR_BARRIERS: Readonly<Record<string, { seed: number | null; reason: string }>> = {};\n\nconst pairKey = (a: string, b: string) => (a < b ? `${a}|${b}` : `${b}|${a}`);\nconst barrier = (reason: string): Barrier => ({ barrier: true, reason });\nconst ok = (op: SheetMutation[], lost: string[] = [], dropped: string[] = []): Transformed => ({ op, lost, dropped });\nconst flip = (side: Side): Side => (side === \"left\" ? \"right\" : \"left\");\n\n// ── addressing ──────────────────────────────────────────────────────────────────────────────────────\nconst sheetOf = (m: SheetMutation) => String(m.params.subUnitId ?? \"\");\nfunction colName(c: number): string {\n let s = \"\";\n for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + ((n - 1) % 26)) + s;\n return s;\n}\nexport const cellRef = (sheet: string, row: number, col: number) => `${sheet}!${colName(col)}${row + 1}`;\nconst rangeRef = (sheet: string, r: SheetRange) =>\n `${sheet}!${colName(r.startColumn)}${r.startRow + 1}:${colName(r.endColumn)}${r.endRow + 1}`;\n\n// ── structural ops ──────────────────────────────────────────────────────────────────────────────────\ninterface Structural {\n axis: Axis;\n op: AxisOp;\n}\nfunction structuralOf(m: SheetMutation): Structural | null {\n const p = m.params as Record<string, SheetRange | undefined>;\n switch (m.id) {\n case ID.insertRow:\n return { axis: \"row\", op: { kind: \"insert\", at: p.range!.startRow, count: p.range!.endRow - p.range!.startRow + 1 } };\n case ID.removeRows:\n return { axis: \"row\", op: { kind: \"remove\", start: p.range!.startRow, count: p.range!.endRow - p.range!.startRow + 1 } };\n case ID.insertCol:\n return { axis: \"col\", op: { kind: \"insert\", at: p.range!.startColumn, count: p.range!.endColumn - p.range!.startColumn + 1 } };\n case ID.removeCol:\n return { axis: \"col\", op: { kind: \"remove\", start: p.range!.startColumn, count: p.range!.endColumn - p.range!.startColumn + 1 } };\n case ID.moveRows:\n return {\n axis: \"row\",\n op: { kind: \"move\", from: p.sourceRange!.startRow, count: p.sourceRange!.endRow - p.sourceRange!.startRow + 1, to: p.targetRange!.startRow },\n };\n case ID.moveCols:\n return {\n axis: \"col\",\n op: {\n kind: \"move\",\n from: p.sourceRange!.startColumn,\n count: p.sourceRange!.endColumn - p.sourceRange!.startColumn + 1,\n to: p.targetRange!.startColumn,\n },\n };\n default:\n return null;\n }\n}\n\nconst S = (axis: Axis) => (axis === \"row\" ? ([\"startRow\", \"endRow\"] as const) : ([\"startColumn\", \"endColumn\"] as const));\n\nfunction buildStructural(template: SheetMutation, axis: Axis, op: AxisOp): SheetMutation {\n const [a0, a1] = S(axis);\n const p = template.params as Record<string, unknown>;\n if (op.kind === \"move\") {\n const src = p.sourceRange as SheetRange;\n const tgt = p.targetRange as SheetRange;\n return {\n id: template.id,\n params: {\n ...p,\n sourceRange: { ...src, [a0]: op.from, [a1]: op.from + op.count - 1 },\n targetRange: { ...tgt, [a0]: op.to, [a1]: op.to + op.count - 1 },\n },\n };\n }\n const start = op.kind === \"insert\" ? op.at : op.start;\n return { id: template.id, params: { ...p, range: { ...(p.range as SheetRange), [a0]: start, [a1]: start + op.count - 1 } } };\n}\n\n/** The same structural op as a Univer mutation info, normalised to span the whole other axis, for Univer's helper. */\nfunction univerMutationInfo(axis: Axis, op: Exclude<AxisOp, { kind: \"move\" }>) {\n const FULL = { startRow: 0, endRow: Number.MAX_SAFE_INTEGER, startColumn: 0, endColumn: Number.MAX_SAFE_INTEGER };\n const start = op.kind === \"insert\" ? op.at : op.start;\n const range = axis === \"row\" ? { ...FULL, startRow: start, endRow: start + op.count - 1 } : { ...FULL, startColumn: start, endColumn: start + op.count - 1 };\n const id = op.kind === \"insert\" ? (axis === \"row\" ? ID.insertRow : ID.insertCol) : axis === \"row\" ? ID.removeRows : ID.removeCol;\n return { id, params: { unitId: \"\", subUnitId: \"\", range } };\n}\n\n// ── merges ──────────────────────────────────────────────────────────────────────────────────────────\nconst intersects = (a: SheetRange, b: SheetRange) =>\n a.startRow <= b.endRow && b.startRow <= a.endRow && a.startColumn <= b.endColumn && b.startColumn <= a.endColumn;\nconst isSingleCell = (r: SheetRange) => r.startRow === r.endRow && r.startColumn === r.endColumn;\n\n/**\n * Where Univer puts merge `m` when structural op `s` runs, and whether that move is a command fixup (a\n * travelling remove/add pair) rather than the seat-local listener shift. `null` = the merge is gone.\n */\nexport function mergeThrough(s: Structural, m: SheetRange): { range: SheetRange | null; fixup: boolean } {\n const [a0, a1] = S(s.axis);\n const lo = m[a0] as number;\n const hi = m[a1] as number;\n const op = s.op;\n if (op.kind === \"insert\") {\n // Univer's own helper is exact here once the insert spans the whole other axis.\n const fixup = lo < op.at && op.at <= hi;\n return { range: adjustRangeOnMutation(m, univerMutationInfo(s.axis, op)) as SheetRange, fixup };\n }\n if (op.kind === \"remove\") {\n const e = op.start + op.count - 1;\n if (e < lo || op.start > hi) return { range: adjustRangeOnMutation(m, univerMutationInfo(s.axis, op)) as SheetRange, fixup: false };\n // The command's own shrink rule (MergeCellController._handleRemove*Command), then a single cell is no merge.\n if (op.start <= lo && e >= hi) return { range: null, fixup: true };\n const r = { ...m };\n if (op.start >= lo && e <= hi) r[a1] = hi - op.count;\n else if (op.start < lo) {\n r[a0] = op.start;\n r[a1] = hi - op.count;\n } else r[a1] = op.start - 1;\n return { range: isSingleCell(r) ? null : r, fixup: true };\n }\n // move: the listener shifts merges clear of the source; the command moves merges wholly inside it; a merge\n // the source cuts through stays where it is (Univer refuses such moves on the sender's own seat).\n const fe = op.from + op.count - 1;\n if (hi < op.from || lo > fe) {\n const r = { ...m };\n if (op.from < lo && op.to > hi) {\n r[a0] = lo - op.count;\n r[a1] = hi - op.count;\n } else if (op.from > hi && op.to <= lo) {\n r[a0] = lo + op.count;\n r[a1] = hi + op.count;\n }\n return { range: r, fixup: false };\n }\n if (lo >= op.from && hi <= fe) {\n const r = { ...m, [a0]: mapIndex(op, lo)!, [a1]: mapIndex(op, hi)! };\n return { range: r, fixup: true };\n }\n return { range: m, fixup: false };\n}\n\n/**\n * Rewrites every remove-merge in a group to name the exact merges it removes. Univer removes every merge a\n * range intersects, and the unmerge command sends the SELECTION; a selection does not move the way the\n * merges under it move, so only exact merges transform correctly. `merges` is each sheet's mergeData right\n * before the group (C6 reads it in beforeCommandExecuted). Pure: the group is simulated, not applied.\n */\nexport function exactMergeRemovals(group: SheetGroup, merges: Readonly<Record<string, readonly SheetRange[]>>): SheetMutation[] {\n const sim = new Map<string, SheetRange[]>(Object.entries(merges).map(([k, v]) => [k, v.map((r) => ({ ...r }))]));\n const out: SheetMutation[] = [];\n for (const m of group) {\n const sheet = sheetOf(m);\n const cur = sim.get(sheet) ?? [];\n if (m.id === ID.removeMerge) {\n const hit = cur.filter((q) => mergeRanges(m).some((r) => intersects(r, q)));\n sim.set(sheet, cur.filter((q) => !hit.includes(q)));\n if (hit.length) out.push(withRanges(m, hit.map((r) => ({ ...r }))));\n continue;\n }\n if (m.id === ID.addMerge) sim.set(sheet, [...cur, ...mergeRanges(m).map((r) => ({ ...r }))]);\n const st = structuralOf(m);\n if (st) sim.set(sheet, cur.map((q) => mergeThrough(st, q).range).filter((q): q is SheetRange => q !== null));\n out.push(m);\n }\n return out;\n}\n\nconst mergeRanges = (m: SheetMutation) => (m.params.ranges as SheetRange[] | undefined) ?? [];\nconst withRanges = (m: SheetMutation, ranges: SheetRange[]): SheetMutation => ({ id: m.id, params: { ...m.params, ranges } });\nconst mergeMutation = (id: string, sheet: string, ranges: SheetRange[]): SheetMutation => ({ id, params: { subUnitId: sheet, ranges } });\n\n// ── cells ───────────────────────────────────────────────────────────────────────────────────────────\ntype Cell = Record<string, unknown> | null;\ntype CellMatrix = Record<string, Record<string, Cell>>;\n/** The content slot of a cell. A travelling entry that touches content must carry all of them (see completeCellContent). */\nexport const CONTENT_KEYS = [\"v\", \"t\", \"p\", \"f\", \"si\", \"custom\"] as const;\nconst CONTENT_TOUCH = [\"v\", \"p\", \"f\", \"si\", \"custom\"];\nconst KNOWN_CELL_KEYS = new Set<string>([...CONTENT_KEYS, \"s\"]);\n\n/**\n * Completes a captured cell entry's content slot from the sender's post-state, so content writes are full\n * replacements (an entry that sets `v` alone would otherwise keep a stale `p` on some seats). C6's capture\n * calls this per touched cell with the cell as it stands right after the command.\n */\nexport function completeCellContent(entry: Cell, post: Record<string, unknown> | null | undefined): Cell {\n if (entry === null) return null;\n if (!CONTENT_TOUCH.some((k) => k in entry)) return entry;\n const out: Record<string, unknown> = {};\n for (const k of CONTENT_KEYS) out[k] = post && post[k] !== undefined ? post[k] : null;\n if (out.v === null) delete out.t; // Univer stores no type without a value; t:null is not a content write\n if (\"s\" in entry) out.s = entry.s;\n return out;\n}\n\nfunction cellsOf(m: SheetMutation): CellMatrix {\n return (m.params.cellValue as CellMatrix | undefined) ?? {};\n}\nfunction forEachCell(cells: CellMatrix, fn: (r: number, c: number, v: Cell) => void) {\n for (const r of Object.keys(cells)) for (const c of Object.keys(cells[r] ?? {})) fn(Number(r), Number(c), cells[r]![c] ?? null);\n}\nfunction cellsMutation(template: SheetMutation, cells: CellMatrix): SheetMutation {\n return { id: template.id, params: { ...template.params, cellValue: cells } };\n}\nfunction putCell(cells: CellMatrix, r: number, c: number, v: Cell) {\n (cells[r] ??= {})[c] = v;\n}\nconst isEmptyMatrix = (cells: CellMatrix) => Object.values(cells).every((row) => Object.keys(row).length === 0);\n\n/** Why a set-range-values cannot be transformed by C5a, or null. */\nfunction cellBarrier(m: SheetMutation): string | null {\n if (m.params.isOverrideStyle) return \"set-range-values with isOverrideStyle (whole-style replace) is not covered\";\n let why: string | null = null;\n forEachCell(cellsOf(m), (_r, _c, v) => {\n if (why || v === null) return;\n for (const k of Object.keys(v)) {\n if (!KNOWN_CELL_KEYS.has(k)) why = `cell key \"${k}\" is not covered`;\n else if ((k === \"f\" || k === \"si\") && v[k] != null) why = \"formula content (f/si) belongs to C5b\";\n }\n if (typeof v.s === \"string\") why = \"a style id travels (style ids are seat-local; capture must send the style object)\";\n if (!why && CONTENT_TOUCH.some((k) => k in v) && !CONTENT_KEYS.every((k) => k in v || (k === \"t\" && v.v == null)))\n why = \"cell content is not completed (capture must call completeCellContent)\";\n });\n return why;\n}\n\nconst hasContent = (v: Record<string, unknown>) => CONTENT_TOUCH.some((k) => k in v);\nconst contentOf = (v: Record<string, unknown>) => {\n const out: Record<string, unknown> = {};\n for (const k of Object.keys(v)) if (k !== \"s\") out[k] = v[k];\n return out;\n};\nconst richText = (v: Record<string, unknown>) => v.p != null;\n\n/** Style keys of a style object; borders count per side (\"bd.t\", \"bd.b\" …). */\nfunction styleKeys(s: Record<string, unknown>): string[] {\n const out: string[] = [];\n for (const k of Object.keys(s)) {\n if (k === \"bd\" && s.bd && typeof s.bd === \"object\") for (const side of Object.keys(s.bd)) out.push(`bd.${side}`);\n else out.push(k);\n }\n return out;\n}\nfunction withoutStyleKeys(s: Record<string, unknown>, drop: Set<string>): Record<string, unknown> | null {\n const out: Record<string, unknown> = {};\n for (const k of Object.keys(s)) {\n if (k === \"bd\" && s.bd && typeof s.bd === \"object\") {\n const bd: Record<string, unknown> = {};\n for (const side of Object.keys(s.bd)) if (!drop.has(`bd.${side}`)) bd[side] = (s.bd as Record<string, unknown>)[side];\n if (Object.keys(bd).length) out.bd = bd;\n } else if (!drop.has(k)) out[k] = s[k];\n }\n return Object.keys(out).length ? out : null;\n}\n\n/**\n * One cell touched by both x and y (same sheet). Returns x's entry after y as a list of entries applied in\n * order (a later entry re-applies what the other side keeps), plus what each side lost.\n */\nfunction transformCell(X: Cell, Y: Cell, side: Side): { entries: Cell[]; xLost: boolean; yLost: boolean } | string {\n // A null entry deletes the whole cell.\n if (X === null || Y === null) {\n if (side === \"left\") return { entries: [X], xLost: false, yLost: true };\n // x loses: a delete of x becomes delete-then-y; x's write on a cell y deleted is dropped.\n return X === null ? { entries: [null, Y], xLost: true, yLost: false } : { entries: [], xLost: true, yLost: false };\n }\n if ((hasContent(X) && richText(X) && \"s\" in Y) || (hasContent(Y) && richText(Y) && \"s\" in X))\n return \"rich-text content concurrent with a style change on the same cell is not covered\";\n const out: Record<string, unknown> = {};\n let xLost = false;\n let yLost = false;\n // content slot: later wins\n if (hasContent(X)) {\n if (!hasContent(Y) || side === \"left\") Object.assign(out, contentOf(X));\n else xLost = true;\n if (hasContent(Y) && side === \"left\") yLost = true;\n }\n // style slot: per key, later wins; a null style clears every key\n const tail: Cell[] = [];\n if (\"s\" in X) {\n const xs = X.s as Record<string, unknown> | null;\n const ys = \"s\" in Y ? (Y.s as Record<string, unknown> | null) : undefined;\n if (ys === undefined || side === \"left\") {\n if (xs !== undefined) out.s = xs;\n if (ys !== undefined) yLost = true;\n } else if (ys === null) {\n xLost = true; // y cleared every style key after x\n } else if (xs === null) {\n // x cleared styles, y (later) set some: clear, then put y's keys back\n out.s = null;\n tail.push({ s: ys });\n xLost = true;\n } else {\n const kept = withoutStyleKeys(xs, new Set(styleKeys(ys)));\n if (kept) out.s = kept;\n if (styleKeys(xs).length !== styleKeys(kept ?? {}).length) xLost = true;\n }\n }\n return { entries: Object.keys(out).length ? [out, ...tail] : tail, xLost, yLost };\n}\n\nfunction transformCellsOverCells(x: SheetMutation, y: SheetMutation, side: Side): TransformResult {\n if (sheetOf(x) !== sheetOf(y)) return ok([x]);\n const ycells = cellsOf(y);\n const passes: CellMatrix[] = [{}];\n const lost: string[] = [];\n const dropped: string[] = [];\n let why: string | null = null;\n forEachCell(cellsOf(x), (r, c, X) => {\n if (why) return;\n const yRow = ycells[r];\n if (!yRow || !(String(c) in yRow)) {\n putCell(passes[0]!, r, c, X);\n return;\n }\n const res = transformCell(X, yRow[c] ?? null, side);\n if (typeof res === \"string\") {\n why = res;\n return;\n }\n res.entries.forEach((e, i) => putCell((passes[i] ??= {}), r, c, e));\n if (res.xLost) dropped.push(cellRef(sheetOf(x), r, c));\n if (res.yLost) lost.push(cellRef(sheetOf(x), r, c));\n });\n if (why) return barrier(why);\n const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));\n return ok(op, lost, dropped);\n}\n\nfunction transformCellsOverStructural(x: SheetMutation, s: Structural): Transformed {\n const out: CellMatrix = {};\n const dropped: string[] = [];\n forEachCell(cellsOf(x), (r, c, v) => {\n const nr = s.axis === \"row\" ? mapIndex(s.op, r) : r;\n const nc = s.axis === \"col\" ? mapIndex(s.op, c) : c;\n if (nr === null || nc === null) dropped.push(cellRef(sheetOf(x), r, c));\n else putCell(out, nr, nc, v);\n });\n return ok(isEmptyMatrix(out) ? [] : [cellsMutation(x, out)], [], dropped);\n}\n\n// ── sizes (row height, auto-height flag, auto height, column width) ────────────────────────────────\ninterface SizeOp {\n axis: Axis;\n attr: string;\n values: Map<number, unknown>;\n}\nfunction sizeOf(m: SheetMutation): SizeOp {\n const p = m.params as Record<string, unknown>;\n const values = new Map<number, unknown>();\n if (m.id === ID.rowAutoHeight) {\n for (const { row, autoHeight } of (p.rowsAutoHeightInfo as Array<{ row: number; autoHeight: unknown }>) ?? []) values.set(row, autoHeight);\n return { axis: \"row\", attr: \"ah\", values };\n }\n const axis: Axis = m.id === ID.colWidth ? \"col\" : \"row\";\n const field = m.id === ID.colWidth ? \"colWidth\" : m.id === ID.rowHeight ? \"rowHeight\" : \"autoHeightInfo\";\n const value = p[field];\n const [a0, a1] = S(axis);\n for (const r of (p.ranges as SheetRange[]) ?? [])\n for (let i = r[a0] as number; i <= (r[a1] as number); i++) {\n if (typeof value === \"number\") values.set(i, value);\n else if (m.id === ID.rowIsAuto) values.set(i, (value as Record<number, unknown> | undefined)?.[i]);\n else if ((value as Record<number, unknown> | undefined)?.[i] != null) values.set(i, (value as Record<number, unknown>)[i]);\n }\n return { axis, attr: m.id === ID.colWidth ? \"w\" : m.id === ID.rowHeight ? \"h\" : \"ia\", values };\n}\nfunction buildSize(template: SheetMutation, values: Map<number, unknown>): SheetMutation | null {\n if (values.size === 0) return null;\n const p = template.params as Record<string, unknown>;\n if (template.id === ID.rowAutoHeight)\n return { id: template.id, params: { ...p, rowsAutoHeightInfo: [...values].sort((a, b) => a[0] - b[0]).map(([row, autoHeight]) => ({ row, autoHeight })) } };\n const axis: Axis = template.id === ID.colWidth ? \"col\" : \"row\";\n const field = template.id === ID.colWidth ? \"colWidth\" : template.id === ID.rowHeight ? \"rowHeight\" : \"autoHeightInfo\";\n const [a0, a1] = S(axis);\n const first = ((p.ranges as SheetRange[]) ?? [])[0] ?? ({ startRow: 0, endRow: 0, startColumn: 0, endColumn: 0 } as SheetRange);\n const ranges = runs(values.keys()).map((r) => ({ ...first, [a0]: r.start, [a1]: r.start + r.count - 1 }));\n const uniform = typeof p[field] === \"number\" ? p[field] : undefined;\n const value = uniform !== undefined && [...values.values()].every((v) => v === uniform) ? uniform : Object.fromEntries(values);\n return { id: template.id, params: { ...p, ranges, [field]: value } };\n}\n\n// ── the pair transform ──────────────────────────────────────────────────────────────────────────────\nfunction familyOf(id: string): string {\n const e = SHEET_MUTATIONS[id];\n return e && e.kind === \"covered\" ? e.family : \"\";\n}\n\n/** x over y for single mutations. */\nexport function transformMutation(x: SheetMutation, y: SheetMutation, side: Side): TransformResult {\n for (const m of [x, y]) {\n const e = SHEET_MUTATIONS[m.id];\n if (!e) return barrier(`${m.id} is not in the registry`);\n if (e.kind !== \"covered\") return barrier(`${m.id}: ${e.kind === \"barrier\" ? `barrier until ${e.until} (${e.reason})` : \"never travels\"}`);\n if (m.id === ID.values) {\n const why = cellBarrier(m);\n if (why) return barrier(why);\n }\n }\n const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];\n if (pb) return barrier(`${x.id} × ${y.id}: ${pb.reason}${pb.seed === null ? \"\" : ` (fuzz seed ${pb.seed})`}`);\n if (sheetOf(x) !== sheetOf(y)) return ok([x]);\n\n const fx = familyOf(x.id);\n const fy = familyOf(y.id);\n const sy = structuralOf(y);\n const sx = structuralOf(x);\n\n // structural over structural\n if (sx && sy) {\n if (sx.axis !== sy.axis) return ok([x]);\n const out = transformAxis(sx.op, sy.op, side);\n if (!out) return barrier(`${x.id} over ${y.id}: moved blocks overlap in part, or the block would split`);\n const dropped = out.length === 0 && sx.op.kind === \"move\" ? [`${sheetOf(x)}: moved ${sx.axis}s`] : [];\n return ok(out.map((o) => buildStructural(x, sx.axis, o)), [], dropped);\n }\n\n // anything over structural: coordinates move\n if (sy) {\n if (fx === \"cell\") return transformCellsOverStructural(x, sy);\n if (fx === \"merge\") {\n const kept: SheetRange[] = [];\n const dropped: string[] = [];\n for (const r of mergeRanges(x)) {\n const t = mergeThrough(sy, r).range;\n if (t) kept.push(t);\n else dropped.push(rangeRef(sheetOf(x), r));\n }\n return ok(kept.length ? [withRanges(x, kept)] : [], [], x.id === ID.addMerge ? dropped : []);\n }\n if (fx === \"size\") {\n const size = sizeOf(x);\n if (size.axis !== sy.axis) return ok([x]);\n const next = new Map<number, unknown>();\n for (const [i, v] of size.values) {\n const m = mapIndex(sy.op, i);\n if (m !== null) next.set(m, v);\n }\n const built = buildSize(x, next);\n return ok(built ? [built] : []);\n }\n return ok([x]); // name\n }\n\n // structural over others\n if (sx) {\n if (fy === \"cell\") {\n // x removes rows/columns holding y's cells: y's author is told (S3).\n const lost: string[] = [];\n forEachCell(cellsOf(y), (r, c) => {\n if ((sx.axis === \"row\" ? mapIndex(sx.op, r) : mapIndex(sx.op, c)) === null) lost.push(cellRef(sheetOf(y), r, c));\n });\n return ok([x], lost);\n }\n if (fy !== \"merge\" || y.id !== ID.addMerge) return ok([x]);\n // y added merges this seat already holds; the raw structural mutation leaves the ones it cuts through\n // where they were, so the fixups the command would have made travel with x.\n const remove: SheetRange[] = [];\n const add: SheetRange[] = [];\n for (const r of mergeRanges(y)) {\n const t = mergeThrough(sx, r);\n if (!t.fixup) continue;\n remove.push(r);\n if (t.range) add.push(t.range);\n }\n const lostMerges = mergeRanges(y).filter((r) => mergeThrough(sx, r).range === null).map((r) => rangeRef(sheetOf(y), r));\n if (!remove.length) return ok([x], lostMerges);\n const sheet = sheetOf(x);\n const pre = sx.op.kind === \"insert\" ? [] : [mergeMutation(ID.removeMerge, sheet, remove)];\n const mid = sx.op.kind === \"insert\" ? [mergeMutation(ID.removeMerge, sheet, remove)] : [];\n return ok([...pre, x, ...mid, ...(add.length ? [mergeMutation(ID.addMerge, sheet, add)] : [])], lostMerges);\n }\n\n if (fx === \"cell\" && fy === \"cell\") return transformCellsOverCells(x, y, side);\n\n if (fx === \"merge\" && fy === \"merge\") {\n const xr = mergeRanges(x);\n const yr = mergeRanges(y);\n const hit = (r: SheetRange) => yr.some((q) => intersects(r, q));\n const sheet = sheetOf(x);\n if (x.id === ID.addMerge && y.id === ID.addMerge) {\n if (!xr.some(hit)) return ok([x]);\n if (side === \"left\") {\n // the later merge stands: clear what it overlaps, then add it\n const lost = yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q));\n return ok([mergeMutation(ID.removeMerge, sheet, xr.filter(hit)), x], lost);\n }\n const kept = xr.filter((r) => !hit(r));\n return ok(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));\n }\n if (x.id === ID.addMerge && y.id === ID.removeMerge) {\n if (side === \"left\" || !xr.some(hit)) return ok([x], side === \"left\" && xr.some(hit) ? yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q)) : []);\n const kept = xr.filter((r) => !hit(r));\n return ok(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));\n }\n if (x.id === ID.removeMerge && y.id === ID.addMerge) {\n // Univer removes every merge a range intersects, so x would also take y's merge with it.\n const touched = yr.filter((q) => xr.some((r) => intersects(r, q)));\n if (!touched.length) return ok([x]);\n if (side === \"left\") return ok([x], touched.map((q) => rangeRef(sheet, q)));\n return ok([x, mergeMutation(ID.addMerge, sheet, touched)], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));\n }\n return ok([x]); // remove over remove: idempotent\n }\n\n if (fx === \"size\" && fy === \"size\") {\n const a = sizeOf(x);\n const b = sizeOf(y);\n if (a.axis !== b.axis || a.attr !== b.attr) return ok([x]);\n if (side === \"left\") {\n const lost = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);\n return ok([x], lost);\n }\n const next = new Map([...a.values].filter(([i]) => !b.values.has(i)));\n const built = buildSize(x, next);\n const dropped = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);\n return ok(built ? [built] : [], [], dropped);\n }\n\n if (fx === \"name\" && fy === \"name\") {\n if (side === \"left\") return ok([x], [`${sheetOf(x)}: name \"${String(y.params.name)}\"`]);\n return ok([], [], [`${sheetOf(x)}: name \"${String(x.params.name)}\"`]);\n }\n\n // different families of different kinds commute (cells × merges, cells × sizes, merges × sizes, name × any)\n return ok([x]);\n}\n\n// ── groups ──────────────────────────────────────────────────────────────────────────────────────────\ninterface Acc {\n lost: string[];\n dropped: string[];\n}\ntype Pair = [SheetMutation[], SheetMutation[]] | Barrier;\nconst blocked = (p: Pair): p is Barrier => !Array.isArray(p);\n\n/** Transforms two sequences against each other: [xs after ys, ys after xs]. */\nfunction tSeq(xs: SheetMutation[], ys: SheetMutation[], side: Side, acc: Acc): Pair {\n if (xs.length === 0 || ys.length === 0) return [xs, ys];\n if (xs.length === 1 && ys.length === 1) {\n const a = transformMutation(xs[0]!, ys[0]!, side);\n if (isBarrier(a)) return a;\n const b = transformMutation(ys[0]!, xs[0]!, flip(side));\n if (isBarrier(b)) return b;\n acc.lost.push(...a.lost);\n acc.dropped.push(...a.dropped);\n return [a.op, b.op];\n }\n if (xs.length > 1) {\n const first = tSeq([xs[0]!], ys, side, acc);\n if (blocked(first)) return first;\n const rest = tSeq(xs.slice(1), first[1], side, acc);\n if (blocked(rest)) return rest;\n return [[...first[0], ...rest[0]], rest[1]];\n }\n const first = tSeq(xs, [ys[0]!], side, acc);\n if (blocked(first)) return first;\n const rest = tSeq(first[0], ys.slice(1), side, acc);\n if (blocked(rest)) return rest;\n return [rest[0], [...first[1], ...rest[1]]];\n}\n\n/** Command group x rewritten to apply after command group y. One Barrier makes the whole group a barrier. */\nexport function transformGroup(x: SheetGroup, y: SheetGroup, side: Side): TransformResult {\n const acc: Acc = { lost: [], dropped: [] };\n const r = tSeq([...x], [...y], side, acc);\n if (blocked(r)) return r;\n return { op: r[0], lost: [...new Set(acc.lost)], dropped: [...new Set(acc.dropped)] };\n}\n\n/** The OpTransformer the C2 session takes (`@ai-matrx/data/realtime/collab`), for sheet command groups. */\nexport const sheetTransformer = {\n version: SHEET_TRANSFORMER_VERSION,\n transform(x: SheetGroup, y: SheetGroup, side: Side): { op: SheetMutation[] | null; lost: string[]; dropped: string[] } | Barrier {\n const r = transformGroup(x, y, side);\n if (isBarrier(r)) return r;\n return { op: r.op.length ? r.op : null, lost: r.lost, dropped: r.dropped };\n },\n compose(a: SheetGroup, b: SheetGroup): SheetMutation[] {\n return [...a, ...b];\n },\n isNoop(op: SheetGroup): boolean {\n return op.length === 0;\n },\n};\n","/**\n * One-dimensional structural algebra for rows and columns: insert, remove and move, the index map each\n * induces, and S-over-S transforms. Index arithmetic is ours (not Univer's ref-range helpers) because ties\n * need the side rule and overlapping removes must subtract, which no free helper does.\n *\n * Semantics pinned to Univer 1.0.4:\n * - insert(at, n): new rows occupy [at, at+n); old row i >= at moves to i+n (the row AT `at` moves down).\n * - remove(start, n): rows [start, start+n) go; i >= start+n moves to i-n.\n * - move(from, n, to): `moveMatrixArray` — rows [from, from+n) are placed before old row `to`. Forward\n * (to >= from+n): block lands at [to-n, to). Backward (to < from): block lands at [to, to+n). A `to` in\n * [from, from+n] moves nothing (Univer throws for [from, from+n)); we treat it as a no-op.\n */\nimport type { Side } from \"./types\";\n\nexport type Axis = \"row\" | \"col\";\n\nexport type AxisOp =\n | { kind: \"insert\"; at: number; count: number }\n | { kind: \"remove\"; start: number; count: number }\n | { kind: \"move\"; from: number; count: number; to: number };\n\nexport function isNoopMove(op: { from: number; count: number; to: number }): boolean {\n return op.count <= 0 || (op.to >= op.from && op.to <= op.from + op.count);\n}\n\n/** Where the moved block starts after the move. */\nexport function movedBlockStart(op: { from: number; count: number; to: number }): number {\n return op.to > op.from ? op.to - op.count : op.to;\n}\n\n/** Old index → new index, or null when the index is removed. */\nexport function mapIndex(op: AxisOp, i: number): number | null {\n switch (op.kind) {\n case \"insert\":\n return i >= op.at ? i + op.count : i;\n case \"remove\":\n if (i < op.start) return i;\n if (i < op.start + op.count) return null;\n return i - op.count;\n case \"move\": {\n if (isNoopMove(op)) return i;\n const { from, count, to } = op;\n if (i >= from && i < from + count) return movedBlockStart(op) + (i - from);\n if (to > from) return i >= from + count && i < to ? i - count : i;\n return i >= to && i < from ? i + count : i;\n }\n }\n}\n\n/** Contiguous runs of a sorted, de-duplicated index list. */\nexport function runs(indices: Iterable<number>): Array<{ start: number; count: number }> {\n const sorted = [...new Set(indices)].sort((a, b) => a - b);\n const out: Array<{ start: number; count: number }> = [];\n for (const i of sorted) {\n const last = out[out.length - 1];\n if (last && last.start + last.count === i) last.count++;\n else out.push({ start: i, count: 1 });\n }\n return out;\n}\n\n/**\n * A gap (insert position: \"before old row p\") through a move. Gaps strictly inside the block ride with\n * it; any other gap is a gap of the non-block rows. At the move's own target gap an insert lands BEFORE\n * the block (side-independent; `transformAxis(move, insert)` keeps the same order).\n */\nfunction mapGapThroughMove(p: number, mv: { from: number; count: number; to: number }): number {\n const { from, count, to } = mv;\n if (p > from && p < from + count) return movedBlockStart(mv) + (p - from);\n const g = p <= from ? p : p - count; // gap index among the non-block rows\n const tg = to <= from ? to : to - count;\n return g <= tg ? g : g + count;\n}\n\n/**\n * x over y on ONE axis. Returns the list of axis ops that apply after y (empty = x vanished), or null when\n * the pair has no transform (the caller turns that into a barrier).\n */\nexport function transformAxis(x: AxisOp, y: AxisOp, side: Side): AxisOp[] | null {\n if (y.kind === \"move\" && isNoopMove(y)) return [x];\n if (x.kind === \"move\" && isNoopMove(x)) return [];\n switch (x.kind) {\n case \"insert\": {\n if (y.kind === \"insert\") {\n if (x.at < y.at || (x.at === y.at && side === \"left\")) return [x];\n return [{ ...x, at: x.at + y.count }];\n }\n if (y.kind === \"remove\") {\n if (x.at <= y.start) return [x];\n if (x.at >= y.start + y.count) return [{ ...x, at: x.at - y.count }];\n return [{ ...x, at: y.start }]; // an insert inside a removed span survives at its start\n }\n return [{ ...x, at: mapGapThroughMove(x.at, y) }];\n }\n case \"remove\": {\n const kept: number[] = [];\n for (let i = x.start; i < x.start + x.count; i++) {\n const m = mapIndex(y, i);\n if (m !== null) kept.push(m);\n }\n if (y.kind === \"insert\" || y.kind === \"remove\" || y.kind === \"move\") {\n // Removes are emitted highest first so each index is still valid when it applies.\n return runs(kept)\n .reverse()\n .map((r) => ({ kind: \"remove\" as const, start: r.start, count: r.count }));\n }\n return null;\n }\n case \"move\": {\n if (y.kind === \"insert\") {\n const inside = y.at > x.from && y.at < x.from + x.count;\n const from = inside || y.at > x.from ? x.from : x.from + y.count;\n const count = inside ? x.count + y.count : x.count;\n const to = x.to >= y.at ? x.to + y.count : x.to;\n const out = { kind: \"move\" as const, from, count, to };\n return isNoopMove(out) ? [] : [out];\n }\n if (y.kind === \"remove\") {\n const kept: number[] = [];\n for (let i = x.from; i < x.from + x.count; i++) {\n const m = mapIndex(y, i);\n if (m !== null) kept.push(m);\n }\n if (kept.length === 0) return [];\n const r = runs(kept);\n if (r.length !== 1) return null;\n const to = x.to <= y.start ? x.to : x.to >= y.start + y.count ? x.to - y.count : y.start;\n const out = { kind: \"move\" as const, from: r[0]!.start, count: r[0]!.count, to };\n return isNoopMove(out) ? [] : [out];\n }\n // move over move. The same rows moved twice: the later move wins, the earlier one is dropped.\n // Blocks that only partly overlap have no transform yet.\n const overlap = Math.min(x.from + x.count, y.from + y.count) - Math.max(x.from, y.from);\n if (overlap > 0) {\n if (x.from !== y.from || x.count !== y.count) return null;\n if (side === \"right\") return [];\n const out = { kind: \"move\" as const, from: movedBlockStart(y), count: x.count, to: mapGapThroughMove(x.to, y) };\n return isNoopMove(out) ? [] : [out];\n }\n // Disjoint blocks: x's rows through y must stay contiguous; the target gap goes through y.\n const mapped: number[] = [];\n for (let i = x.from; i < x.from + x.count; i++) mapped.push(mapIndex(y, i)!);\n const r = runs(mapped);\n if (r.length !== 1) return null;\n let to: number;\n if (x.to > y.from && x.to < y.from + y.count) to = movedBlockStart(y) + (x.to - y.from);\n else to = mapGapThroughMove(x.to, y) + (x.to === y.to && side === \"right\" ? y.count : 0); // same target: later block first\n const out = { kind: \"move\" as const, from: r[0]!.start, count: r[0]!.count, to };\n if (to > out.from && to < out.from + out.count) return null;\n return isNoopMove(out) ? [] : [out];\n }\n }\n}\n"],"mappings":"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","names":["to","out","r","barrier","first","rest"]}
package/dist/docs.cjs CHANGED
@@ -45,6 +45,9 @@ function takeCovered(snapshot) {
45
45
  }
46
46
 
47
47
  // src/docs/document-model.ts
48
+ var RICH_TEXT_EDITING_ID = "doc.mutation.rich-text-editing";
49
+ var COMMAND_TYPE = 0;
50
+ var DEPTH_GUARDED = /* @__PURE__ */ Symbol.for("ai-matrx.office.docs.command-depth-guard");
48
51
  var DOCUMENT_SAVE_DELAY_MS = 2500;
49
52
  var viewIds = 0;
50
53
  var DocumentModel = (_class = class {
@@ -61,17 +64,21 @@ var DocumentModel = (_class = class {
61
64
  __init6() {this.knownSnapshots = /* @__PURE__ */ new Set()}
62
65
  __init7() {this.collabListeners = /* @__PURE__ */ new Set()}
63
66
  __init8() {this.collab = null}
67
+ /** The ordered-log room (C3); exclusive with `collab` (the 0.6 relay room). */
68
+ __init9() {this.ot = null}
69
+ __init10() {this.otStarting = null}
70
+ __init11() {this.otListeners = /* @__PURE__ */ new Set()}
64
71
  /** The saved snapshot the body started from, and the room entries it already holds. */
65
- __init9() {this.baseId = null}
66
- __init10() {this.baseCovered = /* @__PURE__ */ new Set()}
67
- __init11() {this.collabStarting = null}
68
- __init12() {this.awareness = null}
69
- __init13() {this.awarenessListeners = /* @__PURE__ */ new Set()}
70
- __init14() {this.realtimeClose = null}
71
- __init15() {this.pageClose = null}
72
+ __init12() {this.baseId = null}
73
+ __init13() {this.baseCovered = /* @__PURE__ */ new Set()}
74
+ __init14() {this.collabStarting = null}
75
+ __init15() {this.awareness = null}
76
+ __init16() {this.awarenessListeners = /* @__PURE__ */ new Set()}
77
+ __init17() {this.realtimeClose = null}
78
+ __init18() {this.pageClose = null}
72
79
  /** The last view's editor, alive and off the page until a view takes it back. */
73
- __init16() {this.parked = null}
74
- constructor(handle, deps) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);_class.prototype.__init11.call(this);_class.prototype.__init12.call(this);_class.prototype.__init13.call(this);_class.prototype.__init14.call(this);_class.prototype.__init15.call(this);_class.prototype.__init16.call(this);_class.prototype.__init17.call(this);_class.prototype.__init18.call(this);_class.prototype.__init19.call(this);_class.prototype.__init20.call(this);
80
+ __init19() {this.parked = null}
81
+ constructor(handle, deps) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);_class.prototype.__init11.call(this);_class.prototype.__init12.call(this);_class.prototype.__init13.call(this);_class.prototype.__init14.call(this);_class.prototype.__init15.call(this);_class.prototype.__init16.call(this);_class.prototype.__init17.call(this);_class.prototype.__init18.call(this);_class.prototype.__init19.call(this);_class.prototype.__init20.call(this);_class.prototype.__init21.call(this);_class.prototype.__init22.call(this);_class.prototype.__init23.call(this);_class.prototype.__init24.call(this);
75
82
  this.documentId = handle.id;
76
83
  this.handle = handle;
77
84
  this.deps = deps;
@@ -124,7 +131,14 @@ var DocumentModel = (_class = class {
124
131
  const subscription = port.commandService.onMutationExecutedForCollab(
125
132
  (info, options) => this.onViewMutation(id, info, options)
126
133
  );
127
- this.views.set(id, { id, port, dispose: () => subscription.dispose() });
134
+ const view = { id, port, dispose: () => {
135
+ }, commands: [], pre: null };
136
+ const hooks = this.trackCommands(view);
137
+ view.dispose = () => {
138
+ subscription.dispose();
139
+ hooks();
140
+ };
141
+ this.views.set(id, view);
128
142
  if (!this.handle.hasPending()) {
129
143
  try {
130
144
  const mounted = port.snapshot();
@@ -137,8 +151,8 @@ var DocumentModel = (_class = class {
137
151
  return () => {
138
152
  if (detached) return;
139
153
  detached = true;
140
- const view = this.views.get(id);
141
- if (!view) return;
154
+ const view2 = this.views.get(id);
155
+ if (!view2) return;
142
156
  if (this.views.size === 1) {
143
157
  try {
144
158
  const snapshot = port.snapshot();
@@ -147,7 +161,7 @@ var DocumentModel = (_class = class {
147
161
  console.warn(`[document-model] could not keep ${this.documentId}'s last view's document`, error);
148
162
  }
149
163
  }
150
- view.dispose();
164
+ view2.dispose();
151
165
  this.views.delete(id);
152
166
  if (this.lastEditedView === id) this.lastEditedView = null;
153
167
  };
@@ -171,19 +185,74 @@ var DocumentModel = (_class = class {
171
185
  return editor;
172
186
  }
173
187
  onViewMutation(viewId, info, options) {
174
- if (this.relaying || _optionalChain([options, 'optionalAccess', _ => _.fromCollab]) || _optionalChain([options, 'optionalAccess', _2 => _2.fromChangeset])) return;
188
+ if (this.relaying || _optionalChain([options, 'optionalAccess', _7 => _7.fromCollab]) || _optionalChain([options, 'optionalAccess', _8 => _8.fromChangeset])) return;
175
189
  const view = this.views.get(viewId);
176
190
  if (!view || !view.port.editable()) return;
177
191
  this.lastEditedView = viewId;
178
192
  this.relay(info, viewId);
179
- for (const listener of this.collabListeners) listener(info);
193
+ for (const listener of this.collabListeners) listener(info, options);
194
+ if (this.otListeners.size && !_optionalChain([options, 'optionalAccess', _9 => _9.onlyLocal])) {
195
+ const m = {
196
+ id: info.id,
197
+ params: info.params,
198
+ pre: info.id === RICH_TEXT_EDITING_ID ? view.pre : null,
199
+ cmd: _nullishCoalesce(view.commands[0], () => ( null)),
200
+ content: isContentMutation(info)
201
+ };
202
+ view.pre = null;
203
+ for (const listener of Array.from(this.otListeners)) listener(m);
204
+ }
180
205
  if (isContentMutation(info)) this.markDirty();
181
206
  }
207
+ /**
208
+ * Per view: the outermost command running (a mutation's group label) and, while a room listens, the document
209
+ * before each rich-text mutation (its inverse is computed from the APPLIED actions against this copy). Univer's
210
+ * `executeCommand` has no `finally`: a command that mutates then throws never fires `onCommandExecuted`, so
211
+ * the depth is restored in a try/finally around the instance's `executeCommand` (C0 surprise 7).
212
+ */
213
+ trackCommands(view) {
214
+ const cs = view.port.commandService;
215
+ if (typeof cs.beforeCommandExecuted !== "function" || typeof cs.onCommandExecuted !== "function") return () => {
216
+ };
217
+ const before = cs.beforeCommandExecuted((info) => {
218
+ if (info.type === COMMAND_TYPE) view.commands.push(info.id);
219
+ else if (info.id === RICH_TEXT_EDITING_ID && this.otListeners.size && !this.relaying) {
220
+ try {
221
+ const snap = view.port.snapshot();
222
+ view.pre = snap ? structuredClone(snap) : null;
223
+ } catch (e3) {
224
+ view.pre = null;
225
+ }
226
+ }
227
+ });
228
+ const after = cs.onCommandExecuted((info) => {
229
+ if (info.type !== COMMAND_TYPE) return;
230
+ const at = view.commands.lastIndexOf(info.id);
231
+ if (at >= 0) view.commands.splice(at, 1);
232
+ });
233
+ const guarded = cs;
234
+ if (typeof cs.executeCommand === "function" && !guarded[DEPTH_GUARDED]) {
235
+ const original = cs.executeCommand.bind(cs);
236
+ guarded[DEPTH_GUARDED] = true;
237
+ cs.executeCommand = async (id, params, options) => {
238
+ const depth = view.commands.length;
239
+ try {
240
+ return await original(id, params, options);
241
+ } finally {
242
+ if (view.commands.length > depth) view.commands.length = depth;
243
+ }
244
+ };
245
+ }
246
+ return () => {
247
+ before.dispose();
248
+ after.dispose();
249
+ };
250
+ }
182
251
  /** The unit id a view's document has (what a replayed mutation must be addressed to). */
183
252
  unitIdOf(view) {
184
253
  try {
185
- return _nullishCoalesce(_nullishCoalesce(_optionalChain([view, 'access', _3 => _3.port, 'access', _4 => _4.unitId, 'optionalCall', _5 => _5()]), () => ( _optionalChain([view, 'access', _6 => _6.port, 'access', _7 => _7.snapshot, 'call', _8 => _8(), 'optionalAccess', _9 => _9.id]))), () => ( null));
186
- } catch (e3) {
254
+ return _nullishCoalesce(_nullishCoalesce(_optionalChain([view, 'access', _10 => _10.port, 'access', _11 => _11.unitId, 'optionalCall', _12 => _12()]), () => ( _optionalChain([view, 'access', _13 => _13.port, 'access', _14 => _14.snapshot, 'call', _15 => _15(), 'optionalAccess', _16 => _16.id]))), () => ( null));
255
+ } catch (e4) {
187
256
  return null;
188
257
  }
189
258
  }
@@ -216,7 +285,7 @@ var DocumentModel = (_class = class {
216
285
  /** A view could not follow an edit: say so, then show the saved version (unless this tab has unsaved edits of its own). */
217
286
  applyFailed(mutationId, error) {
218
287
  try {
219
- _optionalChain([this, 'access', _10 => _10.deps, 'access', _11 => _11.onApplyFailed, 'optionalCall', _12 => _12(this.documentId, mutationId, error)]);
288
+ _optionalChain([this, 'access', _17 => _17.deps, 'access', _18 => _18.onApplyFailed, 'optionalCall', _19 => _19(this.documentId, mutationId, error)]);
220
289
  } catch (notifyError) {
221
290
  console.warn(`[document-model] the notice for ${this.documentId}'s failed apply also failed`, notifyError);
222
291
  }
@@ -229,19 +298,24 @@ var DocumentModel = (_class = class {
229
298
  markDirty() {
230
299
  this.handle.touch();
231
300
  }
232
- __init17() {this.saving = false}
301
+ __init20() {this.saving = false}
233
302
  /**
234
303
  * The content of the version the server holds (loaded or last written). A
235
304
  * save of the same content is no save: attaching, detaching, waking or a
236
305
  * flush of an unchanged document never writes a snapshot row.
237
306
  */
238
- __init18() {this.savedFingerprint = null}
307
+ __init21() {this.savedFingerprint = null}
239
308
  /**
240
309
  * Write the body as it is now. Returns false when this tab is a collab peer
241
310
  * that does not write (the elected host writes the canonical snapshot; a
242
311
  * peer's edits reach it through the room). An explicit Save always writes.
243
312
  */
244
313
  async write(reason) {
314
+ if (this.ot) {
315
+ const wrote = await this.ot.write(reason);
316
+ if (wrote) _optionalChain([this, 'access', _20 => _20.deps, 'access', _21 => _21.onSaved, 'optionalCall', _22 => _22(this.documentId, reason === "manual" ? "manual" : "autosave")]);
317
+ return wrote;
318
+ }
245
319
  const snapshot = this.latest();
246
320
  if (!snapshot) throw new Error("There is no open document to save.");
247
321
  if (this.collab && !this.collab.isHost() && reason !== "manual") return false;
@@ -264,7 +338,7 @@ var DocumentModel = (_class = class {
264
338
  this.saving = false;
265
339
  }
266
340
  if (this.views.size === 0) this.stored = snapshot;
267
- _optionalChain([this, 'access', _13 => _13.deps, 'access', _14 => _14.onSaved, 'optionalCall', _15 => _15(this.documentId, origin)]);
341
+ _optionalChain([this, 'access', _23 => _23.deps, 'access', _24 => _24.onSaved, 'optionalCall', _25 => _25(this.documentId, origin)]);
268
342
  return true;
269
343
  }
270
344
  hasUnsaved() {
@@ -286,7 +360,7 @@ var DocumentModel = (_class = class {
286
360
  * person chooses; `overUnsaved` is "Take theirs" (`./documentModels.ts`).
287
361
  */
288
362
  async onRemoteSnapshot(snapshotId, { overUnsaved = false } = {}) {
289
- if (this.collab) return;
363
+ if (this.collab || this.ot) return;
290
364
  if (this.knownSnapshots.has(snapshotId)) return;
291
365
  if (this.saving) return;
292
366
  if (this.hasUnsaved() && !overUnsaved) {
@@ -305,8 +379,9 @@ var DocumentModel = (_class = class {
305
379
  * room the peers reload it and the shared log is emptied.
306
380
  */
307
381
  replaceContent(row) {
382
+ if (this.ot) return this.ot.replace(row.snapshot);
308
383
  this.show(row);
309
- _optionalChain([this, 'access', _16 => _16.collab, 'optionalAccess', _17 => _17.announceReplaced, 'call', _18 => _18(row.id)]);
384
+ _optionalChain([this, 'access', _26 => _26.collab, 'optionalAccess', _27 => _27.announceReplaced, 'call', _28 => _28(row.id)]);
310
385
  }
311
386
  /** A peer replaced the document: show the newest save (once). */
312
387
  async onPeerReplaced() {
@@ -329,7 +404,7 @@ var DocumentModel = (_class = class {
329
404
  this.relaying = true;
330
405
  try {
331
406
  for (const view of this.views.values()) view.port.remount(snapshot);
332
- _optionalChain([this, 'access', _19 => _19.parked, 'optionalAccess', _20 => _20.remount, 'call', _21 => _21(snapshot)]);
407
+ _optionalChain([this, 'access', _29 => _29.parked, 'optionalAccess', _30 => _30.remount, 'call', _31 => _31(snapshot)]);
333
408
  } finally {
334
409
  this.relaying = false;
335
410
  }
@@ -340,7 +415,7 @@ var DocumentModel = (_class = class {
340
415
  * binds to. Local edits from any view go out once; a peer's edit is applied
341
416
  * to every view.
342
417
  */
343
- __init19() {this.virtualCommandService = {
418
+ __init22() {this.virtualCommandService = {
344
419
  onMutationExecutedForCollab: (listener) => {
345
420
  this.collabListeners.add(listener);
346
421
  return { dispose: () => this.collabListeners.delete(listener) };
@@ -388,7 +463,79 @@ var DocumentModel = (_class = class {
388
463
  }
389
464
  return this.collabStarting;
390
465
  }
466
+ /** The model as the ordered-log room sees it (COLLAB-DESIGN §6.7: the model is the client, not the view). */
467
+ __init23() {this.otPort = {
468
+ onLocal: (listener) => {
469
+ this.otListeners.add(listener);
470
+ return () => void this.otListeners.delete(listener);
471
+ },
472
+ applyRemote: (id, params) => {
473
+ if (this.views.size === 0) throw new Error("no view of the document is mounted");
474
+ this.relaying = true;
475
+ try {
476
+ for (const view of this.views.values()) {
477
+ const unitId = this.unitIdOf(view);
478
+ const input = Array.isArray(params.actions) ? params.actions.length : 0;
479
+ const p = { ...params, ...unitId ? { unitId } : {}, textRanges: null, noNeedSetTextRange: true };
480
+ const ok = view.port.commandService.syncExecuteCommand(id, p, { onlyLocal: true, fromCollab: true });
481
+ if (ok === false) throw new Error(`"${id}" was refused by the editor`);
482
+ if (input > 0 && Array.isArray(p.actions) && p.actions.length === 0) throw new Error(`"${id}" was emptied by the editor`);
483
+ }
484
+ } finally {
485
+ this.relaying = false;
486
+ }
487
+ if (isContentMutation({ id, type: 2, params })) this.markDirty();
488
+ },
489
+ snapshot: () => this.latest(),
490
+ load: (snapshot) => {
491
+ const s2 = snapshot;
492
+ this.stored = s2;
493
+ this.savedFingerprint = contentFingerprint(s2);
494
+ this.relaying = true;
495
+ try {
496
+ for (const view of this.views.values()) view.port.remount(s2);
497
+ _optionalChain([this, 'access', _32 => _32.parked, 'optionalAccess', _33 => _33.remount, 'call', _34 => _34(s2)]);
498
+ } finally {
499
+ this.relaying = false;
500
+ }
501
+ },
502
+ undoTargets: () => {
503
+ const out = [];
504
+ for (const view of this.views.values()) {
505
+ const unitId = this.unitIdOf(view);
506
+ const service = _optionalChain([view, 'access', _35 => _35.port, 'access', _36 => _36.undoRedo, 'optionalCall', _37 => _37()]);
507
+ if (unitId && service) out.push({ service, unitId });
508
+ }
509
+ return out;
510
+ },
511
+ markDirty: () => this.markDirty()
512
+ }}
513
+ /** Join the document's ordered-log room once (C3). Exclusive with `startCollab`. */
514
+ startOtRoom(factory) {
515
+ if (this.ot || this.collab) return Promise.resolve();
516
+ if (!this.otStarting) {
517
+ this.otStarting = factory(this.otPort, (awareness) => {
518
+ this.awareness = awareness;
519
+ for (const listener of Array.from(this.awarenessListeners)) listener();
520
+ }).then((handle) => {
521
+ if (!handle) return;
522
+ if (this.views.size === 0) {
523
+ handle.stop();
524
+ return;
525
+ }
526
+ this.ot = handle;
527
+ }).finally(() => {
528
+ this.otStarting = null;
529
+ });
530
+ }
531
+ return this.otStarting;
532
+ }
533
+ /** Which co-editing room this document is in right now. */
534
+ collabMode() {
535
+ return this.ot ? "ordered" : this.collab ? "relay" : null;
536
+ }
391
537
  isCollabHost() {
538
+ if (this.ot) return this.ot.isSaver();
392
539
  return this.collab ? this.collab.isHost() : true;
393
540
  }
394
541
  getAwareness() {
@@ -414,11 +561,13 @@ var DocumentModel = (_class = class {
414
561
  * so a collaborator's save still reaches the body a returning view boots from.
415
562
  */
416
563
  rest() {
417
- _optionalChain([this, 'access', _22 => _22.collab, 'optionalAccess', _23 => _23.stop, 'call', _24 => _24()]);
564
+ _optionalChain([this, 'access', _38 => _38.collab, 'optionalAccess', _39 => _39.stop, 'call', _40 => _40()]);
418
565
  this.collab = null;
566
+ _optionalChain([this, 'access', _41 => _41.ot, 'optionalAccess', _42 => _42.stop, 'call', _43 => _43()]);
567
+ this.ot = null;
419
568
  this.awareness = null;
420
569
  }
421
- __init20() {this.closed = false}
570
+ __init24() {this.closed = false}
422
571
  close() {
423
572
  this.closed = true;
424
573
  const parked = this.parked;
@@ -430,9 +579,9 @@ var DocumentModel = (_class = class {
430
579
  console.warn(`[document-model] could not dispose ${this.documentId}'s kept editor`, error);
431
580
  }
432
581
  }
433
- _optionalChain([this, 'access', _25 => _25.realtimeClose, 'optionalCall', _26 => _26()]);
582
+ _optionalChain([this, 'access', _44 => _44.realtimeClose, 'optionalCall', _45 => _45()]);
434
583
  this.realtimeClose = null;
435
- _optionalChain([this, 'access', _27 => _27.pageClose, 'optionalCall', _28 => _28()]);
584
+ _optionalChain([this, 'access', _46 => _46.pageClose, 'optionalCall', _47 => _47()]);
436
585
  this.pageClose = null;
437
586
  }
438
587
  }, _class);