@textbus/collaborate 4.1.0-alpha.0 → 4.1.0-alpha.1

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.
@@ -33,6 +33,4 @@ export declare class CollabHistory implements History {
33
33
  forward(): void;
34
34
  clear(): void;
35
35
  destroy(): void;
36
- private getAbstractSelection;
37
- private getRelativeCursorLocation;
38
36
  }
@@ -1,7 +1,19 @@
1
1
  import { Observable } from '@tanbo/stream';
2
- import { Component, Registry, Scheduler, Selection, Slot } from '@textbus/core';
3
- import { AbstractType, Doc as YDoc, Map as YMap, Text as YText } from 'yjs';
2
+ import { Component, Registry, Scheduler, Selection, Slot, AbstractSelection } from '@textbus/core';
3
+ import { AbstractType, Doc as YDoc, Map as YMap, RelativePosition, Text as YText } from 'yjs';
4
4
  import { SubModelLoader } from './sub-model-loader';
5
+ export interface RelativePositionRecord {
6
+ doc: YDoc;
7
+ position: RelativePosition;
8
+ }
9
+ export interface CursorPosition {
10
+ anchor: RelativePositionRecord;
11
+ focus: RelativePositionRecord;
12
+ }
13
+ export interface CollaborateHistorySelectionPosition {
14
+ before: CursorPosition | null;
15
+ after: CursorPosition | null;
16
+ }
5
17
  declare class SlotMap {
6
18
  private slotAndYTextMap;
7
19
  private yTextAndSlotMap;
@@ -31,6 +43,9 @@ export declare class Collaborate {
31
43
  constructor(scheduler: Scheduler, registry: Registry, selection: Selection, subModelLoader: SubModelLoader);
32
44
  syncRootComponent(yDoc: YDoc, sharedComponent: YMap<any>, localComponent: Component<any>): void;
33
45
  syncRootSlot(yDoc: YDoc, sharedSlot: YText, localSlot: Slot): void;
46
+ getAbstractSelection(position: CursorPosition): AbstractSelection | null;
47
+ getRelativeCursorLocation(): CursorPosition | null;
48
+ restoreCursorPosition(position: CursorPosition | null): void;
34
49
  private initSyncEvent;
35
50
  private syncComponent;
36
51
  private syncSlot;
@@ -1,7 +1,8 @@
1
+ import { HocuspocusProvider } from '@hocuspocus/provider';
1
2
  import { HocuspocusProviderConfiguration } from '@hocuspocus/provider';
2
3
  import { SyncConnector } from '../sync-connector';
3
4
  export declare class HocuspocusConnector extends SyncConnector {
4
- private provide;
5
+ provide: HocuspocusProvider;
5
6
  constructor(config: HocuspocusProviderConfiguration);
6
7
  setLocalStateField(key: string, data: Record<string, any>): void;
7
8
  onDestroy(): void;
@@ -1,7 +1,8 @@
1
1
  import { Doc as YDoc } from 'yjs';
2
+ import { WebsocketProvider } from 'y-websocket';
2
3
  import { SyncConnector } from '../sync-connector';
3
4
  export declare class YWebsocketConnector extends SyncConnector {
4
- private provide;
5
+ provide: WebsocketProvider;
5
6
  constructor(url: string, roomName: string, yDoc: YDoc);
6
7
  setLocalStateField(key: string, data: Record<string, any>): void;
7
8
  onDestroy(): void;
@@ -3,7 +3,7 @@ import { Subject, map, filter, Subscription } from '@tanbo/stream';
3
3
  import { WebsocketProvider } from 'y-websocket';
4
4
  import { Injectable, Inject, Optional } from '@viewfly/core';
5
5
  import { makeError, ChangeOrigin, Slot, createObjectProxy, createArrayProxy, AsyncSlot, AsyncComponent, Component, Scheduler, Registry, Selection, HISTORY_STACK_SIZE, RootComponentRef, History } from '@textbus/core';
6
- import { Doc, Map, Array as Array$1, Text, UndoManager, createAbsolutePositionFromRelativePosition, createRelativePositionFromTypeIndex } from 'yjs';
6
+ import { Doc, createAbsolutePositionFromRelativePosition, createRelativePositionFromTypeIndex, Map, Array as Array$1, Text, UndoManager } from 'yjs';
7
7
 
8
8
  /**
9
9
  * 协作通信通用接口
@@ -209,11 +209,66 @@ let Collaborate = class Collaborate {
209
209
  this.initLocalSlotBySharedSlot(sharedSlot, localSlot);
210
210
  }
211
211
  else {
212
- this.initSharedSlotByLocalSlot(sharedSlot, localSlot);
212
+ yDoc.transact(() => {
213
+ this.initSharedSlotByLocalSlot(sharedSlot, localSlot);
214
+ });
213
215
  }
214
216
  this.initSyncEvent(yDoc);
215
217
  this.syncSlot(sharedSlot, localSlot);
216
218
  }
219
+ getAbstractSelection(position) {
220
+ const anchorPosition = createAbsolutePositionFromRelativePosition(position.anchor.position, position.anchor.doc);
221
+ const focusPosition = createAbsolutePositionFromRelativePosition(position.focus.position, position.focus.doc);
222
+ if (anchorPosition && focusPosition) {
223
+ const focusSlot = this.slotMap.get(focusPosition.type);
224
+ const anchorSlot = this.slotMap.get(anchorPosition.type);
225
+ if (focusSlot && anchorSlot) {
226
+ return {
227
+ anchorSlot,
228
+ anchorOffset: anchorPosition.index,
229
+ focusSlot,
230
+ focusOffset: focusPosition.index
231
+ };
232
+ }
233
+ }
234
+ return null;
235
+ }
236
+ getRelativeCursorLocation() {
237
+ const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
238
+ if (anchorSlot) {
239
+ const anchorYText = this.slotMap.get(anchorSlot);
240
+ if (anchorYText) {
241
+ const anchorPosition = createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
242
+ if (focusSlot) {
243
+ const focusYText = this.slotMap.get(focusSlot);
244
+ if (focusYText) {
245
+ const focusPosition = createRelativePositionFromTypeIndex(focusYText, focusOffset);
246
+ return {
247
+ focus: {
248
+ doc: focusYText.doc,
249
+ position: focusPosition
250
+ },
251
+ anchor: {
252
+ doc: anchorYText.doc,
253
+ position: anchorPosition
254
+ }
255
+ };
256
+ }
257
+ }
258
+ }
259
+ }
260
+ return null;
261
+ }
262
+ restoreCursorPosition(position) {
263
+ if (!position) {
264
+ this.selection.unSelect();
265
+ return;
266
+ }
267
+ const selection = this.getAbstractSelection(position);
268
+ if (selection) {
269
+ this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
270
+ }
271
+ }
217
272
  initSyncEvent(yDoc) {
218
273
  this.subscriptions.push(this.scheduler.onDocChanged.pipe(map(item => {
219
274
  return item.filter(i => {
@@ -469,6 +524,7 @@ let Collaborate = class Collaborate {
469
524
  yDoc: subDocument,
470
525
  yType: content
471
526
  });
527
+ this.initSyncEvent(subDocument);
472
528
  localSlot.loader.markAsLoaded();
473
529
  });
474
530
  localSlot.__changeMarker__.destroyCallbacks.push(() => {
@@ -626,6 +682,7 @@ let Collaborate = class Collaborate {
626
682
  yType: state,
627
683
  yDoc: subDocument
628
684
  });
685
+ this.initSyncEvent(subDocument);
629
686
  component.loader.markAsLoaded();
630
687
  });
631
688
  return sharedComponent;
@@ -899,7 +956,7 @@ let CollabHistory = class CollabHistory {
899
956
  this.manager = manager;
900
957
  let beforePosition = null;
901
958
  this.subscriptions.push(this.scheduler.onLocalChangeBefore.subscribe(() => {
902
- beforePosition = this.getRelativeCursorLocation();
959
+ beforePosition = this.collaborate.getRelativeCursorLocation();
903
960
  }), this.collaborate.onAddSubModel.subscribe(() => {
904
961
  throw collabHistoryErrorFn('single document does not support submodels.');
905
962
  }));
@@ -912,7 +969,7 @@ let CollabHistory = class CollabHistory {
912
969
  this.historyItems.length = this.index;
913
970
  this.historyItems.push({
914
971
  before: beforePosition,
915
- after: this.getRelativeCursorLocation()
972
+ after: this.collaborate.getRelativeCursorLocation()
916
973
  });
917
974
  this.index++;
918
975
  }
@@ -933,14 +990,7 @@ let CollabHistory = class CollabHistory {
933
990
  const index = ev.type === 'undo' ? this.index : this.index - 1;
934
991
  const position = this.historyItems[index] || null;
935
992
  const p = ev.type === 'undo' ? position === null || position === void 0 ? void 0 : position.before : position === null || position === void 0 ? void 0 : position.after;
936
- if (p) {
937
- const selection = this.getAbstractSelection(p);
938
- if (selection) {
939
- this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
940
- return;
941
- }
942
- }
943
- this.selection.unSelect();
993
+ this.collaborate.restoreCursorPosition(p);
944
994
  });
945
995
  }
946
996
  back() {
@@ -972,43 +1022,6 @@ let CollabHistory = class CollabHistory {
972
1022
  this.subscriptions.forEach(i => i.unsubscribe());
973
1023
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
974
1024
  }
975
- getAbstractSelection(position) {
976
- const anchorPosition = createAbsolutePositionFromRelativePosition(position.anchor, this.collaborate.yDoc);
977
- const focusPosition = createAbsolutePositionFromRelativePosition(position.focus, this.collaborate.yDoc);
978
- if (anchorPosition && focusPosition) {
979
- const focusSlot = this.collaborate.slotMap.get(focusPosition.type);
980
- const anchorSlot = this.collaborate.slotMap.get(anchorPosition.type);
981
- if (focusSlot && anchorSlot) {
982
- return {
983
- anchorSlot,
984
- anchorOffset: anchorPosition.index,
985
- focusSlot,
986
- focusOffset: focusPosition.index
987
- };
988
- }
989
- }
990
- return null;
991
- }
992
- getRelativeCursorLocation() {
993
- const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
994
- if (anchorSlot) {
995
- const anchorYText = this.collaborate.slotMap.get(anchorSlot);
996
- if (anchorYText) {
997
- const anchorPosition = createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
998
- if (focusSlot) {
999
- const focusYText = this.collaborate.slotMap.get(focusSlot);
1000
- if (focusYText) {
1001
- const focusPosition = createRelativePositionFromTypeIndex(focusYText, focusOffset);
1002
- return {
1003
- focus: focusPosition,
1004
- anchor: anchorPosition
1005
- };
1006
- }
1007
- }
1008
- }
1009
- }
1010
- return null;
1011
- }
1012
1025
  };
1013
1026
  CollabHistory = __decorate([
1014
1027
  Injectable(),
@@ -1105,8 +1118,9 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1105
1118
  get canForward() {
1106
1119
  return this.actionStack.length > 0 && this.index < this.actionStack.length;
1107
1120
  }
1108
- constructor(collaborate, rootComponentRef, stackSize, undoManagerConfig) {
1121
+ constructor(collaborate, scheduler, rootComponentRef, stackSize, undoManagerConfig) {
1109
1122
  this.collaborate = collaborate;
1123
+ this.scheduler = scheduler;
1110
1124
  this.rootComponentRef = rootComponentRef;
1111
1125
  this.stackSize = stackSize;
1112
1126
  this.undoManagerConfig = undoManagerConfig;
@@ -1119,6 +1133,7 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1119
1133
  this.index = 0;
1120
1134
  this.stackItem = null;
1121
1135
  this.timer = null;
1136
+ this.beforePosition = null;
1122
1137
  this.subscription = new Subscription();
1123
1138
  this.subDocs = new Set();
1124
1139
  this.listenerCaches = new Set();
@@ -1141,6 +1156,8 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1141
1156
  if (this.isListen) {
1142
1157
  this.listenItem(yType, yDoc);
1143
1158
  }
1159
+ }), this.scheduler.onLocalChangeBefore.subscribe(() => {
1160
+ this.beforePosition = this.collaborate.getRelativeCursorLocation();
1144
1161
  }));
1145
1162
  }
1146
1163
  forward() {
@@ -1150,9 +1167,10 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1150
1167
  clearTimeout(this.timer);
1151
1168
  const item = this.actionStack[this.index];
1152
1169
  if (item) {
1153
- for (const i of item) {
1170
+ for (const i of item.undoManagers) {
1154
1171
  i.redo();
1155
1172
  }
1173
+ this.collaborate.restoreCursorPosition(item.after);
1156
1174
  }
1157
1175
  this.index++;
1158
1176
  this.forwardEvent.next();
@@ -1163,29 +1181,32 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1163
1181
  return;
1164
1182
  }
1165
1183
  clearTimeout(this.timer);
1166
- let actions;
1184
+ let historyStackItem;
1167
1185
  if (this.stackItem) {
1168
- actions = this.stackItem;
1186
+ historyStackItem = this.stackItem;
1169
1187
  this.stackItem = null;
1170
1188
  }
1171
1189
  else {
1172
1190
  this.index--;
1173
- actions = this.actionStack[this.index];
1191
+ historyStackItem = this.actionStack[this.index];
1174
1192
  }
1175
- let len = actions.length;
1193
+ let len = historyStackItem.undoManagers.length;
1176
1194
  while (len > 0) {
1177
1195
  len--;
1178
- actions[len].undo();
1196
+ historyStackItem.undoManagers[len].undo();
1179
1197
  }
1180
- if (actions) {
1198
+ if (historyStackItem) {
1199
+ const beforePosition = historyStackItem.before;
1200
+ this.collaborate.restoreCursorPosition(beforePosition);
1181
1201
  this.backEvent.next();
1182
1202
  this.changeEvent.next();
1183
1203
  }
1184
1204
  }
1185
1205
  clear() {
1186
1206
  this.actionStack = [];
1187
- this.stackItem = [];
1207
+ this.stackItem = null;
1188
1208
  this.index = 0;
1209
+ this.beforePosition = null;
1189
1210
  clearTimeout(this.timer);
1190
1211
  this.listenerCaches.forEach((undoManager) => {
1191
1212
  undoManager.clear();
@@ -1194,6 +1215,7 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1194
1215
  }
1195
1216
  destroy() {
1196
1217
  this.clear();
1218
+ this.beforePosition = this.stackItem = null;
1197
1219
  this.subscription.unsubscribe();
1198
1220
  this.listenerCaches.forEach((undoManager) => {
1199
1221
  undoManager.destroy();
@@ -1224,7 +1246,7 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1224
1246
  if (this.index != this.actionStack.length) {
1225
1247
  const redoStack = this.actionStack.slice(this.index);
1226
1248
  redoStack.forEach(item => {
1227
- item.forEach(i => {
1249
+ item.undoManagers.forEach(i => {
1228
1250
  i.clear(false, true);
1229
1251
  });
1230
1252
  });
@@ -1232,7 +1254,11 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1232
1254
  this.changeEvent.next();
1233
1255
  }
1234
1256
  if (this.stackItem === null) {
1235
- this.stackItem = [];
1257
+ this.stackItem = {
1258
+ before: this.beforePosition,
1259
+ after: null,
1260
+ undoManagers: []
1261
+ };
1236
1262
  this.timer = setTimeout(() => {
1237
1263
  if (this.actionStack.length >= this.stackSize) {
1238
1264
  this.actionStack.shift();
@@ -1240,13 +1266,15 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1240
1266
  else {
1241
1267
  this.index++;
1242
1268
  }
1269
+ // this.beforePosition = this.collaborate.getRelativeCursorLocation()
1270
+ this.stackItem.after = this.beforePosition;
1243
1271
  this.actionStack.push(this.stackItem);
1244
1272
  this.stackItem = null;
1245
1273
  this.pushEvent.next();
1246
1274
  this.changeEvent.next();
1247
1275
  }, 500);
1248
1276
  }
1249
- this.stackItem.push(undoManager);
1277
+ this.stackItem.undoManagers.push(undoManager);
1250
1278
  }
1251
1279
  });
1252
1280
  this.listenerCaches.add(undoManager);
@@ -1254,9 +1282,10 @@ let MultipleDocCollabHistory = class MultipleDocCollabHistory {
1254
1282
  };
1255
1283
  MultipleDocCollabHistory = __decorate([
1256
1284
  Injectable(),
1257
- __param(2, Inject(HISTORY_STACK_SIZE)),
1258
- __param(3, Optional()),
1285
+ __param(3, Inject(HISTORY_STACK_SIZE)),
1286
+ __param(4, Optional()),
1259
1287
  __metadata("design:paramtypes", [Collaborate,
1288
+ Scheduler,
1260
1289
  RootComponentRef, Number, CustomUndoManagerConfig])
1261
1290
  ], MultipleDocCollabHistory);
1262
1291
 
package/bundles/index.js CHANGED
@@ -211,11 +211,66 @@ exports.Collaborate = class Collaborate {
211
211
  this.initLocalSlotBySharedSlot(sharedSlot, localSlot);
212
212
  }
213
213
  else {
214
- this.initSharedSlotByLocalSlot(sharedSlot, localSlot);
214
+ yDoc.transact(() => {
215
+ this.initSharedSlotByLocalSlot(sharedSlot, localSlot);
216
+ });
215
217
  }
216
218
  this.initSyncEvent(yDoc);
217
219
  this.syncSlot(sharedSlot, localSlot);
218
220
  }
221
+ getAbstractSelection(position) {
222
+ const anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor.position, position.anchor.doc);
223
+ const focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus.position, position.focus.doc);
224
+ if (anchorPosition && focusPosition) {
225
+ const focusSlot = this.slotMap.get(focusPosition.type);
226
+ const anchorSlot = this.slotMap.get(anchorPosition.type);
227
+ if (focusSlot && anchorSlot) {
228
+ return {
229
+ anchorSlot,
230
+ anchorOffset: anchorPosition.index,
231
+ focusSlot,
232
+ focusOffset: focusPosition.index
233
+ };
234
+ }
235
+ }
236
+ return null;
237
+ }
238
+ getRelativeCursorLocation() {
239
+ const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
240
+ if (anchorSlot) {
241
+ const anchorYText = this.slotMap.get(anchorSlot);
242
+ if (anchorYText) {
243
+ const anchorPosition = yjs.createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
244
+ if (focusSlot) {
245
+ const focusYText = this.slotMap.get(focusSlot);
246
+ if (focusYText) {
247
+ const focusPosition = yjs.createRelativePositionFromTypeIndex(focusYText, focusOffset);
248
+ return {
249
+ focus: {
250
+ doc: focusYText.doc,
251
+ position: focusPosition
252
+ },
253
+ anchor: {
254
+ doc: anchorYText.doc,
255
+ position: anchorPosition
256
+ }
257
+ };
258
+ }
259
+ }
260
+ }
261
+ }
262
+ return null;
263
+ }
264
+ restoreCursorPosition(position) {
265
+ if (!position) {
266
+ this.selection.unSelect();
267
+ return;
268
+ }
269
+ const selection = this.getAbstractSelection(position);
270
+ if (selection) {
271
+ this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
272
+ }
273
+ }
219
274
  initSyncEvent(yDoc) {
220
275
  this.subscriptions.push(this.scheduler.onDocChanged.pipe(stream.map(item => {
221
276
  return item.filter(i => {
@@ -471,6 +526,7 @@ exports.Collaborate = class Collaborate {
471
526
  yDoc: subDocument,
472
527
  yType: content
473
528
  });
529
+ this.initSyncEvent(subDocument);
474
530
  localSlot.loader.markAsLoaded();
475
531
  });
476
532
  localSlot.__changeMarker__.destroyCallbacks.push(() => {
@@ -628,6 +684,7 @@ exports.Collaborate = class Collaborate {
628
684
  yType: state,
629
685
  yDoc: subDocument
630
686
  });
687
+ this.initSyncEvent(subDocument);
631
688
  component.loader.markAsLoaded();
632
689
  });
633
690
  return sharedComponent;
@@ -901,7 +958,7 @@ exports.CollabHistory = class CollabHistory {
901
958
  this.manager = manager;
902
959
  let beforePosition = null;
903
960
  this.subscriptions.push(this.scheduler.onLocalChangeBefore.subscribe(() => {
904
- beforePosition = this.getRelativeCursorLocation();
961
+ beforePosition = this.collaborate.getRelativeCursorLocation();
905
962
  }), this.collaborate.onAddSubModel.subscribe(() => {
906
963
  throw collabHistoryErrorFn('single document does not support submodels.');
907
964
  }));
@@ -914,7 +971,7 @@ exports.CollabHistory = class CollabHistory {
914
971
  this.historyItems.length = this.index;
915
972
  this.historyItems.push({
916
973
  before: beforePosition,
917
- after: this.getRelativeCursorLocation()
974
+ after: this.collaborate.getRelativeCursorLocation()
918
975
  });
919
976
  this.index++;
920
977
  }
@@ -935,14 +992,7 @@ exports.CollabHistory = class CollabHistory {
935
992
  const index = ev.type === 'undo' ? this.index : this.index - 1;
936
993
  const position = this.historyItems[index] || null;
937
994
  const p = ev.type === 'undo' ? position === null || position === void 0 ? void 0 : position.before : position === null || position === void 0 ? void 0 : position.after;
938
- if (p) {
939
- const selection = this.getAbstractSelection(p);
940
- if (selection) {
941
- this.selection.setBaseAndExtent(selection.anchorSlot, selection.anchorOffset, selection.focusSlot, selection.focusOffset);
942
- return;
943
- }
944
- }
945
- this.selection.unSelect();
995
+ this.collaborate.restoreCursorPosition(p);
946
996
  });
947
997
  }
948
998
  back() {
@@ -974,43 +1024,6 @@ exports.CollabHistory = class CollabHistory {
974
1024
  this.subscriptions.forEach(i => i.unsubscribe());
975
1025
  (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
976
1026
  }
977
- getAbstractSelection(position) {
978
- const anchorPosition = yjs.createAbsolutePositionFromRelativePosition(position.anchor, this.collaborate.yDoc);
979
- const focusPosition = yjs.createAbsolutePositionFromRelativePosition(position.focus, this.collaborate.yDoc);
980
- if (anchorPosition && focusPosition) {
981
- const focusSlot = this.collaborate.slotMap.get(focusPosition.type);
982
- const anchorSlot = this.collaborate.slotMap.get(anchorPosition.type);
983
- if (focusSlot && anchorSlot) {
984
- return {
985
- anchorSlot,
986
- anchorOffset: anchorPosition.index,
987
- focusSlot,
988
- focusOffset: focusPosition.index
989
- };
990
- }
991
- }
992
- return null;
993
- }
994
- getRelativeCursorLocation() {
995
- const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
996
- if (anchorSlot) {
997
- const anchorYText = this.collaborate.slotMap.get(anchorSlot);
998
- if (anchorYText) {
999
- const anchorPosition = yjs.createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
1000
- if (focusSlot) {
1001
- const focusYText = this.collaborate.slotMap.get(focusSlot);
1002
- if (focusYText) {
1003
- const focusPosition = yjs.createRelativePositionFromTypeIndex(focusYText, focusOffset);
1004
- return {
1005
- focus: focusPosition,
1006
- anchor: anchorPosition
1007
- };
1008
- }
1009
- }
1010
- }
1011
- }
1012
- return null;
1013
- }
1014
1027
  };
1015
1028
  exports.CollabHistory = __decorate([
1016
1029
  core$1.Injectable(),
@@ -1107,8 +1120,9 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1107
1120
  get canForward() {
1108
1121
  return this.actionStack.length > 0 && this.index < this.actionStack.length;
1109
1122
  }
1110
- constructor(collaborate, rootComponentRef, stackSize, undoManagerConfig) {
1123
+ constructor(collaborate, scheduler, rootComponentRef, stackSize, undoManagerConfig) {
1111
1124
  this.collaborate = collaborate;
1125
+ this.scheduler = scheduler;
1112
1126
  this.rootComponentRef = rootComponentRef;
1113
1127
  this.stackSize = stackSize;
1114
1128
  this.undoManagerConfig = undoManagerConfig;
@@ -1121,6 +1135,7 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1121
1135
  this.index = 0;
1122
1136
  this.stackItem = null;
1123
1137
  this.timer = null;
1138
+ this.beforePosition = null;
1124
1139
  this.subscription = new stream.Subscription();
1125
1140
  this.subDocs = new Set();
1126
1141
  this.listenerCaches = new Set();
@@ -1143,6 +1158,8 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1143
1158
  if (this.isListen) {
1144
1159
  this.listenItem(yType, yDoc);
1145
1160
  }
1161
+ }), this.scheduler.onLocalChangeBefore.subscribe(() => {
1162
+ this.beforePosition = this.collaborate.getRelativeCursorLocation();
1146
1163
  }));
1147
1164
  }
1148
1165
  forward() {
@@ -1152,9 +1169,10 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1152
1169
  clearTimeout(this.timer);
1153
1170
  const item = this.actionStack[this.index];
1154
1171
  if (item) {
1155
- for (const i of item) {
1172
+ for (const i of item.undoManagers) {
1156
1173
  i.redo();
1157
1174
  }
1175
+ this.collaborate.restoreCursorPosition(item.after);
1158
1176
  }
1159
1177
  this.index++;
1160
1178
  this.forwardEvent.next();
@@ -1165,29 +1183,32 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1165
1183
  return;
1166
1184
  }
1167
1185
  clearTimeout(this.timer);
1168
- let actions;
1186
+ let historyStackItem;
1169
1187
  if (this.stackItem) {
1170
- actions = this.stackItem;
1188
+ historyStackItem = this.stackItem;
1171
1189
  this.stackItem = null;
1172
1190
  }
1173
1191
  else {
1174
1192
  this.index--;
1175
- actions = this.actionStack[this.index];
1193
+ historyStackItem = this.actionStack[this.index];
1176
1194
  }
1177
- let len = actions.length;
1195
+ let len = historyStackItem.undoManagers.length;
1178
1196
  while (len > 0) {
1179
1197
  len--;
1180
- actions[len].undo();
1198
+ historyStackItem.undoManagers[len].undo();
1181
1199
  }
1182
- if (actions) {
1200
+ if (historyStackItem) {
1201
+ const beforePosition = historyStackItem.before;
1202
+ this.collaborate.restoreCursorPosition(beforePosition);
1183
1203
  this.backEvent.next();
1184
1204
  this.changeEvent.next();
1185
1205
  }
1186
1206
  }
1187
1207
  clear() {
1188
1208
  this.actionStack = [];
1189
- this.stackItem = [];
1209
+ this.stackItem = null;
1190
1210
  this.index = 0;
1211
+ this.beforePosition = null;
1191
1212
  clearTimeout(this.timer);
1192
1213
  this.listenerCaches.forEach((undoManager) => {
1193
1214
  undoManager.clear();
@@ -1196,6 +1217,7 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1196
1217
  }
1197
1218
  destroy() {
1198
1219
  this.clear();
1220
+ this.beforePosition = this.stackItem = null;
1199
1221
  this.subscription.unsubscribe();
1200
1222
  this.listenerCaches.forEach((undoManager) => {
1201
1223
  undoManager.destroy();
@@ -1226,7 +1248,7 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1226
1248
  if (this.index != this.actionStack.length) {
1227
1249
  const redoStack = this.actionStack.slice(this.index);
1228
1250
  redoStack.forEach(item => {
1229
- item.forEach(i => {
1251
+ item.undoManagers.forEach(i => {
1230
1252
  i.clear(false, true);
1231
1253
  });
1232
1254
  });
@@ -1234,7 +1256,11 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1234
1256
  this.changeEvent.next();
1235
1257
  }
1236
1258
  if (this.stackItem === null) {
1237
- this.stackItem = [];
1259
+ this.stackItem = {
1260
+ before: this.beforePosition,
1261
+ after: null,
1262
+ undoManagers: []
1263
+ };
1238
1264
  this.timer = setTimeout(() => {
1239
1265
  if (this.actionStack.length >= this.stackSize) {
1240
1266
  this.actionStack.shift();
@@ -1242,13 +1268,15 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1242
1268
  else {
1243
1269
  this.index++;
1244
1270
  }
1271
+ // this.beforePosition = this.collaborate.getRelativeCursorLocation()
1272
+ this.stackItem.after = this.beforePosition;
1245
1273
  this.actionStack.push(this.stackItem);
1246
1274
  this.stackItem = null;
1247
1275
  this.pushEvent.next();
1248
1276
  this.changeEvent.next();
1249
1277
  }, 500);
1250
1278
  }
1251
- this.stackItem.push(undoManager);
1279
+ this.stackItem.undoManagers.push(undoManager);
1252
1280
  }
1253
1281
  });
1254
1282
  this.listenerCaches.add(undoManager);
@@ -1256,9 +1284,10 @@ exports.MultipleDocCollabHistory = class MultipleDocCollabHistory {
1256
1284
  };
1257
1285
  exports.MultipleDocCollabHistory = __decorate([
1258
1286
  core$1.Injectable(),
1259
- __param(2, core$1.Inject(core.HISTORY_STACK_SIZE)),
1260
- __param(3, core$1.Optional()),
1287
+ __param(3, core$1.Inject(core.HISTORY_STACK_SIZE)),
1288
+ __param(4, core$1.Optional()),
1261
1289
  __metadata("design:paramtypes", [exports.Collaborate,
1290
+ core.Scheduler,
1262
1291
  core.RootComponentRef, Number, CustomUndoManagerConfig])
1263
1292
  ], exports.MultipleDocCollabHistory);
1264
1293
 
@@ -1,9 +1,10 @@
1
1
  import { Observable } from '@tanbo/stream';
2
- import { History, RootComponentRef } from '@textbus/core';
2
+ import { History, RootComponentRef, Scheduler } from '@textbus/core';
3
3
  import { Collaborate } from './collaborate';
4
4
  import { CustomUndoManagerConfig } from './collab-history';
5
5
  export declare class MultipleDocCollabHistory implements History {
6
6
  private collaborate;
7
+ private scheduler;
7
8
  private rootComponentRef;
8
9
  private stackSize;
9
10
  private undoManagerConfig;
@@ -22,10 +23,11 @@ export declare class MultipleDocCollabHistory implements History {
22
23
  private index;
23
24
  private stackItem;
24
25
  private timer;
26
+ private beforePosition;
25
27
  private subscription;
26
28
  private subDocs;
27
29
  private listenerCaches;
28
- constructor(collaborate: Collaborate, rootComponentRef: RootComponentRef, stackSize: number, undoManagerConfig: CustomUndoManagerConfig);
30
+ constructor(collaborate: Collaborate, scheduler: Scheduler, rootComponentRef: RootComponentRef, stackSize: number, undoManagerConfig: CustomUndoManagerConfig);
29
31
  listen(): void;
30
32
  forward(): void;
31
33
  back(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@textbus/collaborate",
3
- "version": "4.1.0-alpha.0",
3
+ "version": "4.1.0-alpha.1",
4
4
  "description": "Textbus is a rich text editor and framework that is highly customizable and extensible to achieve rich wysiwyg effects.",
5
5
  "main": "./bundles/index.js",
6
6
  "module": "./bundles/index.esm.js",
@@ -50,5 +50,5 @@
50
50
  "bugs": {
51
51
  "url": "https://github.com/textbus/textbus.git/issues"
52
52
  },
53
- "gitHead": "cf4fd289b73bc777124a32fe42bb58eba05a34f1"
53
+ "gitHead": "04567b43046abd508826c795a27531b37a7753e3"
54
54
  }