@ai-matrx/office 0.8.24 → 0.8.25

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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## 0.8.24
3
+ ## 0.8.25
4
4
  ### C9: comment anchors that follow concurrent edits
5
5
 
6
6
  - **Docs:** `addCommentAnchorActions(body, start, end, id)` anchors a passage with a `COMMENT` custom range (Univer's own builder, so the op has the link family's shape C0 proved); `commentAnchorsOf(body)` reads every anchor back (split pieces joined, Univer's inclusive end as `[start, end)`); `removeCommentAnchorActions` takes a cancelled draft's anchor out; `commentPartAnchor` / `anchorIdOfPartAnchor` are the thread's `part_anchor` (`anchor:<id>`, quote as `label`). Fuzz on the C0 corpora: anchor × every captured family and anchor × anchor, 0 divergences in 180,000 checks at 2,000 seeds; red check without a transform.
@@ -3564,17 +3564,65 @@ function rebaseSheetUndoStack(items, remote, unitId) {
3564
3564
  function createSheetsOtAdapter(port, hooks = {}) {
3565
3565
  let queue = [];
3566
3566
  let draining = false;
3567
+ const lazy = typeof port.beforeUndo === "function";
3568
+ let pending = [];
3569
+ let pendingBase = 0;
3570
+ let applied = 0;
3571
+ let currentAt = /* @__PURE__ */ new WeakMap();
3572
+ const PENDING_CAP = 2e3;
3573
+ const now = () => typeof performance !== "undefined" ? performance.now() : Date.now();
3574
+ const stacksOfTargets = () => port.undoTargets().flatMap((t) => {
3575
+ const stacks = undoStacksOf2(t.service);
3576
+ return stacks ? [stacks.undo, stacks.redo].map((map) => ({ items: map.get(t.unitId), unitId: t.unitId, isUndo: map === stacks.undo })) : [];
3577
+ });
3578
+ const markNew = (items) => {
3579
+ for (let i = items.length - 1; i >= 0 && !currentAt.has(items[i]); i--) currentAt.set(items[i], applied);
3580
+ };
3581
+ const catchUpItem = (item, unitId) => {
3582
+ const from = currentAt.get(item) ?? applied;
3583
+ for (let k = from - pendingBase; k < pending.length; k++) if (rebaseSheetUndoStack([item], pending[k], unitId) > 0) return false;
3584
+ currentAt.set(item, applied);
3585
+ return true;
3586
+ };
3587
+ const catchUp = () => {
3588
+ if (!pending.length) return;
3589
+ const t0 = now();
3590
+ let dropped = 0;
3591
+ for (const { items, unitId } of stacksOfTargets()) {
3592
+ if (!items?.length) continue;
3593
+ for (let i = items.length - 1; i >= 0; i--)
3594
+ if (!catchUpItem(items[i], unitId)) {
3595
+ items.splice(i, 1);
3596
+ dropped++;
3597
+ }
3598
+ }
3599
+ pending = [];
3600
+ pendingBase = applied;
3601
+ hooks.onUndoWork?.(now() - t0, "catch_up");
3602
+ if (dropped) hooks.onUndoRebased?.(dropped);
3603
+ };
3604
+ if (lazy) port.beforeUndo(catchUp);
3567
3605
  const applyNow = (op) => {
3568
3606
  for (const m of op) port.applyRemote(m);
3607
+ const t0 = now();
3569
3608
  let dropped = 0;
3570
- for (const t of port.undoTargets()) {
3571
- const stacks = undoStacksOf2(t.service);
3572
- if (!stacks) continue;
3573
- for (const map of [stacks.undo, stacks.redo]) {
3574
- const items = map.get(t.unitId);
3575
- if (items?.length) dropped += rebaseSheetUndoStack(items, op, t.unitId);
3609
+ if (!lazy) {
3610
+ for (const { items, unitId } of stacksOfTargets()) if (items?.length) dropped += rebaseSheetUndoStack(items, op, unitId);
3611
+ } else if (!isNoopSheetOp(op)) {
3612
+ for (const { items, unitId, isUndo } of stacksOfTargets()) {
3613
+ if (!items?.length) continue;
3614
+ markNew(items);
3615
+ const top = items[items.length - 1];
3616
+ if (isUndo && (!catchUpItem(top, unitId) || rebaseSheetUndoStack([top], op, unitId) > 0)) {
3617
+ items.pop();
3618
+ dropped++;
3619
+ } else if (isUndo) currentAt.set(top, applied + 1);
3576
3620
  }
3621
+ pending.push(op);
3622
+ applied++;
3623
+ if (pending.length > PENDING_CAP) catchUp();
3577
3624
  }
3625
+ hooks.onUndoWork?.(now() - t0, "remote");
3578
3626
  hooks.onUndoRebased?.(dropped);
3579
3627
  port.markDirty();
3580
3628
  };
@@ -3612,6 +3660,9 @@ function createSheetsOtAdapter(port, hooks = {}) {
3612
3660
  stacks?.undo.delete(t.unitId);
3613
3661
  stacks?.redo.delete(t.unitId);
3614
3662
  }
3663
+ pending = [];
3664
+ pendingBase = applied;
3665
+ currentAt = /* @__PURE__ */ new WeakMap();
3615
3666
  },
3616
3667
  snapshot: () => port.snapshot(),
3617
3668
  async hash() {
@@ -3799,6 +3850,8 @@ var REMOVE_MERGE = "sheet.mutation.remove-worksheet-merge";
3799
3850
  var SHEET_NAME = "sheet.mutation.set-worksheet-name";
3800
3851
  var INSERT_SHEET = "sheet.mutation.insert-sheet";
3801
3852
  var RESHAPE = /* @__PURE__ */ new Set(["sheet.mutation.set-worksheet-row-count", "sheet.mutation.set-worksheet-column-count", "sheet.mutation.remove-sheet", INSERT_SHEET]);
3853
+ var UNDO = "univer.command.undo";
3854
+ var REDO = "univer.command.redo";
3802
3855
  var DEPTH_GUARD = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets.command-depth-guard");
3803
3856
  var json = (v) => v === void 0 ? v : JSON.parse(JSON.stringify(v));
3804
3857
  var flagged = (options) => {
@@ -3808,6 +3861,7 @@ var flagged = (options) => {
3808
3861
  function univerSheetsOtPort(o) {
3809
3862
  const cs = o.commandService;
3810
3863
  const listeners = /* @__PURE__ */ new Set();
3864
+ const undoWatchers = /* @__PURE__ */ new Set();
3811
3865
  const idle = [];
3812
3866
  const pre = /* @__PURE__ */ new WeakMap();
3813
3867
  const tracker = { stack: [], settle: () => settle() };
@@ -3864,6 +3918,7 @@ function univerSheetsOtPort(o) {
3864
3918
  if (tracker.stack.length === 0 && !group) for (const fn of idle.splice(0)) fn();
3865
3919
  }
3866
3920
  const before = cs.beforeCommandExecuted((info, options) => {
3921
+ if (info.id === UNDO || info.id === REDO) for (const fn of [...undoWatchers]) fn();
3867
3922
  if (info.type === COMMAND) {
3868
3923
  if (tracker.stack.length === 0 && !group) group = openGroup(info.id);
3869
3924
  tracker.stack.push(info.id);
@@ -4121,8 +4176,13 @@ function univerSheetsOtPort(o) {
4121
4176
  const service = o.undoRedo?.();
4122
4177
  return u && service ? [{ service, unitId: u }] : [];
4123
4178
  },
4179
+ beforeUndo(fn) {
4180
+ undoWatchers.add(fn);
4181
+ return () => void undoWatchers.delete(fn);
4182
+ },
4124
4183
  markDirty: () => o.markDirty(),
4125
4184
  dispose() {
4185
+ undoWatchers.clear();
4126
4186
  before.dispose();
4127
4187
  after.dispose();
4128
4188
  collab.dispose();