@manuscripts/track-changes-plugin 1.7.2 → 1.7.3
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/cjs/ChangeSet.js +155 -0
- package/dist/cjs/actions.js +23 -0
- package/dist/cjs/change-steps/diffChangeSteps.js +63 -0
- package/dist/cjs/change-steps/matchInserted.js +70 -0
- package/dist/cjs/change-steps/processChangeSteps.js +141 -0
- package/dist/cjs/changes/applyChanges.js +81 -0
- package/dist/cjs/changes/findChanges.js +72 -0
- package/dist/cjs/changes/fixInconsistentChanges.js +21 -0
- package/dist/cjs/changes/updateChangeAttrs.js +65 -0
- package/dist/cjs/commands.js +47 -0
- package/dist/cjs/compute/nodeHelpers.js +77 -0
- package/dist/cjs/compute/setFragmentAsInserted.js +53 -0
- package/dist/cjs/compute/splitSliceIntoMergedParts.js +57 -0
- package/dist/cjs/index.js +41 -0
- package/dist/cjs/mutate/deleteAndMergeSplitNodes.js +105 -0
- package/dist/cjs/mutate/deleteNode.js +43 -0
- package/dist/cjs/mutate/deleteText.js +29 -0
- package/dist/cjs/mutate/mergeNode.js +21 -0
- package/dist/cjs/mutate/mergeTrackedMarks.js +25 -0
- package/dist/cjs/plugin.js +118 -0
- package/dist/cjs/steps/trackReplaceAroundStep.js +72 -0
- package/dist/cjs/steps/trackReplaceStep.js +79 -0
- package/dist/cjs/steps/trackTransaction.js +88 -0
- package/dist/cjs/types/change.js +15 -0
- package/dist/cjs/types/pm.js +2 -0
- package/dist/cjs/types/step.js +2 -0
- package/dist/cjs/types/track.js +9 -0
- package/dist/cjs/utils/logger.js +43 -0
- package/dist/cjs/utils/track-utils.js +28 -0
- package/dist/cjs/utils/uuidv4.js +10 -0
- package/dist/es/ChangeSet.js +151 -0
- package/dist/es/actions.js +17 -0
- package/dist/es/change-steps/diffChangeSteps.js +59 -0
- package/dist/es/change-steps/matchInserted.js +66 -0
- package/dist/es/change-steps/processChangeSteps.js +114 -0
- package/dist/es/changes/applyChanges.js +77 -0
- package/dist/es/changes/findChanges.js +68 -0
- package/dist/es/changes/fixInconsistentChanges.js +17 -0
- package/dist/es/changes/updateChangeAttrs.js +60 -0
- package/dist/es/commands.js +39 -0
- package/dist/es/compute/nodeHelpers.js +67 -0
- package/dist/es/compute/setFragmentAsInserted.js +49 -0
- package/dist/es/compute/splitSliceIntoMergedParts.js +53 -0
- package/dist/es/index.js +7 -0
- package/dist/es/mutate/deleteAndMergeSplitNodes.js +78 -0
- package/dist/es/mutate/deleteNode.js +38 -0
- package/dist/es/mutate/deleteText.js +25 -0
- package/dist/es/mutate/mergeNode.js +17 -0
- package/dist/es/mutate/mergeTrackedMarks.js +21 -0
- package/dist/es/plugin.js +114 -0
- package/dist/es/steps/trackReplaceAroundStep.js +45 -0
- package/dist/es/steps/trackReplaceStep.js +52 -0
- package/dist/es/steps/trackTransaction.js +84 -0
- package/dist/es/types/change.js +12 -0
- package/dist/es/types/pm.js +1 -0
- package/dist/es/types/step.js +1 -0
- package/dist/es/types/track.js +6 -0
- package/dist/es/utils/logger.js +36 -0
- package/dist/es/utils/track-utils.js +22 -0
- package/dist/es/utils/uuidv4.js +6 -0
- package/dist/types/ChangeSet.d.ts +28 -0
- package/dist/{actions.d.ts → types/actions.d.ts} +27 -60
- package/dist/{change-steps → types/change-steps}/diffChangeSteps.d.ts +2 -2
- package/dist/types/change-steps/matchInserted.d.ts +3 -0
- package/dist/types/change-steps/processChangeSteps.d.ts +6 -0
- package/dist/types/changes/applyChanges.d.ts +5 -0
- package/dist/types/changes/findChanges.d.ts +3 -0
- package/dist/types/changes/fixInconsistentChanges.d.ts +4 -0
- package/dist/types/changes/updateChangeAttrs.d.ts +6 -0
- package/dist/types/commands.d.ts +8 -0
- package/dist/{compute → types/compute}/nodeHelpers.d.ts +13 -28
- package/dist/types/compute/setFragmentAsInserted.d.ts +3 -0
- package/dist/types/compute/splitSliceIntoMergedParts.d.ts +13 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/mutate/deleteAndMergeSplitNodes.d.ts +13 -0
- package/dist/types/mutate/deleteNode.d.ts +5 -0
- package/dist/types/mutate/deleteText.d.ts +4 -0
- package/dist/types/mutate/mergeNode.d.ts +3 -0
- package/dist/types/mutate/mergeTrackedMarks.d.ts +3 -0
- package/dist/types/plugin.d.ts +4 -0
- package/dist/{steps → types/steps}/trackReplaceAroundStep.d.ts +5 -5
- package/dist/types/steps/trackReplaceStep.d.ts +6 -0
- package/dist/types/steps/trackTransaction.d.ts +2 -0
- package/dist/types/types/change.d.ts +61 -0
- package/dist/types/types/pm.d.ts +12 -0
- package/dist/types/{step.d.ts → types/step.d.ts} +38 -53
- package/dist/types/types/track.d.ts +30 -0
- package/dist/types/utils/logger.d.ts +8 -0
- package/dist/{utils → types/utils}/track-utils.d.ts +4 -4
- package/dist/types/utils/uuidv4.d.ts +1 -0
- package/package.json +18 -39
- package/LICENSE +0 -201
- package/dist/ChangeSet.d.ts +0 -71
- package/dist/change-steps/matchInserted.d.ts +0 -13
- package/dist/change-steps/processChangeSteps.d.ts +0 -21
- package/dist/changes/applyChanges.d.ts +0 -28
- package/dist/changes/findChanges.d.ts +0 -27
- package/dist/changes/fixInconsistentChanges.d.ts +0 -29
- package/dist/changes/updateChangeAttrs.d.ts +0 -21
- package/dist/commands.d.ts +0 -47
- package/dist/compute/setFragmentAsInserted.d.ts +0 -18
- package/dist/compute/splitSliceIntoMergedParts.d.ts +0 -41
- package/dist/index.cjs +0 -2026
- package/dist/index.d.ts +0 -22
- package/dist/index.js +0 -2013
- package/dist/mutate/deleteAndMergeSplitNodes.d.ts +0 -53
- package/dist/mutate/deleteNode.d.ts +0 -36
- package/dist/mutate/deleteText.d.ts +0 -33
- package/dist/mutate/mergeNode.d.ts +0 -25
- package/dist/mutate/mergeTrackedMarks.d.ts +0 -29
- package/dist/plugin.d.ts +0 -25
- package/dist/steps/trackReplaceStep.d.ts +0 -21
- package/dist/steps/trackTransaction.d.ts +0 -17
- package/dist/types/change.d.ts +0 -76
- package/dist/types/pm.d.ts +0 -27
- package/dist/types/track.d.ts +0 -45
- package/dist/utils/logger.d.ts +0 -27
- package/dist/utils/uuidv4.d.ts +0 -16
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Fragment } from 'prosemirror-model';
|
|
2
|
+
function getMergedNode(node, currentDepth, depth, first) {
|
|
3
|
+
if (currentDepth === depth) {
|
|
4
|
+
return {
|
|
5
|
+
mergedNodeContent: node.content,
|
|
6
|
+
unmergedContent: undefined,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
const result = [];
|
|
10
|
+
let merged = Fragment.empty;
|
|
11
|
+
node.content.forEach((n, _, i) => {
|
|
12
|
+
if ((first && i === 0) || (!first && i === node.childCount - 1)) {
|
|
13
|
+
const { mergedNodeContent, unmergedContent } = getMergedNode(n, currentDepth + 1, depth, first);
|
|
14
|
+
merged = mergedNodeContent;
|
|
15
|
+
if (unmergedContent) {
|
|
16
|
+
result.push(...unmergedContent.content);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
result.push(n);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return {
|
|
24
|
+
mergedNodeContent: merged,
|
|
25
|
+
unmergedContent: result.length > 0 ? Fragment.fromArray(result) : undefined,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function splitSliceIntoMergedParts(insertSlice, mergeEqualSides = false) {
|
|
29
|
+
const { openStart, openEnd, content: { firstChild, lastChild, content: nodes }, } = insertSlice;
|
|
30
|
+
let updatedSliceNodes = nodes;
|
|
31
|
+
const mergeSides = openStart !== openEnd || mergeEqualSides;
|
|
32
|
+
const firstMergedNode = openStart > 0 && mergeSides && firstChild
|
|
33
|
+
? getMergedNode(firstChild, 1, openStart, true)
|
|
34
|
+
: undefined;
|
|
35
|
+
const lastMergedNode = openEnd > 0 && mergeSides && lastChild ? getMergedNode(lastChild, 1, openEnd, false) : undefined;
|
|
36
|
+
if (firstMergedNode) {
|
|
37
|
+
updatedSliceNodes = updatedSliceNodes.slice(1);
|
|
38
|
+
if (firstMergedNode.unmergedContent) {
|
|
39
|
+
updatedSliceNodes = [...firstMergedNode.unmergedContent.content, ...updatedSliceNodes];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (lastMergedNode) {
|
|
43
|
+
updatedSliceNodes = updatedSliceNodes.slice(0, -1);
|
|
44
|
+
if (lastMergedNode.unmergedContent) {
|
|
45
|
+
updatedSliceNodes = [...updatedSliceNodes, ...lastMergedNode.unmergedContent.content];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
updatedSliceNodes,
|
|
50
|
+
firstMergedNode,
|
|
51
|
+
lastMergedNode,
|
|
52
|
+
};
|
|
53
|
+
}
|
package/dist/es/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { trackChangesPluginKey, trackChangesPlugin } from './plugin';
|
|
2
|
+
export { skipTracking } from './actions';
|
|
3
|
+
export * as trackCommands from './commands';
|
|
4
|
+
export { enableDebug } from './utils/logger';
|
|
5
|
+
export { ChangeSet } from './ChangeSet';
|
|
6
|
+
export * from './types/change';
|
|
7
|
+
export * from './types/track';
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Fragment } from 'prosemirror-model';
|
|
2
|
+
import { splitSliceIntoMergedParts } from '../compute/splitSliceIntoMergedParts';
|
|
3
|
+
import { setFragmentAsInserted } from '../compute/setFragmentAsInserted';
|
|
4
|
+
import * as trackUtils from '../utils/track-utils';
|
|
5
|
+
export function deleteAndMergeSplitNodes(from, to, gap, startDoc, newTr, schema, trackAttrs, insertSlice) {
|
|
6
|
+
const steps = [];
|
|
7
|
+
if (from === to) {
|
|
8
|
+
return {
|
|
9
|
+
newSliceContent: insertSlice.content,
|
|
10
|
+
sliceWasSplit: false,
|
|
11
|
+
steps,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const { openStart, openEnd } = insertSlice;
|
|
15
|
+
const { updatedSliceNodes, firstMergedNode, lastMergedNode } = splitSliceIntoMergedParts(insertSlice, gap !== undefined);
|
|
16
|
+
let mergingStartSide = true;
|
|
17
|
+
startDoc.nodesBetween(from, to, (node, pos) => {
|
|
18
|
+
const nodeEnd = pos + node.nodeSize;
|
|
19
|
+
const wasWithinGap = gap &&
|
|
20
|
+
((!node.isText && pos >= gap.start) ||
|
|
21
|
+
(node.isText && pos >= gap.start && nodeEnd <= gap.end));
|
|
22
|
+
if (nodeEnd > from && !wasWithinGap) {
|
|
23
|
+
const nodeCompletelyDeleted = pos >= from && nodeEnd <= to;
|
|
24
|
+
const endTokenDeleted = nodeEnd <= to;
|
|
25
|
+
const startTokenDeleted = pos >= from;
|
|
26
|
+
if (node.isText ||
|
|
27
|
+
(!endTokenDeleted && startTokenDeleted) ||
|
|
28
|
+
(endTokenDeleted && !startTokenDeleted)) {
|
|
29
|
+
if (!endTokenDeleted && startTokenDeleted) {
|
|
30
|
+
mergingStartSide = false;
|
|
31
|
+
}
|
|
32
|
+
const depth = newTr.doc.resolve(pos).depth;
|
|
33
|
+
const mergeContent = mergingStartSide
|
|
34
|
+
? firstMergedNode === null || firstMergedNode === void 0 ? void 0 : firstMergedNode.mergedNodeContent
|
|
35
|
+
: lastMergedNode === null || lastMergedNode === void 0 ? void 0 : lastMergedNode.mergedNodeContent;
|
|
36
|
+
const mergeStartNode = endTokenDeleted && openStart > 0 && depth === openStart && mergeContent !== undefined;
|
|
37
|
+
const mergeEndNode = startTokenDeleted && openEnd > 0 && depth === openEnd && mergeContent !== undefined;
|
|
38
|
+
if (mergeStartNode || mergeEndNode) {
|
|
39
|
+
steps.push({
|
|
40
|
+
type: 'merge-fragment',
|
|
41
|
+
pos,
|
|
42
|
+
mergePos: mergeStartNode ? nodeEnd - openStart : pos + openEnd,
|
|
43
|
+
from,
|
|
44
|
+
to,
|
|
45
|
+
node,
|
|
46
|
+
fragment: setFragmentAsInserted(mergeContent, trackUtils.createNewInsertAttrs(trackAttrs), schema),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
else if (node.isText) {
|
|
50
|
+
steps.push({
|
|
51
|
+
type: 'delete-text',
|
|
52
|
+
pos,
|
|
53
|
+
from: Math.max(pos, from),
|
|
54
|
+
to: Math.min(nodeEnd, to),
|
|
55
|
+
node,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
else if (startTokenDeleted) {
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (nodeCompletelyDeleted) {
|
|
62
|
+
steps.push({
|
|
63
|
+
type: 'delete-node',
|
|
64
|
+
pos,
|
|
65
|
+
nodeEnd,
|
|
66
|
+
node,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return {
|
|
72
|
+
sliceWasSplit: !!(firstMergedNode || lastMergedNode),
|
|
73
|
+
newSliceContent: updatedSliceNodes
|
|
74
|
+
? Fragment.fromArray(updatedSliceNodes)
|
|
75
|
+
: insertSlice.content,
|
|
76
|
+
steps,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Fragment } from 'prosemirror-model';
|
|
2
|
+
import { liftTarget } from 'prosemirror-transform';
|
|
3
|
+
import { log } from '../utils/logger';
|
|
4
|
+
import { CHANGE_OPERATION } from '../types/change';
|
|
5
|
+
import { addTrackIdIfDoesntExist, getBlockInlineTrackedData } from '../compute/nodeHelpers';
|
|
6
|
+
export function deleteNode(node, pos, tr) {
|
|
7
|
+
var _a;
|
|
8
|
+
const startPos = tr.doc.resolve(pos + 1);
|
|
9
|
+
const range = startPos.blockRange(tr.doc.resolve(startPos.pos - 2 + node.nodeSize));
|
|
10
|
+
const targetDepth = range && liftTarget(range);
|
|
11
|
+
if (range && typeof targetDepth === 'number') {
|
|
12
|
+
return tr.lift(range, targetDepth);
|
|
13
|
+
}
|
|
14
|
+
const resPos = tr.doc.resolve(pos);
|
|
15
|
+
const canMergeToNodeAbove = resPos.parent !== tr.doc && resPos.nodeBefore && node.isBlock && ((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.isText);
|
|
16
|
+
if (canMergeToNodeAbove) {
|
|
17
|
+
return tr.replaceWith(pos - 1, pos + 1, Fragment.empty);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return tr.delete(pos, pos + node.nodeSize);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function deleteOrSetNodeDeleted(node, pos, newTr, deleteAttrs) {
|
|
24
|
+
const dataTracked = getBlockInlineTrackedData(node);
|
|
25
|
+
const inserted = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === CHANGE_OPERATION.insert);
|
|
26
|
+
const deleted = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === CHANGE_OPERATION.delete);
|
|
27
|
+
const updated = dataTracked === null || dataTracked === void 0 ? void 0 : dataTracked.find((d) => d.operation === CHANGE_OPERATION.set_node_attributes);
|
|
28
|
+
if (inserted && inserted.authorID === deleteAttrs.authorID) {
|
|
29
|
+
return deleteNode(node, pos, newTr);
|
|
30
|
+
}
|
|
31
|
+
if (!newTr.doc.nodeAt(pos)) {
|
|
32
|
+
log.error(`deleteOrSetNodeDeleted: no node found for deletion`, { pos, node, newTr });
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const newDeleted = deleted
|
|
36
|
+
? Object.assign(Object.assign({}, deleted), { updatedAt: deleteAttrs.updatedAt }) : addTrackIdIfDoesntExist(deleteAttrs);
|
|
37
|
+
newTr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { dataTracked: updated ? [newDeleted, updated] : [newDeleted] }), node.marks);
|
|
38
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Fragment } from 'prosemirror-model';
|
|
2
|
+
import { addTrackIdIfDoesntExist, getMergeableMarkTrackedAttrs } from '../compute/nodeHelpers';
|
|
3
|
+
export function deleteTextIfInserted(node, pos, newTr, schema, deleteAttrs, from, to) {
|
|
4
|
+
const start = from ? Math.max(pos, from) : pos;
|
|
5
|
+
const nodeEnd = pos + node.nodeSize;
|
|
6
|
+
const end = to ? Math.min(nodeEnd, to) : nodeEnd;
|
|
7
|
+
if (node.marks.find((m) => m.type === schema.marks.tracked_insert)) {
|
|
8
|
+
newTr.replaceWith(start, end, Fragment.empty);
|
|
9
|
+
return start;
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
const leftNode = newTr.doc.resolve(start).nodeBefore;
|
|
13
|
+
const leftMarks = getMergeableMarkTrackedAttrs(leftNode, deleteAttrs, schema);
|
|
14
|
+
const rightNode = newTr.doc.resolve(end).nodeAfter;
|
|
15
|
+
const rightMarks = getMergeableMarkTrackedAttrs(rightNode, deleteAttrs, schema);
|
|
16
|
+
const fromStartOfMark = start - (leftNode && leftMarks ? leftNode.nodeSize : 0);
|
|
17
|
+
const toEndOfMark = end + (rightNode && rightMarks ? rightNode.nodeSize : 0);
|
|
18
|
+
const createdAt = Math.min((leftMarks === null || leftMarks === void 0 ? void 0 : leftMarks.createdAt) || Number.MAX_VALUE, (rightMarks === null || rightMarks === void 0 ? void 0 : rightMarks.createdAt) || Number.MAX_VALUE, deleteAttrs.createdAt);
|
|
19
|
+
const dataTracked = addTrackIdIfDoesntExist(Object.assign(Object.assign(Object.assign(Object.assign({}, leftMarks), rightMarks), deleteAttrs), { createdAt }));
|
|
20
|
+
newTr.addMark(fromStartOfMark, toEndOfMark, schema.marks.tracked_delete.create({
|
|
21
|
+
dataTracked,
|
|
22
|
+
}));
|
|
23
|
+
return toEndOfMark;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Fragment } from 'prosemirror-model';
|
|
2
|
+
import { canJoin } from 'prosemirror-transform';
|
|
3
|
+
export function mergeNode(node, pos, tr) {
|
|
4
|
+
var _a;
|
|
5
|
+
if (canJoin(tr.doc, pos)) {
|
|
6
|
+
return tr.join(pos);
|
|
7
|
+
}
|
|
8
|
+
else if (!tr.doc.resolve(pos).nodeBefore) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const resPos = tr.doc.resolve(pos);
|
|
12
|
+
const canMergeToNodeAbove = (resPos.parent !== tr.doc || resPos.nodeBefore) && ((_a = node.firstChild) === null || _a === void 0 ? void 0 : _a.isText);
|
|
13
|
+
if (canMergeToNodeAbove) {
|
|
14
|
+
return tr.replaceWith(pos - 1, pos + 1, Fragment.empty);
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { shouldMergeTrackedAttributes } from '../compute/nodeHelpers';
|
|
2
|
+
export function mergeTrackedMarks(pos, doc, newTr, schema) {
|
|
3
|
+
const resolved = doc.resolve(pos);
|
|
4
|
+
const { nodeAfter, nodeBefore } = resolved;
|
|
5
|
+
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];
|
|
6
|
+
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];
|
|
7
|
+
if (!nodeAfter || !nodeBefore || !leftMark || !rightMark || leftMark.type !== rightMark.type) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const leftDataTracked = leftMark.attrs.dataTracked;
|
|
11
|
+
const rightDataTracked = rightMark.attrs.dataTracked;
|
|
12
|
+
if (!shouldMergeTrackedAttributes(leftDataTracked, rightDataTracked)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const isLeftOlder = (leftDataTracked.createdAt || 0) < (rightDataTracked.createdAt || 0);
|
|
16
|
+
const ancestorAttrs = isLeftOlder ? leftDataTracked : rightDataTracked;
|
|
17
|
+
const dataTracked = Object.assign(Object.assign({}, ancestorAttrs), { updatedAt: Date.now() });
|
|
18
|
+
const fromStartOfMark = pos - nodeBefore.nodeSize;
|
|
19
|
+
const toEndOfMark = pos + nodeAfter.nodeSize;
|
|
20
|
+
newTr.addMark(fromStartOfMark, toEndOfMark, leftMark.type.create(Object.assign(Object.assign({}, leftMark.attrs), { dataTracked })));
|
|
21
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
13
|
+
import { getAction, setAction, TrackChangesAction } from './actions';
|
|
14
|
+
import { ChangeSet } from './ChangeSet';
|
|
15
|
+
import { log, enableDebug } from './utils/logger';
|
|
16
|
+
import { applyAcceptedRejectedChanges } from './changes/applyChanges';
|
|
17
|
+
import { findChanges } from './changes/findChanges';
|
|
18
|
+
import { fixInconsistentChanges } from './changes/fixInconsistentChanges';
|
|
19
|
+
import { trackTransaction } from './steps/trackTransaction';
|
|
20
|
+
import { updateChangeAttrs } from './changes/updateChangeAttrs';
|
|
21
|
+
import { TrackChangesStatus } from './types/track';
|
|
22
|
+
export const trackChangesPluginKey = new PluginKey('track-changes');
|
|
23
|
+
export const trackChangesPlugin = (opts = { userID: 'anonymous:Anonymous' }) => {
|
|
24
|
+
const { userID, debug, skipTrsWithMetas = [] } = opts;
|
|
25
|
+
let editorView;
|
|
26
|
+
if (debug) {
|
|
27
|
+
enableDebug(true);
|
|
28
|
+
}
|
|
29
|
+
return new Plugin({
|
|
30
|
+
key: trackChangesPluginKey,
|
|
31
|
+
props: {
|
|
32
|
+
editable(state) {
|
|
33
|
+
var _a;
|
|
34
|
+
return ((_a = trackChangesPluginKey.getState(state)) === null || _a === void 0 ? void 0 : _a.status) !== TrackChangesStatus.viewSnapshots;
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
state: {
|
|
38
|
+
init(_config, state) {
|
|
39
|
+
return {
|
|
40
|
+
status: TrackChangesStatus.enabled,
|
|
41
|
+
userID,
|
|
42
|
+
changeSet: findChanges(state),
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
apply(tr, pluginState, _oldState, newState) {
|
|
46
|
+
const setUserID = getAction(tr, TrackChangesAction.setUserID);
|
|
47
|
+
const setStatus = getAction(tr, TrackChangesAction.setPluginStatus);
|
|
48
|
+
if (setUserID) {
|
|
49
|
+
return Object.assign(Object.assign({}, pluginState), { userID: setUserID });
|
|
50
|
+
}
|
|
51
|
+
else if (setStatus) {
|
|
52
|
+
return Object.assign(Object.assign({}, pluginState), { status: setStatus, changeSet: setStatus === TrackChangesStatus.disabled ? new ChangeSet() : findChanges(newState) });
|
|
53
|
+
}
|
|
54
|
+
else if (pluginState.status === TrackChangesStatus.disabled) {
|
|
55
|
+
return Object.assign(Object.assign({}, pluginState), { changeSet: new ChangeSet() });
|
|
56
|
+
}
|
|
57
|
+
let { changeSet } = pluginState, rest = __rest(pluginState, ["changeSet"]);
|
|
58
|
+
if (getAction(tr, TrackChangesAction.refreshChanges)) {
|
|
59
|
+
changeSet = findChanges(newState);
|
|
60
|
+
}
|
|
61
|
+
return Object.assign({ changeSet }, rest);
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
view(p) {
|
|
65
|
+
editorView = p;
|
|
66
|
+
return {
|
|
67
|
+
update: undefined,
|
|
68
|
+
destroy: undefined,
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
appendTransaction(trs, oldState, newState) {
|
|
72
|
+
const pluginState = trackChangesPluginKey.getState(newState);
|
|
73
|
+
if (!pluginState || pluginState.status === TrackChangesStatus.disabled || !(editorView === null || editorView === void 0 ? void 0 : editorView.editable)) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const { userID, changeSet } = pluginState;
|
|
77
|
+
let createdTr = newState.tr, docChanged = false;
|
|
78
|
+
log.info('TRS', trs);
|
|
79
|
+
trs.forEach((tr) => {
|
|
80
|
+
const wasAppended = tr.getMeta('appendedTransaction');
|
|
81
|
+
const skipMetaUsed = skipTrsWithMetas.some((m) => tr.getMeta(m) || (wasAppended === null || wasAppended === void 0 ? void 0 : wasAppended.getMeta(m)));
|
|
82
|
+
const skipTrackUsed = getAction(tr, TrackChangesAction.skipTrack) || (wasAppended && getAction(wasAppended, TrackChangesAction.skipTrack));
|
|
83
|
+
if (tr.docChanged && !skipMetaUsed && !skipTrackUsed && !tr.getMeta('history$') && !(wasAppended && tr.getMeta('origin') === 'paragraphs')) {
|
|
84
|
+
createdTr = trackTransaction(tr, oldState, createdTr, userID);
|
|
85
|
+
}
|
|
86
|
+
docChanged = docChanged || tr.docChanged;
|
|
87
|
+
const setChangeStatuses = getAction(tr, TrackChangesAction.setChangeStatuses);
|
|
88
|
+
if (setChangeStatuses) {
|
|
89
|
+
const { status, ids } = setChangeStatuses;
|
|
90
|
+
ids.forEach((changeId) => {
|
|
91
|
+
const change = changeSet === null || changeSet === void 0 ? void 0 : changeSet.get(changeId);
|
|
92
|
+
if (change) {
|
|
93
|
+
createdTr = updateChangeAttrs(createdTr, change, Object.assign(Object.assign({}, change.dataTracked), { status, reviewedByID: userID }), oldState.schema);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
else if (getAction(tr, TrackChangesAction.applyAndRemoveChanges)) {
|
|
98
|
+
const mapping = applyAcceptedRejectedChanges(createdTr, oldState.schema, changeSet.bothNodeChanges);
|
|
99
|
+
applyAcceptedRejectedChanges(createdTr, oldState.schema, changeSet.textChanges, mapping);
|
|
100
|
+
setAction(createdTr, TrackChangesAction.refreshChanges, true);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const changed = pluginState.changeSet.hasInconsistentData && fixInconsistentChanges(pluginState.changeSet, userID, createdTr, oldState.schema);
|
|
104
|
+
if (changed) {
|
|
105
|
+
log.warn('had to fix inconsistent changes in', createdTr);
|
|
106
|
+
}
|
|
107
|
+
if (docChanged || createdTr.docChanged || changed) {
|
|
108
|
+
createdTr.setMeta('origin', trackChangesPluginKey);
|
|
109
|
+
return setAction(createdTr, TrackChangesAction.refreshChanges, true);
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Slice } from 'prosemirror-model';
|
|
2
|
+
import { deleteAndMergeSplitNodes } from '../mutate/deleteAndMergeSplitNodes';
|
|
3
|
+
import { setFragmentAsInserted } from '../compute/setFragmentAsInserted';
|
|
4
|
+
import { log } from '../utils/logger';
|
|
5
|
+
import * as trackUtils from '../utils/track-utils';
|
|
6
|
+
import { TrackChangesAction } from '../actions';
|
|
7
|
+
export function trackReplaceAroundStep(step, oldState, tr, newTr, attrs) {
|
|
8
|
+
log.info('###### ReplaceAroundStep ######');
|
|
9
|
+
const { from, to, gapFrom, gapTo, insert, slice, structure, } = step;
|
|
10
|
+
const newStep = step.invert(oldState.doc);
|
|
11
|
+
const stepResult = newTr.maybeStep(newStep);
|
|
12
|
+
if (stepResult.failed) {
|
|
13
|
+
log.error(`inverting ReplaceAroundStep failed: "${stepResult.failed}"`, newStep);
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const gap = oldState.doc.slice(gapFrom, gapTo);
|
|
17
|
+
log.info('RETAINED GAP CONTENT', gap);
|
|
18
|
+
const { sliceWasSplit, newSliceContent, steps: deleteSteps, } = deleteAndMergeSplitNodes(from, to, { start: gapFrom, end: gapTo }, newTr.doc, newTr, oldState.schema, attrs, slice);
|
|
19
|
+
const steps = deleteSteps;
|
|
20
|
+
log.info('TR: new steps after applying delete', [...newTr.steps]);
|
|
21
|
+
log.info('DELETE STEPS: ', deleteSteps);
|
|
22
|
+
if (gap.size > 0 ||
|
|
23
|
+
(!structure && newSliceContent.size > 0) ||
|
|
24
|
+
tr.getMeta(TrackChangesAction.updateMetaNode)) {
|
|
25
|
+
log.info('newSliceContent', newSliceContent);
|
|
26
|
+
const openStart = slice.openStart !== slice.openEnd || newSliceContent.size === 0 ? 0 : slice.openStart;
|
|
27
|
+
const openEnd = slice.openStart !== slice.openEnd || newSliceContent.size === 0 ? 0 : slice.openEnd;
|
|
28
|
+
let insertedSlice = new Slice(setFragmentAsInserted(newSliceContent, trackUtils.createNewInsertAttrs(attrs), oldState.schema), openStart, openEnd);
|
|
29
|
+
if (gap.size > 0 || tr.getMeta(TrackChangesAction.updateMetaNode)) {
|
|
30
|
+
log.info('insertedSlice before inserted gap', insertedSlice);
|
|
31
|
+
insertedSlice = insertedSlice.insertAt(insertedSlice.size === 0 ? 0 : insert, gap.content);
|
|
32
|
+
log.info('insertedSlice after inserted gap', insertedSlice);
|
|
33
|
+
}
|
|
34
|
+
deleteSteps.push({
|
|
35
|
+
type: 'insert-slice',
|
|
36
|
+
from: gapFrom,
|
|
37
|
+
to: gapTo,
|
|
38
|
+
slice: insertedSlice,
|
|
39
|
+
sliceWasSplit,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
}
|
|
44
|
+
return steps;
|
|
45
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Slice } from 'prosemirror-model';
|
|
2
|
+
import { deleteAndMergeSplitNodes } from '../mutate/deleteAndMergeSplitNodes';
|
|
3
|
+
import { setFragmentAsInserted } from '../compute/setFragmentAsInserted';
|
|
4
|
+
import { log } from '../utils/logger';
|
|
5
|
+
import * as trackUtils from '../utils/track-utils';
|
|
6
|
+
export function trackReplaceStep(step, oldState, newTr, attrs, stepResult, currentStepDoc) {
|
|
7
|
+
log.info('###### ReplaceStep ######');
|
|
8
|
+
let selectionPos = 0;
|
|
9
|
+
const changeSteps = [];
|
|
10
|
+
step.getMap().forEach((fromA, toA, fromB, toB) => {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
log.info(`changed ranges: ${fromA} ${toA} ${fromB} ${toB}`);
|
|
13
|
+
const { slice } = step;
|
|
14
|
+
log.info('TR: steps before applying delete', [...newTr.steps]);
|
|
15
|
+
if (stepResult.failed) {
|
|
16
|
+
log.error(`invert ReplaceStep failed: "${stepResult.failed}"`);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const { sliceWasSplit, newSliceContent, steps: deleteSteps, } = deleteAndMergeSplitNodes(fromA, toA, undefined, currentStepDoc, newTr, oldState.schema, attrs, slice);
|
|
20
|
+
changeSteps.push(...deleteSteps);
|
|
21
|
+
log.info('TR: steps after applying delete', [...newTr.steps]);
|
|
22
|
+
log.info('DELETE STEPS: ', changeSteps);
|
|
23
|
+
function sameThingBackSpaced() {
|
|
24
|
+
if (changeSteps.length == 2 && newSliceContent.size > 0) {
|
|
25
|
+
const correspondingDeletion = changeSteps.find((step) => step.node.text === newSliceContent.content[0].text);
|
|
26
|
+
return correspondingDeletion;
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
const backSpacedText = sameThingBackSpaced();
|
|
31
|
+
if (backSpacedText) {
|
|
32
|
+
changeSteps.splice(changeSteps.indexOf(backSpacedText));
|
|
33
|
+
}
|
|
34
|
+
const textWasDeleted = !!changeSteps.length;
|
|
35
|
+
if (!backSpacedText && newSliceContent.size > 0) {
|
|
36
|
+
log.info('newSliceContent', newSliceContent);
|
|
37
|
+
const openStart = slice.openStart !== slice.openEnd ? 0 : slice.openStart;
|
|
38
|
+
const openEnd = slice.openStart !== slice.openEnd ? 0 : slice.openEnd;
|
|
39
|
+
changeSteps.push({
|
|
40
|
+
type: 'insert-slice',
|
|
41
|
+
from: textWasDeleted ? fromB : toA,
|
|
42
|
+
to: textWasDeleted ? toB - 1 : toA,
|
|
43
|
+
sliceWasSplit,
|
|
44
|
+
slice: new Slice(setFragmentAsInserted(newSliceContent, trackUtils.createNewInsertAttrs(attrs), oldState.schema), openStart, openEnd),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
selectionPos = ((_a = window.event) === null || _a === void 0 ? void 0 : _a.code) === 'Delete' || ((_b = window.event) === null || _b === void 0 ? void 0 : _b.inputType) === 'deleteContentForward' ? toA : fromA;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return [changeSteps, selectionPos];
|
|
52
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { NodeSelection as NodeSelectionClass } from 'prosemirror-state';
|
|
2
|
+
import { ReplaceAroundStep, ReplaceStep } from 'prosemirror-transform';
|
|
3
|
+
import { log } from '../utils/logger';
|
|
4
|
+
import { CHANGE_STATUS } from '../types/change';
|
|
5
|
+
import { trackReplaceAroundStep } from './trackReplaceAroundStep';
|
|
6
|
+
import { trackReplaceStep } from './trackReplaceStep';
|
|
7
|
+
import { processChangeSteps } from '../change-steps/processChangeSteps';
|
|
8
|
+
import { diffChangeSteps } from '../change-steps/diffChangeSteps';
|
|
9
|
+
const getSelectionStaticConstructor = (sel) => Object.getPrototypeOf(sel).constructor;
|
|
10
|
+
const isHighlightMarkerNode = (node) => node && node.type === node.type.schema.nodes.highlight_marker;
|
|
11
|
+
export function trackTransaction(tr, oldState, newTr, authorID) {
|
|
12
|
+
var _a, _b, _c, _d;
|
|
13
|
+
const emptyAttrs = {
|
|
14
|
+
authorID,
|
|
15
|
+
reviewedByID: null,
|
|
16
|
+
createdAt: tr.time,
|
|
17
|
+
updatedAt: tr.time,
|
|
18
|
+
status: CHANGE_STATUS.pending,
|
|
19
|
+
};
|
|
20
|
+
const wasNodeSelection = tr.selection instanceof NodeSelectionClass;
|
|
21
|
+
let iters = 0;
|
|
22
|
+
log.info('ORIGINAL transaction', tr);
|
|
23
|
+
for (let i = tr.steps.length - 1; i >= 0; i--) {
|
|
24
|
+
const step = tr.steps[i];
|
|
25
|
+
log.info('transaction step', step);
|
|
26
|
+
iters += 1;
|
|
27
|
+
if (iters > 20) {
|
|
28
|
+
console.error('@manuscripts/track-changes-plugin: Possible infinite loop in iterating tr.steps, tracking skipped!\n' +
|
|
29
|
+
'This is probably an error with the library, please report back to maintainers with a reproduction if possible', newTr);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
else if (!(step instanceof ReplaceStep) && step.constructor.name === 'ReplaceStep') {
|
|
33
|
+
console.error('@manuscripts/track-changes-plugin: Multiple prosemirror-transform packages imported, alias/dedupe them ' +
|
|
34
|
+
'or instanceof checks fail as well as creating new steps');
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
else if (step instanceof ReplaceStep) {
|
|
38
|
+
const { slice } = step;
|
|
39
|
+
if (((_b = (_a = slice === null || slice === void 0 ? void 0 : slice.content) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.length) === 1 &&
|
|
40
|
+
isHighlightMarkerNode(slice.content.content[0])) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const newStep = step.invert(tr.docs[i]);
|
|
44
|
+
const stepResult = newTr.maybeStep(newStep);
|
|
45
|
+
let [steps, startPos] = trackReplaceStep(step, oldState, newTr, emptyAttrs, stepResult, tr.docs[i]);
|
|
46
|
+
if (steps.length === 1) {
|
|
47
|
+
const step = steps[0];
|
|
48
|
+
if (isHighlightMarkerNode((step === null || step === void 0 ? void 0 : step.node) || ((_d = (_c = step === null || step === void 0 ? void 0 : step.slice) === null || _c === void 0 ? void 0 : _c.content) === null || _d === void 0 ? void 0 : _d.content[0]))) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
log.info('CHANGES: ', steps);
|
|
53
|
+
const deleted = steps.filter((s) => s.type !== 'insert-slice');
|
|
54
|
+
const inserted = steps.filter((s) => s.type === 'insert-slice');
|
|
55
|
+
steps = diffChangeSteps(deleted, inserted);
|
|
56
|
+
log.info('DIFFED STEPS: ', steps);
|
|
57
|
+
const [mapping, selectionPos] = processChangeSteps(steps, startPos || tr.selection.head, newTr, emptyAttrs, oldState.schema);
|
|
58
|
+
if (!wasNodeSelection) {
|
|
59
|
+
const sel = getSelectionStaticConstructor(tr.selection);
|
|
60
|
+
const near = sel.near(newTr.doc.resolve(selectionPos), -1);
|
|
61
|
+
newTr.setSelection(near);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (step instanceof ReplaceAroundStep) {
|
|
65
|
+
let steps = trackReplaceAroundStep(step, oldState, tr, newTr, emptyAttrs);
|
|
66
|
+
const deleted = steps.filter((s) => s.type !== 'insert-slice');
|
|
67
|
+
const inserted = steps.filter((s) => s.type === 'insert-slice');
|
|
68
|
+
log.info('INSERT STEPS: ', inserted);
|
|
69
|
+
steps = diffChangeSteps(deleted, inserted);
|
|
70
|
+
log.info('DIFFED STEPS: ', steps);
|
|
71
|
+
const [mapping, selectionPos] = processChangeSteps(steps, tr.selection.from, newTr, emptyAttrs, oldState.schema);
|
|
72
|
+
}
|
|
73
|
+
tr.getMeta('inputType') && newTr.setMeta('inputType', tr.getMeta('inputType'));
|
|
74
|
+
tr.getMeta('uiEvent') && newTr.setMeta('uiEvent', tr.getMeta('uiEvent'));
|
|
75
|
+
}
|
|
76
|
+
if (wasNodeSelection) {
|
|
77
|
+
console.log('%c Getting into node select! ', 'background: #222; color: #bada55');
|
|
78
|
+
const mappedPos = newTr.mapping.map(tr.selection.from, -1);
|
|
79
|
+
const sel = getSelectionStaticConstructor(tr.selection);
|
|
80
|
+
newTr.setSelection(sel.create(newTr.doc, mappedPos));
|
|
81
|
+
}
|
|
82
|
+
log.info('NEW transaction', newTr);
|
|
83
|
+
return newTr;
|
|
84
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export var CHANGE_OPERATION;
|
|
2
|
+
(function (CHANGE_OPERATION) {
|
|
3
|
+
CHANGE_OPERATION["insert"] = "insert";
|
|
4
|
+
CHANGE_OPERATION["delete"] = "delete";
|
|
5
|
+
CHANGE_OPERATION["set_node_attributes"] = "set_attrs";
|
|
6
|
+
})(CHANGE_OPERATION || (CHANGE_OPERATION = {}));
|
|
7
|
+
export var CHANGE_STATUS;
|
|
8
|
+
(function (CHANGE_STATUS) {
|
|
9
|
+
CHANGE_STATUS["accepted"] = "accepted";
|
|
10
|
+
CHANGE_STATUS["rejected"] = "rejected";
|
|
11
|
+
CHANGE_STATUS["pending"] = "pending";
|
|
12
|
+
})(CHANGE_STATUS || (CHANGE_STATUS = {}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export var TrackChangesStatus;
|
|
2
|
+
(function (TrackChangesStatus) {
|
|
3
|
+
TrackChangesStatus["enabled"] = "enabled";
|
|
4
|
+
TrackChangesStatus["viewSnapshots"] = "view-snapshots";
|
|
5
|
+
TrackChangesStatus["disabled"] = "disabled";
|
|
6
|
+
})(TrackChangesStatus || (TrackChangesStatus = {}));
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
export const logger = debug('track');
|
|
3
|
+
export const log = {
|
|
4
|
+
info(str, obj) {
|
|
5
|
+
if (obj) {
|
|
6
|
+
logger(str, obj);
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
logger(str);
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
warn(str, obj) {
|
|
13
|
+
if (obj) {
|
|
14
|
+
logger(`%c WARNING ${str}`, 'color: #f3f32c', obj);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
logger(`%c WARNING ${str}`, 'color: #f3f32c');
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
error(str, obj) {
|
|
21
|
+
if (obj) {
|
|
22
|
+
logger(`%c ERROR ${str}`, 'color: #ff4242', obj);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
logger(`%c ERROR ${str}`, 'color: #ff4242');
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
export const enableDebug = (enabled) => {
|
|
30
|
+
if (enabled) {
|
|
31
|
+
debug.enable('track');
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
debug.disable();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { CHANGE_OPERATION } from '../types/change';
|
|
13
|
+
export function createNewInsertAttrs(attrs) {
|
|
14
|
+
return Object.assign(Object.assign({}, attrs), { operation: CHANGE_OPERATION.insert });
|
|
15
|
+
}
|
|
16
|
+
export function createNewDeleteAttrs(attrs) {
|
|
17
|
+
return Object.assign(Object.assign({}, attrs), { operation: CHANGE_OPERATION.delete });
|
|
18
|
+
}
|
|
19
|
+
export function createNewUpdateAttrs(attrs, oldAttrs) {
|
|
20
|
+
const { dataTracked } = oldAttrs, restAttrs = __rest(oldAttrs, ["dataTracked"]);
|
|
21
|
+
return Object.assign(Object.assign({}, attrs), { operation: CHANGE_OPERATION.set_node_attributes, oldAttrs: JSON.parse(JSON.stringify(restAttrs)) });
|
|
22
|
+
}
|