@manuscripts/track-changes-plugin 0.4.2 → 0.4.4

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/dist/actions.d.ts CHANGED
@@ -21,7 +21,6 @@ export declare enum TrackChangesAction {
21
21
  setUserID = "track-changes-set-user-id",
22
22
  setPluginStatus = "track-changes-set-track-status",
23
23
  setChangeStatuses = "track-changes-set-change-statuses",
24
- updateChanges = "track-changes-update-changes",
25
24
  refreshChanges = "track-changes-refresh-changes",
26
25
  applyAndRemoveChanges = "track-changes-apply-remove-changes"
27
26
  }
@@ -33,7 +32,6 @@ export declare type TrackChangesActionParams = {
33
32
  status: CHANGE_STATUS;
34
33
  ids: string[];
35
34
  };
36
- [TrackChangesAction.updateChanges]: string[];
37
35
  [TrackChangesAction.refreshChanges]: boolean;
38
36
  [TrackChangesAction.applyAndRemoveChanges]: boolean;
39
37
  };
@@ -1,19 +1,2 @@
1
- /*!
2
- * © 2021 Atypon Systems LLC
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { Schema } from 'prosemirror-model';
17
- import type { Transaction } from 'prosemirror-state';
18
1
  import { ChangeStep, InsertSliceStep } from '../types/step';
19
- export declare function diffChangeSteps(deleted: ChangeStep[], inserted: InsertSliceStep[], newTr: Transaction, schema: Schema): ChangeStep[];
2
+ export declare function diffChangeSteps(deleted: ChangeStep[], inserted: InsertSliceStep[]): ChangeStep[];
@@ -1,3 +1,13 @@
1
1
  import { ExposedFragment } from '../types/pm';
2
2
  import { ChangeStep } from '../types/step';
3
+ /**
4
+ * Matches deleted to inserted content and returns the first pos they differ and the updated
5
+ * ChangeStep list.
6
+ *
7
+ * Based on https://github.com/ProseMirror/prosemirror-model/blob/master/src/diff.ts
8
+ * @param matchedDeleted
9
+ * @param deleted
10
+ * @param inserted
11
+ * @returns
12
+ */
3
13
  export declare function matchInserted(matchedDeleted: number, deleted: ChangeStep[], inserted: ExposedFragment): [number, ChangeStep[]];
@@ -18,9 +18,9 @@ import { ChangeSet } from '../ChangeSet';
18
18
  /**
19
19
  * Finds all changes (basically text marks or node attributes) from document
20
20
  *
21
- * This could be possibly made more efficient by only iterating the sections of doc
22
- * where changes have been applied. This could attempted with eg findDiffStart
23
- * but it might be less robust than just using doc.descendants
21
+ * This could be possibly made more efficient by only iterating the sections of doc where changes have
22
+ * been applied. This could attempted with eg findDiffStart but it might be less robust than just using
23
+ * doc.descendants
24
24
  * @param state
25
25
  * @returns
26
26
  */
@@ -25,7 +25,7 @@ import { TrackChangesStatus } from './types/track';
25
25
  * to the document.
26
26
  * @param status
27
27
  */
28
- export declare const setTrackingStatus: (status?: TrackChangesStatus | undefined) => Command;
28
+ export declare const setTrackingStatus: (status?: TrackChangesStatus) => Command;
29
29
  /**
30
30
  * Appends a transaction to set change attributes/marks' statuses to any of: 'pending' 'accepted' 'rejected'.
31
31
  * @param status
@@ -45,7 +45,3 @@ export declare const applyAndRemoveChanges: () => Command;
45
45
  * Runs `findChanges` to iterate over the document to collect changes into a new ChangeSet.
46
46
  */
47
47
  export declare const refreshChanges: () => Command;
48
- /**
49
- * Adds track attributes for a block node. For testing puroses
50
- */
51
- export declare const setParagraphTestAttribute: (val?: string) => Command;
package/dist/index.cjs CHANGED
@@ -17,7 +17,6 @@ var TrackChangesAction;
17
17
  TrackChangesAction["setUserID"] = "track-changes-set-user-id";
18
18
  TrackChangesAction["setPluginStatus"] = "track-changes-set-track-status";
19
19
  TrackChangesAction["setChangeStatuses"] = "track-changes-set-change-statuses";
20
- TrackChangesAction["updateChanges"] = "track-changes-update-changes";
21
20
  TrackChangesAction["refreshChanges"] = "track-changes-refresh-changes";
22
21
  TrackChangesAction["applyAndRemoveChanges"] = "track-changes-apply-remove-changes";
23
22
  })(TrackChangesAction || (TrackChangesAction = {}));
@@ -373,7 +372,7 @@ function getTextNodeTrackedMarkData(node, schema) {
373
372
  return marksTrackedData[0] || undefined;
374
373
  }
375
374
  function getBlockInlineTrackedData(node) {
376
- let { dataTracked } = node.attrs;
375
+ const { dataTracked } = node.attrs;
377
376
  if (dataTracked && !Array.isArray(dataTracked)) {
378
377
  return [dataTracked];
379
378
  }
@@ -635,9 +634,9 @@ function applyAcceptedRejectedChanges(tr, schema, changes, deleteMap = new prose
635
634
  /**
636
635
  * Finds all changes (basically text marks or node attributes) from document
637
636
  *
638
- * This could be possibly made more efficient by only iterating the sections of doc
639
- * where changes have been applied. This could attempted with eg findDiffStart
640
- * but it might be less robust than just using doc.descendants
637
+ * This could be possibly made more efficient by only iterating the sections of doc where changes have
638
+ * been applied. This could attempted with eg findDiffStart but it might be less robust than just using
639
+ * doc.descendants
641
640
  * @param state
642
641
  * @returns
643
642
  */
@@ -1021,7 +1020,7 @@ function deleteAndMergeSplitNodes(from, to, gap, startDoc, newTr, schema, trackA
1021
1020
  // @TODO ATM 20.7.2022 there doesn't seem to be tests that capture this.
1022
1021
  const wasWithinGap = gap &&
1023
1022
  ((!node.isText && pos >= gap.start) ||
1024
- (node.isText && pos <= gap.start && nodeEnd >= gap.start));
1023
+ (node.isText && pos >= gap.start && nodeEnd <= gap.end));
1025
1024
  // nodeEnd > offsetFrom -> delete touches this node
1026
1025
  // eg (del 6 10) <p 5>|<t 6>cdf</t 9></p 10>| -> <p> nodeEnd 10 > from 6
1027
1026
  if (nodeEnd > from && !wasWithinGap) {
@@ -1122,41 +1121,6 @@ function deleteAndMergeSplitNodes(from, to, gap, startDoc, newTr, schema, trackA
1122
1121
  };
1123
1122
  }
1124
1123
 
1125
- /**
1126
- * Merges tracked marks between text nodes at a position
1127
- *
1128
- * Will work for any nodes that use tracked_insert or tracked_delete marks which may not be preferrable
1129
- * if used for block nodes (since we possibly want to show the individual changed nodes).
1130
- * Merging is done based on the userID, operation type and status.
1131
- * @param pos
1132
- * @param doc
1133
- * @param newTr
1134
- * @param schema
1135
- */
1136
- function mergeTrackedMarks(pos, doc, newTr, schema) {
1137
- const resolved = doc.resolve(pos);
1138
- const { nodeAfter, nodeBefore } = resolved;
1139
- const leftMark = nodeBefore === null || nodeBefore === void 0 ? void 0 : nodeBefore.marks.filter((m) => m.type === schema.marks.tracked_insert || m.type === schema.marks.tracked_delete)[0];
1140
- const rightMark = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.marks.filter((m) => m.type === schema.marks.tracked_insert || m.type === schema.marks.tracked_delete)[0];
1141
- if (!nodeAfter || !nodeBefore || !leftMark || !rightMark || leftMark.type !== rightMark.type) {
1142
- return;
1143
- }
1144
- const leftDataTracked = leftMark.attrs.dataTracked;
1145
- const rightDataTracked = rightMark.attrs.dataTracked;
1146
- if (!shouldMergeTrackedAttributes(leftDataTracked, rightDataTracked)) {
1147
- return;
1148
- }
1149
- const isLeftOlder = (leftDataTracked.createdAt || 0) < (rightDataTracked.createdAt || 0);
1150
- const ancestorAttrs = isLeftOlder ? leftDataTracked : rightDataTracked;
1151
- const dataTracked = {
1152
- ...ancestorAttrs,
1153
- updatedAt: Date.now(),
1154
- };
1155
- const fromStartOfMark = pos - nodeBefore.nodeSize;
1156
- const toEndOfMark = pos + nodeAfter.nodeSize;
1157
- newTr.addMark(fromStartOfMark, toEndOfMark, leftMark.type.create({ ...leftMark.attrs, dataTracked }));
1158
- }
1159
-
1160
1124
  /*!
1161
1125
  * © 2021 Atypon Systems LLC
1162
1126
  *
@@ -1176,27 +1140,6 @@ function trackReplaceAroundStep(step, oldState, newTr, attrs) {
1176
1140
  log.info('###### ReplaceAroundStep ######');
1177
1141
  // @ts-ignore
1178
1142
  const { from, to, gapFrom, gapTo, insert, slice, structure, } = step;
1179
- if (from === gapFrom && to === gapTo) {
1180
- log.info('WRAPPED IN SOMETHING');
1181
- }
1182
- else if (!slice.size || slice.content.content.length === 2) {
1183
- log.info('UNWRAPPED FROM SOMETHING');
1184
- }
1185
- else if (slice.size === 2 && gapFrom - from === 1 && to - gapTo === 1) {
1186
- log.info('REPLACED WRAPPING');
1187
- }
1188
- else {
1189
- log.info('????');
1190
- }
1191
- if (gapFrom - from > to - gapTo) {
1192
- log.info('DELETED BEFORE GAP FROM');
1193
- }
1194
- else if (gapFrom - from < to - gapTo) {
1195
- log.info('DELETED AFTER GAP TO');
1196
- }
1197
- else {
1198
- log.info('EQUAL REPLACE BETWEEN GAPS');
1199
- }
1200
1143
  // Invert the transaction step to prevent it from actually deleting or inserting anything
1201
1144
  const newStep = step.invert(oldState.doc);
1202
1145
  const stepResult = newTr.maybeStep(newStep);
@@ -1209,7 +1152,7 @@ function trackReplaceAroundStep(step, oldState, newTr, attrs) {
1209
1152
  // First apply the deleted range and update the insert slice to not include content that was deleted,
1210
1153
  // eg partial nodes in an open-ended slice
1211
1154
  const { sliceWasSplit, newSliceContent, steps: deleteSteps, } = deleteAndMergeSplitNodes(from, to, { start: gapFrom, end: gapTo }, newTr.doc, newTr, oldState.schema, attrs, slice);
1212
- let steps = deleteSteps;
1155
+ const steps = deleteSteps;
1213
1156
  log.info('TR: new steps after applying delete', [...newTr.steps]);
1214
1157
  log.info('DELETE STEPS: ', deleteSteps);
1215
1158
  // We only want to insert when there something inside the gap (actually would this be always true?)
@@ -1234,11 +1177,6 @@ function trackReplaceAroundStep(step, oldState, newTr, attrs) {
1234
1177
  sliceWasSplit,
1235
1178
  });
1236
1179
  }
1237
- else {
1238
- // Incase only deletion was applied, check whether tracked marks around deleted content can be merged
1239
- mergeTrackedMarks(gapFrom, newTr.doc, newTr, oldState.schema);
1240
- mergeTrackedMarks(gapTo, newTr.doc, newTr, oldState.schema);
1241
- }
1242
1180
  return steps;
1243
1181
  }
1244
1182
 
@@ -1277,7 +1215,7 @@ function trackReplaceStep(step, oldState, newTr, attrs) {
1277
1215
  changeSteps.push(...deleteSteps);
1278
1216
  log.info('TR: steps after applying delete', [...newTr.steps]);
1279
1217
  log.info('DELETE STEPS: ', changeSteps);
1280
- const adjustedInsertPos = toA; // deleteMap.map(toA)
1218
+ const adjustedInsertPos = toA;
1281
1219
  if (newSliceContent.size > 0) {
1282
1220
  log.info('newSliceContent', newSliceContent);
1283
1221
  // Since deleteAndMergeSplitBlockNodes modified the slice to not to contain any merged nodes,
@@ -1294,7 +1232,7 @@ function trackReplaceStep(step, oldState, newTr, attrs) {
1294
1232
  }
1295
1233
  else {
1296
1234
  // Incase only deletion was applied, check whether tracked marks around deleted content can be merged
1297
- mergeTrackedMarks(adjustedInsertPos, newTr.doc, newTr, oldState.schema);
1235
+ // mergeTrackedMarks(adjustedInsertPos, newTr.doc, newTr, oldState.schema)
1298
1236
  selectionPos = fromA;
1299
1237
  }
1300
1238
  });
@@ -1328,6 +1266,7 @@ function trackReplaceStep(step, oldState, newTr, attrs) {
1328
1266
  * @param deleteAttrs
1329
1267
  * @param from
1330
1268
  * @param to
1269
+ * @returns position at the end of the possibly deleted text
1331
1270
  */
1332
1271
  function deleteTextIfInserted(node, pos, newTr, schema, deleteAttrs, from, to) {
1333
1272
  const start = from ? Math.max(pos, from) : pos;
@@ -1361,6 +1300,41 @@ function deleteTextIfInserted(node, pos, newTr, schema, deleteAttrs, from, to) {
1361
1300
  }
1362
1301
  }
1363
1302
 
1303
+ /**
1304
+ * Merges tracked marks between text nodes at a position
1305
+ *
1306
+ * Will work for any nodes that use tracked_insert or tracked_delete marks which may not be preferrable
1307
+ * if used for block nodes (since we possibly want to show the individual changed nodes).
1308
+ * Merging is done based on the userID, operation type and status.
1309
+ * @param pos
1310
+ * @param doc
1311
+ * @param newTr
1312
+ * @param schema
1313
+ */
1314
+ function mergeTrackedMarks(pos, doc, newTr, schema) {
1315
+ const resolved = doc.resolve(pos);
1316
+ const { nodeAfter, nodeBefore } = resolved;
1317
+ const leftMark = nodeBefore === null || nodeBefore === void 0 ? void 0 : nodeBefore.marks.filter((m) => m.type === schema.marks.tracked_insert || m.type === schema.marks.tracked_delete)[0];
1318
+ const rightMark = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.marks.filter((m) => m.type === schema.marks.tracked_insert || m.type === schema.marks.tracked_delete)[0];
1319
+ if (!nodeAfter || !nodeBefore || !leftMark || !rightMark || leftMark.type !== rightMark.type) {
1320
+ return;
1321
+ }
1322
+ const leftDataTracked = leftMark.attrs.dataTracked;
1323
+ const rightDataTracked = rightMark.attrs.dataTracked;
1324
+ if (!shouldMergeTrackedAttributes(leftDataTracked, rightDataTracked)) {
1325
+ return;
1326
+ }
1327
+ const isLeftOlder = (leftDataTracked.createdAt || 0) < (rightDataTracked.createdAt || 0);
1328
+ const ancestorAttrs = isLeftOlder ? leftDataTracked : rightDataTracked;
1329
+ const dataTracked = {
1330
+ ...ancestorAttrs,
1331
+ updatedAt: Date.now(),
1332
+ };
1333
+ const fromStartOfMark = pos - nodeBefore.nodeSize;
1334
+ const toEndOfMark = pos + nodeAfter.nodeSize;
1335
+ newTr.addMark(fromStartOfMark, toEndOfMark, leftMark.type.create({ ...leftMark.attrs, dataTracked }));
1336
+ }
1337
+
1364
1338
  function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema) {
1365
1339
  const mapping = new prosemirrorTransform.Mapping();
1366
1340
  const deleteAttrs = createNewDeleteAttrs(emptyAttrs);
@@ -1448,6 +1422,19 @@ function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema) {
1448
1422
  return [mapping, selectionPos];
1449
1423
  }
1450
1424
 
1425
+ /**
1426
+ * Matches deleted-text recursively to inserted text
1427
+ *
1428
+ * This is needed as text containing various marks is split into multiple parts even though it's
1429
+ * continously deleted. Therefore, we need to find the next part if there is any and keep going until
1430
+ * we've reached the end of the deleted text or inserted content.
1431
+ * @param adjDeleted
1432
+ * @param insNode
1433
+ * @param offset
1434
+ * @param matchedDeleted
1435
+ * @param deleted
1436
+ * @returns
1437
+ */
1451
1438
  function matchText(adjDeleted, insNode, offset, matchedDeleted, deleted) {
1452
1439
  const { pos, from, to, node: delNode } = adjDeleted;
1453
1440
  let j = offset, d = from - pos, maxSteps = to - Math.max(pos, from);
@@ -1480,15 +1467,26 @@ function matchText(adjDeleted, insNode, offset, matchedDeleted, deleted) {
1480
1467
  }
1481
1468
  return [matchedDeleted, deleted];
1482
1469
  }
1470
+ /**
1471
+ * Matches deleted to inserted content and returns the first pos they differ and the updated
1472
+ * ChangeStep list.
1473
+ *
1474
+ * Based on https://github.com/ProseMirror/prosemirror-model/blob/master/src/diff.ts
1475
+ * @param matchedDeleted
1476
+ * @param deleted
1477
+ * @param inserted
1478
+ * @returns
1479
+ */
1483
1480
  function matchInserted(matchedDeleted, deleted, inserted) {
1484
1481
  var _a;
1485
1482
  let matched = [matchedDeleted, deleted];
1486
1483
  for (let i = 0;; i += 1) {
1487
- if (inserted.childCount === i)
1484
+ if (inserted.childCount === i) {
1488
1485
  return matched;
1486
+ }
1489
1487
  const insNode = inserted.child(i);
1490
1488
  // @ts-ignore
1491
- let adjDeleted = matched[1].find((d) => (d.type === 'delete-text' && Math.max(d.pos, d.from) === matched[0]) ||
1489
+ const adjDeleted = matched[1].find((d) => (d.type === 'delete-text' && Math.max(d.pos, d.from) === matched[0]) ||
1492
1490
  (d.type === 'delete-node' && d.pos === matched[0]));
1493
1491
  if (insNode.type !== ((_a = adjDeleted === null || adjDeleted === void 0 ? void 0 : adjDeleted.node) === null || _a === void 0 ? void 0 : _a.type)) {
1494
1492
  return matched;
@@ -1533,16 +1531,13 @@ function matchInserted(matchedDeleted, deleted, inserted) {
1533
1531
  /**
1534
1532
  * Cuts a fragment similar to Fragment.cut but also removes the parent node.
1535
1533
  *
1536
- * @TODO there is however, some silly calculation mistake so that I need to use matched - deleted + 1 > 0
1537
- * inside it to check whether to actually cut a text node. The offset might be cascading, therefore it should
1538
- * be fixed at some point.
1539
1534
  * @param matched
1540
1535
  * @param deleted
1541
1536
  * @param content
1542
1537
  * @returns
1543
1538
  */
1544
1539
  function cutFragment(matched, deleted, content) {
1545
- let newContent = [];
1540
+ const newContent = [];
1546
1541
  for (let i = 0; matched <= deleted && i < content.childCount; i += 1) {
1547
1542
  const child = content.child(i);
1548
1543
  if (!child.isText && child.content.size > 0) {
@@ -1565,7 +1560,7 @@ function cutFragment(matched, deleted, content) {
1565
1560
  }
1566
1561
  return [matched, prosemirrorModel.Fragment.fromArray(newContent)];
1567
1562
  }
1568
- function diffChangeSteps(deleted, inserted, newTr, schema) {
1563
+ function diffChangeSteps(deleted, inserted) {
1569
1564
  const updated = [];
1570
1565
  let updatedDeleted = [...deleted];
1571
1566
  inserted.forEach((ins) => {
@@ -1670,7 +1665,7 @@ function trackTransaction(tr, oldState, newTr, authorID) {
1670
1665
  // deleted and merged really...
1671
1666
  const deleted = steps.filter((s) => s.type !== 'insert-slice');
1672
1667
  const inserted = steps.filter((s) => s.type === 'insert-slice');
1673
- steps = diffChangeSteps(deleted, inserted, newTr, oldState.schema);
1668
+ steps = diffChangeSteps(deleted, inserted);
1674
1669
  log.info('DIFFED STEPS: ', steps);
1675
1670
  const [mapping, selectionPos] = processChangeSteps(steps, startPos || tr.selection.head, // Incase startPos is it's default value 0, use the old selection head
1676
1671
  newTr, emptyAttrs, oldState.schema);
@@ -1688,7 +1683,7 @@ function trackTransaction(tr, oldState, newTr, authorID) {
1688
1683
  const deleted = steps.filter((s) => s.type !== 'insert-slice');
1689
1684
  const inserted = steps.filter((s) => s.type === 'insert-slice');
1690
1685
  log.info('INSERT STEPS: ', inserted);
1691
- steps = diffChangeSteps(deleted, inserted, newTr, oldState.schema);
1686
+ steps = diffChangeSteps(deleted, inserted);
1692
1687
  log.info('DIFFED STEPS: ', steps);
1693
1688
  processChangeSteps(steps, tr.selection.from, newTr, emptyAttrs, oldState.schema);
1694
1689
  }
@@ -1778,15 +1773,14 @@ const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
1778
1773
  return {
1779
1774
  ...pluginState,
1780
1775
  status: setStatus,
1781
- changeSet: findChanges(newState),
1776
+ changeSet: setStatus === exports.TrackChangesStatus.disabled ? new ChangeSet() : findChanges(newState),
1782
1777
  };
1783
1778
  }
1784
1779
  else if (pluginState.status === exports.TrackChangesStatus.disabled) {
1785
1780
  return { ...pluginState, changeSet: new ChangeSet() };
1786
1781
  }
1787
1782
  let { changeSet, ...rest } = pluginState;
1788
- const updatedChangeIds = getAction(tr, TrackChangesAction.updateChanges);
1789
- if (updatedChangeIds || getAction(tr, TrackChangesAction.refreshChanges)) {
1783
+ if (getAction(tr, TrackChangesAction.refreshChanges)) {
1790
1784
  changeSet = findChanges(newState);
1791
1785
  }
1792
1786
  return {
@@ -1830,7 +1824,6 @@ const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
1830
1824
  createdTr = updateChangeAttrs(createdTr, change, { ...change.dataTracked, status, reviewedByID: userID }, oldState.schema);
1831
1825
  }
1832
1826
  });
1833
- setAction(createdTr, TrackChangesAction.updateChanges, ids);
1834
1827
  }
1835
1828
  else if (getAction(tr, TrackChangesAction.applyAndRemoveChanges)) {
1836
1829
  const mapping = applyAcceptedRejectedChanges(createdTr, oldState.schema, changeSet.bothNodeChanges);
@@ -1909,24 +1902,8 @@ const applyAndRemoveChanges = () => (state, dispatch) => {
1909
1902
  * Runs `findChanges` to iterate over the document to collect changes into a new ChangeSet.
1910
1903
  */
1911
1904
  const refreshChanges = () => (state, dispatch) => {
1912
- dispatch && dispatch(setAction(state.tr, TrackChangesAction.updateChanges, []));
1905
+ dispatch && dispatch(setAction(state.tr, TrackChangesAction.refreshChanges, true));
1913
1906
  return true;
1914
- };
1915
- /**
1916
- * Adds track attributes for a block node. For testing puroses
1917
- */
1918
- const setParagraphTestAttribute = (val = 'changed') => (state, dispatch) => {
1919
- var _a;
1920
- const cursor = state.selection.head;
1921
- const blockNodePos = state.doc.resolve(cursor).start(1) - 1;
1922
- if (((_a = state.doc.resolve(blockNodePos).nodeAfter) === null || _a === void 0 ? void 0 : _a.type) === state.schema.nodes.paragraph &&
1923
- dispatch) {
1924
- dispatch(state.tr.setNodeMarkup(blockNodePos, undefined, {
1925
- testAttribute: val,
1926
- }));
1927
- return true;
1928
- }
1929
- return false;
1930
1907
  };
1931
1908
 
1932
1909
  var commands = /*#__PURE__*/Object.freeze({
@@ -1935,8 +1912,7 @@ var commands = /*#__PURE__*/Object.freeze({
1935
1912
  setChangeStatuses: setChangeStatuses,
1936
1913
  setUserID: setUserID,
1937
1914
  applyAndRemoveChanges: applyAndRemoveChanges,
1938
- refreshChanges: refreshChanges,
1939
- setParagraphTestAttribute: setParagraphTestAttribute
1915
+ refreshChanges: refreshChanges
1940
1916
  });
1941
1917
 
1942
1918
  exports.ChangeSet = ChangeSet;
package/dist/index.js CHANGED
@@ -9,7 +9,6 @@ var TrackChangesAction;
9
9
  TrackChangesAction["setUserID"] = "track-changes-set-user-id";
10
10
  TrackChangesAction["setPluginStatus"] = "track-changes-set-track-status";
11
11
  TrackChangesAction["setChangeStatuses"] = "track-changes-set-change-statuses";
12
- TrackChangesAction["updateChanges"] = "track-changes-update-changes";
13
12
  TrackChangesAction["refreshChanges"] = "track-changes-refresh-changes";
14
13
  TrackChangesAction["applyAndRemoveChanges"] = "track-changes-apply-remove-changes";
15
14
  })(TrackChangesAction || (TrackChangesAction = {}));
@@ -365,7 +364,7 @@ function getTextNodeTrackedMarkData(node, schema) {
365
364
  return marksTrackedData[0] || undefined;
366
365
  }
367
366
  function getBlockInlineTrackedData(node) {
368
- let { dataTracked } = node.attrs;
367
+ const { dataTracked } = node.attrs;
369
368
  if (dataTracked && !Array.isArray(dataTracked)) {
370
369
  return [dataTracked];
371
370
  }
@@ -627,9 +626,9 @@ function applyAcceptedRejectedChanges(tr, schema, changes, deleteMap = new Mappi
627
626
  /**
628
627
  * Finds all changes (basically text marks or node attributes) from document
629
628
  *
630
- * This could be possibly made more efficient by only iterating the sections of doc
631
- * where changes have been applied. This could attempted with eg findDiffStart
632
- * but it might be less robust than just using doc.descendants
629
+ * This could be possibly made more efficient by only iterating the sections of doc where changes have
630
+ * been applied. This could attempted with eg findDiffStart but it might be less robust than just using
631
+ * doc.descendants
633
632
  * @param state
634
633
  * @returns
635
634
  */
@@ -1013,7 +1012,7 @@ function deleteAndMergeSplitNodes(from, to, gap, startDoc, newTr, schema, trackA
1013
1012
  // @TODO ATM 20.7.2022 there doesn't seem to be tests that capture this.
1014
1013
  const wasWithinGap = gap &&
1015
1014
  ((!node.isText && pos >= gap.start) ||
1016
- (node.isText && pos <= gap.start && nodeEnd >= gap.start));
1015
+ (node.isText && pos >= gap.start && nodeEnd <= gap.end));
1017
1016
  // nodeEnd > offsetFrom -> delete touches this node
1018
1017
  // eg (del 6 10) <p 5>|<t 6>cdf</t 9></p 10>| -> <p> nodeEnd 10 > from 6
1019
1018
  if (nodeEnd > from && !wasWithinGap) {
@@ -1114,41 +1113,6 @@ function deleteAndMergeSplitNodes(from, to, gap, startDoc, newTr, schema, trackA
1114
1113
  };
1115
1114
  }
1116
1115
 
1117
- /**
1118
- * Merges tracked marks between text nodes at a position
1119
- *
1120
- * Will work for any nodes that use tracked_insert or tracked_delete marks which may not be preferrable
1121
- * if used for block nodes (since we possibly want to show the individual changed nodes).
1122
- * Merging is done based on the userID, operation type and status.
1123
- * @param pos
1124
- * @param doc
1125
- * @param newTr
1126
- * @param schema
1127
- */
1128
- function mergeTrackedMarks(pos, doc, newTr, schema) {
1129
- const resolved = doc.resolve(pos);
1130
- const { nodeAfter, nodeBefore } = resolved;
1131
- const leftMark = nodeBefore === null || nodeBefore === void 0 ? void 0 : nodeBefore.marks.filter((m) => m.type === schema.marks.tracked_insert || m.type === schema.marks.tracked_delete)[0];
1132
- const rightMark = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.marks.filter((m) => m.type === schema.marks.tracked_insert || m.type === schema.marks.tracked_delete)[0];
1133
- if (!nodeAfter || !nodeBefore || !leftMark || !rightMark || leftMark.type !== rightMark.type) {
1134
- return;
1135
- }
1136
- const leftDataTracked = leftMark.attrs.dataTracked;
1137
- const rightDataTracked = rightMark.attrs.dataTracked;
1138
- if (!shouldMergeTrackedAttributes(leftDataTracked, rightDataTracked)) {
1139
- return;
1140
- }
1141
- const isLeftOlder = (leftDataTracked.createdAt || 0) < (rightDataTracked.createdAt || 0);
1142
- const ancestorAttrs = isLeftOlder ? leftDataTracked : rightDataTracked;
1143
- const dataTracked = {
1144
- ...ancestorAttrs,
1145
- updatedAt: Date.now(),
1146
- };
1147
- const fromStartOfMark = pos - nodeBefore.nodeSize;
1148
- const toEndOfMark = pos + nodeAfter.nodeSize;
1149
- newTr.addMark(fromStartOfMark, toEndOfMark, leftMark.type.create({ ...leftMark.attrs, dataTracked }));
1150
- }
1151
-
1152
1116
  /*!
1153
1117
  * © 2021 Atypon Systems LLC
1154
1118
  *
@@ -1168,27 +1132,6 @@ function trackReplaceAroundStep(step, oldState, newTr, attrs) {
1168
1132
  log.info('###### ReplaceAroundStep ######');
1169
1133
  // @ts-ignore
1170
1134
  const { from, to, gapFrom, gapTo, insert, slice, structure, } = step;
1171
- if (from === gapFrom && to === gapTo) {
1172
- log.info('WRAPPED IN SOMETHING');
1173
- }
1174
- else if (!slice.size || slice.content.content.length === 2) {
1175
- log.info('UNWRAPPED FROM SOMETHING');
1176
- }
1177
- else if (slice.size === 2 && gapFrom - from === 1 && to - gapTo === 1) {
1178
- log.info('REPLACED WRAPPING');
1179
- }
1180
- else {
1181
- log.info('????');
1182
- }
1183
- if (gapFrom - from > to - gapTo) {
1184
- log.info('DELETED BEFORE GAP FROM');
1185
- }
1186
- else if (gapFrom - from < to - gapTo) {
1187
- log.info('DELETED AFTER GAP TO');
1188
- }
1189
- else {
1190
- log.info('EQUAL REPLACE BETWEEN GAPS');
1191
- }
1192
1135
  // Invert the transaction step to prevent it from actually deleting or inserting anything
1193
1136
  const newStep = step.invert(oldState.doc);
1194
1137
  const stepResult = newTr.maybeStep(newStep);
@@ -1201,7 +1144,7 @@ function trackReplaceAroundStep(step, oldState, newTr, attrs) {
1201
1144
  // First apply the deleted range and update the insert slice to not include content that was deleted,
1202
1145
  // eg partial nodes in an open-ended slice
1203
1146
  const { sliceWasSplit, newSliceContent, steps: deleteSteps, } = deleteAndMergeSplitNodes(from, to, { start: gapFrom, end: gapTo }, newTr.doc, newTr, oldState.schema, attrs, slice);
1204
- let steps = deleteSteps;
1147
+ const steps = deleteSteps;
1205
1148
  log.info('TR: new steps after applying delete', [...newTr.steps]);
1206
1149
  log.info('DELETE STEPS: ', deleteSteps);
1207
1150
  // We only want to insert when there something inside the gap (actually would this be always true?)
@@ -1226,11 +1169,6 @@ function trackReplaceAroundStep(step, oldState, newTr, attrs) {
1226
1169
  sliceWasSplit,
1227
1170
  });
1228
1171
  }
1229
- else {
1230
- // Incase only deletion was applied, check whether tracked marks around deleted content can be merged
1231
- mergeTrackedMarks(gapFrom, newTr.doc, newTr, oldState.schema);
1232
- mergeTrackedMarks(gapTo, newTr.doc, newTr, oldState.schema);
1233
- }
1234
1172
  return steps;
1235
1173
  }
1236
1174
 
@@ -1269,7 +1207,7 @@ function trackReplaceStep(step, oldState, newTr, attrs) {
1269
1207
  changeSteps.push(...deleteSteps);
1270
1208
  log.info('TR: steps after applying delete', [...newTr.steps]);
1271
1209
  log.info('DELETE STEPS: ', changeSteps);
1272
- const adjustedInsertPos = toA; // deleteMap.map(toA)
1210
+ const adjustedInsertPos = toA;
1273
1211
  if (newSliceContent.size > 0) {
1274
1212
  log.info('newSliceContent', newSliceContent);
1275
1213
  // Since deleteAndMergeSplitBlockNodes modified the slice to not to contain any merged nodes,
@@ -1286,7 +1224,7 @@ function trackReplaceStep(step, oldState, newTr, attrs) {
1286
1224
  }
1287
1225
  else {
1288
1226
  // Incase only deletion was applied, check whether tracked marks around deleted content can be merged
1289
- mergeTrackedMarks(adjustedInsertPos, newTr.doc, newTr, oldState.schema);
1227
+ // mergeTrackedMarks(adjustedInsertPos, newTr.doc, newTr, oldState.schema)
1290
1228
  selectionPos = fromA;
1291
1229
  }
1292
1230
  });
@@ -1320,6 +1258,7 @@ function trackReplaceStep(step, oldState, newTr, attrs) {
1320
1258
  * @param deleteAttrs
1321
1259
  * @param from
1322
1260
  * @param to
1261
+ * @returns position at the end of the possibly deleted text
1323
1262
  */
1324
1263
  function deleteTextIfInserted(node, pos, newTr, schema, deleteAttrs, from, to) {
1325
1264
  const start = from ? Math.max(pos, from) : pos;
@@ -1353,6 +1292,41 @@ function deleteTextIfInserted(node, pos, newTr, schema, deleteAttrs, from, to) {
1353
1292
  }
1354
1293
  }
1355
1294
 
1295
+ /**
1296
+ * Merges tracked marks between text nodes at a position
1297
+ *
1298
+ * Will work for any nodes that use tracked_insert or tracked_delete marks which may not be preferrable
1299
+ * if used for block nodes (since we possibly want to show the individual changed nodes).
1300
+ * Merging is done based on the userID, operation type and status.
1301
+ * @param pos
1302
+ * @param doc
1303
+ * @param newTr
1304
+ * @param schema
1305
+ */
1306
+ function mergeTrackedMarks(pos, doc, newTr, schema) {
1307
+ const resolved = doc.resolve(pos);
1308
+ const { nodeAfter, nodeBefore } = resolved;
1309
+ const leftMark = nodeBefore === null || nodeBefore === void 0 ? void 0 : nodeBefore.marks.filter((m) => m.type === schema.marks.tracked_insert || m.type === schema.marks.tracked_delete)[0];
1310
+ const rightMark = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.marks.filter((m) => m.type === schema.marks.tracked_insert || m.type === schema.marks.tracked_delete)[0];
1311
+ if (!nodeAfter || !nodeBefore || !leftMark || !rightMark || leftMark.type !== rightMark.type) {
1312
+ return;
1313
+ }
1314
+ const leftDataTracked = leftMark.attrs.dataTracked;
1315
+ const rightDataTracked = rightMark.attrs.dataTracked;
1316
+ if (!shouldMergeTrackedAttributes(leftDataTracked, rightDataTracked)) {
1317
+ return;
1318
+ }
1319
+ const isLeftOlder = (leftDataTracked.createdAt || 0) < (rightDataTracked.createdAt || 0);
1320
+ const ancestorAttrs = isLeftOlder ? leftDataTracked : rightDataTracked;
1321
+ const dataTracked = {
1322
+ ...ancestorAttrs,
1323
+ updatedAt: Date.now(),
1324
+ };
1325
+ const fromStartOfMark = pos - nodeBefore.nodeSize;
1326
+ const toEndOfMark = pos + nodeAfter.nodeSize;
1327
+ newTr.addMark(fromStartOfMark, toEndOfMark, leftMark.type.create({ ...leftMark.attrs, dataTracked }));
1328
+ }
1329
+
1356
1330
  function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema) {
1357
1331
  const mapping = new Mapping();
1358
1332
  const deleteAttrs = createNewDeleteAttrs(emptyAttrs);
@@ -1440,6 +1414,19 @@ function processChangeSteps(changes, startPos, newTr, emptyAttrs, schema) {
1440
1414
  return [mapping, selectionPos];
1441
1415
  }
1442
1416
 
1417
+ /**
1418
+ * Matches deleted-text recursively to inserted text
1419
+ *
1420
+ * This is needed as text containing various marks is split into multiple parts even though it's
1421
+ * continously deleted. Therefore, we need to find the next part if there is any and keep going until
1422
+ * we've reached the end of the deleted text or inserted content.
1423
+ * @param adjDeleted
1424
+ * @param insNode
1425
+ * @param offset
1426
+ * @param matchedDeleted
1427
+ * @param deleted
1428
+ * @returns
1429
+ */
1443
1430
  function matchText(adjDeleted, insNode, offset, matchedDeleted, deleted) {
1444
1431
  const { pos, from, to, node: delNode } = adjDeleted;
1445
1432
  let j = offset, d = from - pos, maxSteps = to - Math.max(pos, from);
@@ -1472,15 +1459,26 @@ function matchText(adjDeleted, insNode, offset, matchedDeleted, deleted) {
1472
1459
  }
1473
1460
  return [matchedDeleted, deleted];
1474
1461
  }
1462
+ /**
1463
+ * Matches deleted to inserted content and returns the first pos they differ and the updated
1464
+ * ChangeStep list.
1465
+ *
1466
+ * Based on https://github.com/ProseMirror/prosemirror-model/blob/master/src/diff.ts
1467
+ * @param matchedDeleted
1468
+ * @param deleted
1469
+ * @param inserted
1470
+ * @returns
1471
+ */
1475
1472
  function matchInserted(matchedDeleted, deleted, inserted) {
1476
1473
  var _a;
1477
1474
  let matched = [matchedDeleted, deleted];
1478
1475
  for (let i = 0;; i += 1) {
1479
- if (inserted.childCount === i)
1476
+ if (inserted.childCount === i) {
1480
1477
  return matched;
1478
+ }
1481
1479
  const insNode = inserted.child(i);
1482
1480
  // @ts-ignore
1483
- let adjDeleted = matched[1].find((d) => (d.type === 'delete-text' && Math.max(d.pos, d.from) === matched[0]) ||
1481
+ const adjDeleted = matched[1].find((d) => (d.type === 'delete-text' && Math.max(d.pos, d.from) === matched[0]) ||
1484
1482
  (d.type === 'delete-node' && d.pos === matched[0]));
1485
1483
  if (insNode.type !== ((_a = adjDeleted === null || adjDeleted === void 0 ? void 0 : adjDeleted.node) === null || _a === void 0 ? void 0 : _a.type)) {
1486
1484
  return matched;
@@ -1525,16 +1523,13 @@ function matchInserted(matchedDeleted, deleted, inserted) {
1525
1523
  /**
1526
1524
  * Cuts a fragment similar to Fragment.cut but also removes the parent node.
1527
1525
  *
1528
- * @TODO there is however, some silly calculation mistake so that I need to use matched - deleted + 1 > 0
1529
- * inside it to check whether to actually cut a text node. The offset might be cascading, therefore it should
1530
- * be fixed at some point.
1531
1526
  * @param matched
1532
1527
  * @param deleted
1533
1528
  * @param content
1534
1529
  * @returns
1535
1530
  */
1536
1531
  function cutFragment(matched, deleted, content) {
1537
- let newContent = [];
1532
+ const newContent = [];
1538
1533
  for (let i = 0; matched <= deleted && i < content.childCount; i += 1) {
1539
1534
  const child = content.child(i);
1540
1535
  if (!child.isText && child.content.size > 0) {
@@ -1557,7 +1552,7 @@ function cutFragment(matched, deleted, content) {
1557
1552
  }
1558
1553
  return [matched, Fragment.fromArray(newContent)];
1559
1554
  }
1560
- function diffChangeSteps(deleted, inserted, newTr, schema) {
1555
+ function diffChangeSteps(deleted, inserted) {
1561
1556
  const updated = [];
1562
1557
  let updatedDeleted = [...deleted];
1563
1558
  inserted.forEach((ins) => {
@@ -1662,7 +1657,7 @@ function trackTransaction(tr, oldState, newTr, authorID) {
1662
1657
  // deleted and merged really...
1663
1658
  const deleted = steps.filter((s) => s.type !== 'insert-slice');
1664
1659
  const inserted = steps.filter((s) => s.type === 'insert-slice');
1665
- steps = diffChangeSteps(deleted, inserted, newTr, oldState.schema);
1660
+ steps = diffChangeSteps(deleted, inserted);
1666
1661
  log.info('DIFFED STEPS: ', steps);
1667
1662
  const [mapping, selectionPos] = processChangeSteps(steps, startPos || tr.selection.head, // Incase startPos is it's default value 0, use the old selection head
1668
1663
  newTr, emptyAttrs, oldState.schema);
@@ -1680,7 +1675,7 @@ function trackTransaction(tr, oldState, newTr, authorID) {
1680
1675
  const deleted = steps.filter((s) => s.type !== 'insert-slice');
1681
1676
  const inserted = steps.filter((s) => s.type === 'insert-slice');
1682
1677
  log.info('INSERT STEPS: ', inserted);
1683
- steps = diffChangeSteps(deleted, inserted, newTr, oldState.schema);
1678
+ steps = diffChangeSteps(deleted, inserted);
1684
1679
  log.info('DIFFED STEPS: ', steps);
1685
1680
  processChangeSteps(steps, tr.selection.from, newTr, emptyAttrs, oldState.schema);
1686
1681
  }
@@ -1770,15 +1765,14 @@ const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
1770
1765
  return {
1771
1766
  ...pluginState,
1772
1767
  status: setStatus,
1773
- changeSet: findChanges(newState),
1768
+ changeSet: setStatus === TrackChangesStatus.disabled ? new ChangeSet() : findChanges(newState),
1774
1769
  };
1775
1770
  }
1776
1771
  else if (pluginState.status === TrackChangesStatus.disabled) {
1777
1772
  return { ...pluginState, changeSet: new ChangeSet() };
1778
1773
  }
1779
1774
  let { changeSet, ...rest } = pluginState;
1780
- const updatedChangeIds = getAction(tr, TrackChangesAction.updateChanges);
1781
- if (updatedChangeIds || getAction(tr, TrackChangesAction.refreshChanges)) {
1775
+ if (getAction(tr, TrackChangesAction.refreshChanges)) {
1782
1776
  changeSet = findChanges(newState);
1783
1777
  }
1784
1778
  return {
@@ -1822,7 +1816,6 @@ const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
1822
1816
  createdTr = updateChangeAttrs(createdTr, change, { ...change.dataTracked, status, reviewedByID: userID }, oldState.schema);
1823
1817
  }
1824
1818
  });
1825
- setAction(createdTr, TrackChangesAction.updateChanges, ids);
1826
1819
  }
1827
1820
  else if (getAction(tr, TrackChangesAction.applyAndRemoveChanges)) {
1828
1821
  const mapping = applyAcceptedRejectedChanges(createdTr, oldState.schema, changeSet.bothNodeChanges);
@@ -1901,24 +1894,8 @@ const applyAndRemoveChanges = () => (state, dispatch) => {
1901
1894
  * Runs `findChanges` to iterate over the document to collect changes into a new ChangeSet.
1902
1895
  */
1903
1896
  const refreshChanges = () => (state, dispatch) => {
1904
- dispatch && dispatch(setAction(state.tr, TrackChangesAction.updateChanges, []));
1897
+ dispatch && dispatch(setAction(state.tr, TrackChangesAction.refreshChanges, true));
1905
1898
  return true;
1906
- };
1907
- /**
1908
- * Adds track attributes for a block node. For testing puroses
1909
- */
1910
- const setParagraphTestAttribute = (val = 'changed') => (state, dispatch) => {
1911
- var _a;
1912
- const cursor = state.selection.head;
1913
- const blockNodePos = state.doc.resolve(cursor).start(1) - 1;
1914
- if (((_a = state.doc.resolve(blockNodePos).nodeAfter) === null || _a === void 0 ? void 0 : _a.type) === state.schema.nodes.paragraph &&
1915
- dispatch) {
1916
- dispatch(state.tr.setNodeMarkup(blockNodePos, undefined, {
1917
- testAttribute: val,
1918
- }));
1919
- return true;
1920
- }
1921
- return false;
1922
1899
  };
1923
1900
 
1924
1901
  var commands = /*#__PURE__*/Object.freeze({
@@ -1927,8 +1904,7 @@ var commands = /*#__PURE__*/Object.freeze({
1927
1904
  setChangeStatuses: setChangeStatuses,
1928
1905
  setUserID: setUserID,
1929
1906
  applyAndRemoveChanges: applyAndRemoveChanges,
1930
- refreshChanges: refreshChanges,
1931
- setParagraphTestAttribute: setParagraphTestAttribute
1907
+ refreshChanges: refreshChanges
1932
1908
  });
1933
1909
 
1934
1910
  export { CHANGE_OPERATION, CHANGE_STATUS, ChangeSet, TrackChangesStatus, enableDebug, skipTracking, trackChangesPlugin, trackChangesPluginKey, commands as trackCommands };
@@ -28,5 +28,6 @@ import { NewDeleteAttrs } from '../types/track';
28
28
  * @param deleteAttrs
29
29
  * @param from
30
30
  * @param to
31
+ * @returns position at the end of the possibly deleted text
31
32
  */
32
33
  export declare function deleteTextIfInserted(node: PMNode, pos: number, newTr: Transaction, schema: Schema, deleteAttrs: NewDeleteAttrs, from?: number, to?: number): number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manuscripts/track-changes-plugin",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "author": "Atypon Systems LLC",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/Atypon-OpenSource/manuscripts-quarterback/tree/main/quarterback-packages/track-changes-plugin",
@@ -11,7 +11,10 @@
11
11
  "exports": {
12
12
  "./package.json": "./package.json",
13
13
  "./src/styles.css": "./src/styles.css",
14
- ".": "./dist/index.js"
14
+ ".": {
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
17
+ }
15
18
  },
16
19
  "files": [
17
20
  "dist",
@@ -21,28 +24,28 @@
21
24
  "access": "public"
22
25
  },
23
26
  "devDependencies": {
24
- "@manuscripts/manuscript-transform": "^0.49.4",
25
- "@rollup/plugin-commonjs": "^22.0.0",
27
+ "@manuscripts/manuscript-transform": "^0.54.0",
28
+ "@rollup/plugin-commonjs": "^22.0.2",
26
29
  "@types/debug": "^4.1.7",
27
30
  "@types/jest": "27.5.1",
28
- "@types/node": "^17.0.35",
31
+ "@types/node": "^18.7.18",
29
32
  "jest": "27.5.1",
30
33
  "jest-environment-jsdom": "27.5.1",
31
- "jsdom": "^19.0.0",
32
- "prosemirror-commands": "^1.3.0",
34
+ "jsdom": "^20.0.0",
35
+ "prosemirror-commands": "^1.3.1",
33
36
  "prosemirror-example-setup": "^1.2.1",
34
37
  "prosemirror-history": "^1.3.0",
35
38
  "prosemirror-keymap": "^1.2.0",
36
39
  "prosemirror-model": "^1.18.1",
37
- "prosemirror-schema-list": "^1.2.0",
40
+ "prosemirror-schema-list": "^1.2.2",
38
41
  "prosemirror-state": "^1.4.1",
39
- "prosemirror-transform": "^1.6.0",
40
- "prosemirror-view": "^1.27.0",
41
- "rollup": "^2.74.0",
42
- "rollup-plugin-typescript2": "^0.31.2",
42
+ "prosemirror-transform": "^1.7.0",
43
+ "prosemirror-view": "^1.28.1",
44
+ "rollup": "^2.79.0",
45
+ "rollup-plugin-typescript2": "^0.34.0",
43
46
  "ts-jest": "27.1.4",
44
47
  "tslib": "^2.4.0",
45
- "typescript": "^4.6.4"
48
+ "typescript": "^4.8.3"
46
49
  },
47
50
  "peerDependencies": {
48
51
  "prosemirror-model": ">=1.14.0",