@fluid-experimental/property-changeset 2.0.0-internal.3.0.5 → 2.0.0-internal.3.1.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.
- package/README.md +1 -0
- package/dist/changeset.d.ts +2 -2
- package/dist/changeset.d.ts.map +1 -1
- package/dist/changeset.js +61 -45
- package/dist/changeset.js.map +1 -1
- package/dist/changeset_operations/array.d.ts +6 -6
- package/dist/changeset_operations/array.d.ts.map +1 -1
- package/dist/changeset_operations/array.js +87 -56
- package/dist/changeset_operations/array.js.map +1 -1
- package/dist/changeset_operations/arrayChangesetIterator.d.ts.map +1 -1
- package/dist/changeset_operations/arrayChangesetIterator.js +43 -41
- package/dist/changeset_operations/arrayChangesetIterator.js.map +1 -1
- package/dist/changeset_operations/changesetConflictTypes.d.ts.map +1 -1
- package/dist/changeset_operations/changesetConflictTypes.js.map +1 -1
- package/dist/changeset_operations/indexedCollection.d.ts.map +1 -1
- package/dist/changeset_operations/indexedCollection.js +76 -44
- package/dist/changeset_operations/indexedCollection.js.map +1 -1
- package/dist/changeset_operations/isEmptyChangeset.d.ts.map +1 -1
- package/dist/changeset_operations/isEmptyChangeset.js +2 -1
- package/dist/changeset_operations/isEmptyChangeset.js.map +1 -1
- package/dist/changeset_operations/operationTypes.d.ts.map +1 -1
- package/dist/changeset_operations/operationTypes.js.map +1 -1
- package/dist/helpers/typeidHelper.d.ts +10 -10
- package/dist/helpers/typeidHelper.d.ts.map +1 -1
- package/dist/helpers/typeidHelper.js +19 -17
- package/dist/helpers/typeidHelper.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/isReservedKeyword.d.ts.map +1 -1
- package/dist/isReservedKeyword.js.map +1 -1
- package/dist/pathHelper.d.ts.map +1 -1
- package/dist/pathHelper.js +16 -10
- package/dist/pathHelper.js.map +1 -1
- package/dist/rebase.d.ts.map +1 -1
- package/dist/rebase.js +20 -13
- package/dist/rebase.js.map +1 -1
- package/dist/templateSchema.d.ts.map +1 -1
- package/dist/templateSchema.js +10 -11
- package/dist/templateSchema.js.map +1 -1
- package/dist/templateValidator.d.ts.map +1 -1
- package/dist/templateValidator.js +135 -102
- package/dist/templateValidator.js.map +1 -1
- package/dist/test/array.spec.js +141 -343
- package/dist/test/array.spec.js.map +1 -1
- package/dist/test/pathHelper.spec.js +299 -166
- package/dist/test/pathHelper.spec.js.map +1 -1
- package/dist/test/reversibleCs.spec.js.map +1 -1
- package/dist/test/schemaValidator.js +3 -1
- package/dist/test/schemaValidator.js.map +1 -1
- package/dist/test/schemas/badBothPropertiesAndTypeid.js +8 -8
- package/dist/test/schemas/badBothPropertiesAndTypeid.js.map +1 -1
- package/dist/test/schemas/badInvalidSemverInTypeid.js +18 -16
- package/dist/test/schemas/badInvalidSemverInTypeid.js.map +1 -1
- package/dist/test/schemas/badMissingSemverInTypeid.js +18 -16
- package/dist/test/schemas/badMissingSemverInTypeid.js.map +1 -1
- package/dist/test/schemas/badNestedProperties.js +18 -17
- package/dist/test/schemas/badNestedProperties.js.map +1 -1
- package/dist/test/schemas/badPrimitiveTypeid.js +9 -8
- package/dist/test/schemas/badPrimitiveTypeid.js.map +1 -1
- package/dist/test/schemas/badVersionedTypeid.js +19 -17
- package/dist/test/schemas/badVersionedTypeid.js.map +1 -1
- package/dist/test/schemas/goodColorPalette.js +4 -4
- package/dist/test/schemas/goodColorPalette.js.map +1 -1
- package/dist/test/schemas/goodDraftAsVersion.js +2 -4
- package/dist/test/schemas/goodDraftAsVersion.js.map +1 -1
- package/dist/test/schemas/goodPointId.js +18 -16
- package/dist/test/schemas/goodPointId.js.map +1 -1
- package/dist/test/schemas/goodReferenceAndRegular.js +5 -5
- package/dist/test/schemas/goodReferenceAndRegular.js.map +1 -1
- package/dist/test/schemas/goodReservedTypes.js +8 -7
- package/dist/test/schemas/goodReservedTypes.js.map +1 -1
- package/dist/test/schemas/goodUIBorder.js +19 -16
- package/dist/test/schemas/goodUIBorder.js.map +1 -1
- package/dist/test/tsconfig.tsbuildinfo +1 -1
- package/dist/test/validator/templateSyntax.spec.js.map +1 -1
- package/dist/test/validator/templateValidator.spec.js +329 -306
- package/dist/test/validator/templateValidator.spec.js.map +1 -1
- package/dist/test/validator/typeidHelper.spec.js +98 -65
- package/dist/test/validator/typeidHelper.spec.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +149 -95
- package/dist/utils.js.map +1 -1
- package/dist/validationResultBuilder.d.ts.map +1 -1
- package/dist/validationResultBuilder.js.map +1 -1
- package/lib/changeset.js +63 -47
- package/lib/changeset.js.map +1 -1
- package/lib/changeset_operations/array.js +88 -57
- package/lib/changeset_operations/array.js.map +1 -1
- package/lib/changeset_operations/arrayChangesetIterator.js +43 -41
- package/lib/changeset_operations/arrayChangesetIterator.js.map +1 -1
- package/lib/changeset_operations/changesetConflictTypes.js.map +1 -1
- package/lib/changeset_operations/indexedCollection.js +76 -44
- package/lib/changeset_operations/indexedCollection.js.map +1 -1
- package/lib/changeset_operations/isEmptyChangeset.js +2 -1
- package/lib/changeset_operations/isEmptyChangeset.js.map +1 -1
- package/lib/changeset_operations/operationTypes.js.map +1 -1
- package/lib/helpers/typeidHelper.js +19 -17
- package/lib/helpers/typeidHelper.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/isReservedKeyword.js.map +1 -1
- package/lib/pathHelper.js +17 -11
- package/lib/pathHelper.js.map +1 -1
- package/lib/rebase.js +20 -13
- package/lib/rebase.js.map +1 -1
- package/lib/templateSchema.js +10 -11
- package/lib/templateSchema.js.map +1 -1
- package/lib/templateValidator.js +135 -102
- package/lib/templateValidator.js.map +1 -1
- package/lib/utils.js +149 -95
- package/lib/utils.js.map +1 -1
- package/lib/validationResultBuilder.js.map +1 -1
- package/package.json +100 -100
|
@@ -65,8 +65,7 @@ export class ArrayChangeSetIterator {
|
|
|
65
65
|
let type;
|
|
66
66
|
this._op.removeInsertOperation = undefined;
|
|
67
67
|
// Process the current remove entry
|
|
68
|
-
if (this._changeSet.remove &&
|
|
69
|
-
this._currentIndices.remove < this._changeSet.remove.length) {
|
|
68
|
+
if (this._changeSet.remove && this._currentIndices.remove < this._changeSet.remove.length) {
|
|
70
69
|
type = ArrayChangeSetIterator.types.REMOVE;
|
|
71
70
|
currentIndex = this._changeSet.remove[this._currentIndices.remove][0];
|
|
72
71
|
let currentLength = this._changeSet.remove[this._currentIndices.remove][1];
|
|
@@ -76,8 +75,10 @@ export class ArrayChangeSetIterator {
|
|
|
76
75
|
// Check, whether this is a removeInsertOperation
|
|
77
76
|
if (this._changeSet.insert &&
|
|
78
77
|
this._currentIndices.insert < this._changeSet.insert.length &&
|
|
79
|
-
this._changeSet.insert[this._currentIndices.insert][0] <=
|
|
80
|
-
|
|
78
|
+
this._changeSet.insert[this._currentIndices.insert][0] <=
|
|
79
|
+
currentIndex + currentLength) {
|
|
80
|
+
this._op.removeInsertOperation =
|
|
81
|
+
this._changeSet.insert[this._currentIndices.insert];
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
// Process the current insert entry (we prefer remove over insert, since this prevents the array from growing more
|
|
@@ -125,51 +126,52 @@ export class ArrayChangeSetIterator {
|
|
|
125
126
|
this._op.operation = this._changeSet.remove[this._currentIndices.remove];
|
|
126
127
|
this._op.offset = this._currentOffset;
|
|
127
128
|
// Update the current offset. For a remove we have to decrement it by the number of the removed elements
|
|
128
|
-
var removedElements = isNumber(this._op.operation[1])
|
|
129
|
+
var removedElements = isNumber(this._op.operation[1])
|
|
130
|
+
? this._op.operation[1]
|
|
131
|
+
: this._op.operation[1].length;
|
|
129
132
|
this._lastOperationOffset -= removedElements;
|
|
130
133
|
// Shift the internal index
|
|
131
134
|
this._currentIndices.remove++;
|
|
132
135
|
break;
|
|
133
|
-
case ArrayChangeSetIterator.types.MODIFY:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
nextModify[1] = nextModify[1].substr(insertPosition - nextModify[0]);
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
partialModify[1] = nextModify[1].splice(0, insertPosition - nextModify[0]);
|
|
160
|
-
}
|
|
161
|
-
nextModify[0] = insertPosition;
|
|
162
|
-
// use the whole modify
|
|
163
|
-
this._op.operation = partialModify;
|
|
136
|
+
case ArrayChangeSetIterator.types.MODIFY: {
|
|
137
|
+
this._op.type = ArrayChangeSetIterator.types.MODIFY;
|
|
138
|
+
this._op.offset = this._currentOffset;
|
|
139
|
+
// check, if the modify's range overlaps with coming insert changes:
|
|
140
|
+
let nextModify = this._copiedModifies[this._currentIndices.modify];
|
|
141
|
+
const modifyEnd = nextModify[0] + nextModify[1].length;
|
|
142
|
+
if (this._changeSet.insert &&
|
|
143
|
+
this._currentIndices.insert < this._changeSet.insert.length &&
|
|
144
|
+
this._changeSet.insert[this._currentIndices.insert][0] < modifyEnd) {
|
|
145
|
+
// we have an overlap and need to cut the modify
|
|
146
|
+
const insertPosition = this._changeSet.insert[this._currentIndices.insert][0];
|
|
147
|
+
// if we haven't copied the change set's modifies yet, we need to do that now
|
|
148
|
+
if (this._copiedModifies === this._changeSet.modify) {
|
|
149
|
+
this._copiedModifies = this._copyModifies(this._changeSet.modify);
|
|
150
|
+
// now we need to update nextModify!
|
|
151
|
+
nextModify = this._copiedModifies[this._currentIndices.modify];
|
|
152
|
+
}
|
|
153
|
+
// use modify only up to insert's position
|
|
154
|
+
// build a partial modify and cut the remaining one:
|
|
155
|
+
const partialModify = [nextModify[0], undefined];
|
|
156
|
+
if (isString(nextModify[1])) {
|
|
157
|
+
partialModify[1] = nextModify[1].substr(0, insertPosition - nextModify[0]);
|
|
158
|
+
nextModify[1] = nextModify[1].substr(insertPosition - nextModify[0]);
|
|
164
159
|
}
|
|
165
160
|
else {
|
|
166
|
-
|
|
167
|
-
this._op.operation = nextModify;
|
|
168
|
-
// Shift the internal index
|
|
169
|
-
this._currentIndices.modify++;
|
|
161
|
+
partialModify[1] = nextModify[1].splice(0, insertPosition - nextModify[0]);
|
|
170
162
|
}
|
|
171
|
-
|
|
163
|
+
nextModify[0] = insertPosition;
|
|
164
|
+
// use the whole modify
|
|
165
|
+
this._op.operation = partialModify;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
// use the whole modify
|
|
169
|
+
this._op.operation = nextModify;
|
|
170
|
+
// Shift the internal index
|
|
171
|
+
this._currentIndices.modify++;
|
|
172
172
|
}
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
173
175
|
default:
|
|
174
176
|
throw new Error(`ArrayChangeSetIterator: ${MSG.UNKNOWN_OPERATION}`);
|
|
175
177
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arrayChangesetIterator.js","sourceRoot":"","sources":["../../src/changeset_operations/arrayChangesetIterator.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n/**\n * @fileoverview Iterator to iterate over array ChangeSets\n */\n\n import isNumber from \"lodash/isNumber\";\n import isString from \"lodash/isString\";\n\n// @ts-ignore\nimport { constants } from \"@fluid-experimental/property-common\";\n\nimport { SerializedChangeSet } from \"../changeset\";\nimport { ArrayIteratorOperationTypes } from \"./operationTypes\";\n\nconst { MSG } = constants;\n\ntype genericArray = (number | string | (SerializedChangeSet & { typeid: string; }))[];\nexport type arrayInsertList = [number, string | genericArray];\nexport type arrayModifyList = [number, string | genericArray] | [number, string, string] | [number, genericArray, genericArray];\nexport type arrayRemoveList = [number, number | string | genericArray];\n\n/**\n * Description of an array operation\n */\nexport interface OperationDescription {\n _absoluteBegin?: number;\n type?: ArrayIteratorOperationTypes;\n offset?: number;\n}\n\n/**\n * Description of an insert array operation\n */\nexport interface InsertOperation extends OperationDescription {\n type: ArrayIteratorOperationTypes.INSERT;\n removeInsertOperation?: arrayInsertList;\n operation?: arrayInsertList;\n}\n\n/**\n * Description of a remove array operation\n */\nexport interface RemoveOperation extends OperationDescription {\n type: ArrayIteratorOperationTypes.REMOVE;\n removeInsertOperation?: arrayRemoveList;\n operation?: arrayRemoveList;\n}\n\n/**\n * Description of a modify array operation\n */\nexport interface ModifyOperation extends OperationDescription {\n type: ArrayIteratorOperationTypes.MODIFY;\n removeInsertOperation?: arrayModifyList;\n operation: arrayModifyList;\n}\n\n/**\n * Description of a modify array operation\n */\n export interface NOPOperation extends Omit<OperationDescription, \"removeInsertOperation\" | \"operation\"> {\n type: ArrayIteratorOperationTypes.NOP;\n operation?: [];\n}\n\nexport type NoneNOPOperation = RemoveOperation | InsertOperation | ModifyOperation;\nexport type GenericOperation = NoneNOPOperation | NOPOperation;\n\n/**\n * Iterator class which iterates over an array ChangeSet. It will successively return the operations ordered by their\n * position within the array. Additionally, it will keep track of the modifications to the array indices caused\n * by the previous operations.\n *\n */\nexport class ArrayChangeSetIterator {\n static types = ArrayIteratorOperationTypes; // @TODO Not sure if this is still required if we export it separately.\n\n private readonly _changeSet: SerializedChangeSet;\n private _copiedModifies: string | any[];\n private readonly _currentIndices: { insert: number; remove: number; modify: number; };\n private _currentOffset: number;\n private _lastOperationIndex: number;\n private _lastOperationOffset: number;\n\n private _atEnd: boolean;\n private _op: GenericOperation;\n\n public get opDescription(): GenericOperation {\n return this._op;\n }\n\n public get currentOffset(): number {\n return this._currentOffset;\n }\n\n public get lastOperationIndex(): number {\n return this._lastOperationIndex;\n }\n\n public get lastOperationOffset(): number {\n return this._lastOperationOffset;\n }\n\n /**\n * @param in_changeSet - The ChangeSet to iterate over (this has to be an array ChangeSet\n */\n constructor(in_changeSet: SerializedChangeSet) {\n this._changeSet = in_changeSet;\n // if we need to chop overlapping modifies internally, so we have to copy them\n // we do this lazy and only if really needed\n this._copiedModifies = in_changeSet.modify;\n this._currentIndices = {\n insert: 0,\n remove: 0,\n modify: 0,\n };\n\n this._currentOffset = 0;\n this._lastOperationIndex = -1;\n this._lastOperationOffset = 0;\n this._atEnd = false;\n\n this._op = {\n type: ArrayIteratorOperationTypes.NOP,\n offset: 0,\n operation: undefined,\n };\n\n // go to the first element\n this.next();\n }\n\n /**\n * Returns the next operation in the ChangeSet\n * @returns true, if there are operations left\n */\n next(): boolean {\n // Find the smallest index in the operations lists\n let currentIndex = Infinity;\n let type: ArrayIteratorOperationTypes;\n (this._op as any).removeInsertOperation = undefined;\n // Process the current remove entry\n if (this._changeSet.remove &&\n this._currentIndices.remove < this._changeSet.remove.length) {\n type = ArrayChangeSetIterator.types.REMOVE;\n currentIndex = this._changeSet.remove[this._currentIndices.remove][0];\n let currentLength = this._changeSet.remove[this._currentIndices.remove][1];\n if (!isNumber(currentLength)) {\n currentLength = currentLength.length;\n }\n\n // Check, whether this is a removeInsertOperation\n if (this._changeSet.insert &&\n this._currentIndices.insert < this._changeSet.insert.length &&\n this._changeSet.insert[this._currentIndices.insert][0] <= currentIndex + currentLength) {\n (this._op as InsertOperation).removeInsertOperation = this._changeSet.insert[this._currentIndices.insert];\n }\n }\n\n // Process the current insert entry (we prefer remove over insert, since this prevents the array from growing more\n // than necessary)\n if (this._changeSet.insert &&\n this._currentIndices.insert < this._changeSet.insert.length &&\n this._changeSet.insert[this._currentIndices.insert][0] < currentIndex) {\n type = ArrayChangeSetIterator.types.INSERT;\n currentIndex = this._changeSet.insert[this._currentIndices.insert][0];\n }\n\n // Process the current modify entry\n if (this._copiedModifies &&\n this._currentIndices.modify < this._copiedModifies.length &&\n this._copiedModifies[this._currentIndices.modify][0] < currentIndex) {\n type = ArrayChangeSetIterator.types.MODIFY;\n }\n\n if (this._lastOperationIndex !== currentIndex) {\n this._currentOffset += this._lastOperationOffset;\n this._lastOperationIndex = currentIndex;\n this._lastOperationOffset = 0;\n }\n\n // We have found nothing, so we are at the end of the ChangeSet\n if (type === undefined) {\n this._op.type = ArrayChangeSetIterator.types.NOP;\n this._op.offset = this._currentOffset;\n this._op.operation = undefined;\n this._atEnd = true;\n return false;\n }\n\n // Determine the return value and update the internal indices and offsets depending on the next operation\n switch (type) {\n case ArrayChangeSetIterator.types.INSERT:\n this._op.type = ArrayChangeSetIterator.types.INSERT;\n // Define the return value\n this._op.operation = this._changeSet.insert[this._currentIndices.insert];\n this._op.offset = this._currentOffset;\n // Update the current offset. For an insert we have to increase it by the number of the inserted elements\n this._lastOperationOffset += (this._op.operation[1] as any).length;\n\n // Shift the internal index\n this._currentIndices.insert++;\n break;\n case ArrayChangeSetIterator.types.REMOVE:\n this._op.type = ArrayChangeSetIterator.types.REMOVE;\n // Define the return value\n this._op.operation = this._changeSet.remove[this._currentIndices.remove];\n this._op.offset = this._currentOffset;\n // Update the current offset. For a remove we have to decrement it by the number of the removed elements\n var removedElements = isNumber(this._op.operation[1]) ? this._op.operation[1] : this._op.operation[1].length;\n this._lastOperationOffset -= removedElements;\n\n // Shift the internal index\n this._currentIndices.remove++;\n break;\n case ArrayChangeSetIterator.types.MODIFY:\n {\n this._op.type = ArrayChangeSetIterator.types.MODIFY;\n this._op.offset = this._currentOffset;\n // check, if the modify's range overlaps with coming insert changes:\n let nextModify = this._copiedModifies[this._currentIndices.modify];\n const modifyEnd = nextModify[0] + nextModify[1].length;\n if (this._changeSet.insert &&\n this._currentIndices.insert < this._changeSet.insert.length &&\n this._changeSet.insert[this._currentIndices.insert][0] < modifyEnd) {\n // we have an overlap and need to cut the modify\n const insertPosition = this._changeSet.insert[this._currentIndices.insert][0];\n\n // if we haven't copied the change set's modifies yet, we need to do that now\n if (this._copiedModifies === this._changeSet.modify) {\n this._copiedModifies = this._copyModifies(this._changeSet.modify);\n // now we need to update nextModify!\n nextModify = this._copiedModifies[this._currentIndices.modify];\n }\n\n // use modify only up to insert's position\n\n // build a partial modify and cut the remaining one:\n const partialModify: arrayModifyList = [nextModify[0], undefined];\n if (isString(nextModify[1])) {\n partialModify[1] = nextModify[1].substr(0, insertPosition - nextModify[0]);\n nextModify[1] = nextModify[1].substr(insertPosition - nextModify[0]);\n } else {\n partialModify[1] = nextModify[1].splice(0, insertPosition - nextModify[0]);\n }\n\n nextModify[0] = insertPosition;\n\n // use the whole modify\n this._op.operation = partialModify;\n } else {\n // use the whole modify\n this._op.operation = nextModify;\n\n // Shift the internal index\n this._currentIndices.modify++;\n }\n break;\n }\n default:\n throw new Error(`ArrayChangeSetIterator: ${MSG.UNKNOWN_OPERATION}`);\n }\n this._atEnd = false;\n return true;\n }\n\n /**\n * @returns true, if there are no more operations left\n */\n atEnd(): boolean {\n return this._atEnd;\n }\n\n private _copyModifies(in_modifies: string[]) {\n if (!in_modifies || in_modifies.length === 0) {\n return undefined;\n }\n const result = [];\n for (let i = 0; i < in_modifies.length; i++) {\n result.push([in_modifies[i][0], in_modifies[i][1].slice()]);\n }\n return result;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"arrayChangesetIterator.js","sourceRoot":"","sources":["../../src/changeset_operations/arrayChangesetIterator.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n/**\n * @fileoverview Iterator to iterate over array ChangeSets\n */\n\nimport isNumber from \"lodash/isNumber\";\nimport isString from \"lodash/isString\";\n\n// @ts-ignore\nimport { constants } from \"@fluid-experimental/property-common\";\n\nimport { SerializedChangeSet } from \"../changeset\";\nimport { ArrayIteratorOperationTypes } from \"./operationTypes\";\n\nconst { MSG } = constants;\n\ntype genericArray = (number | string | (SerializedChangeSet & { typeid: string }))[];\nexport type arrayInsertList = [number, string | genericArray];\nexport type arrayModifyList =\n\t| [number, string | genericArray]\n\t| [number, string, string]\n\t| [number, genericArray, genericArray];\nexport type arrayRemoveList = [number, number | string | genericArray];\n\n/**\n * Description of an array operation\n */\nexport interface OperationDescription {\n\t_absoluteBegin?: number;\n\ttype?: ArrayIteratorOperationTypes;\n\toffset?: number;\n}\n\n/**\n * Description of an insert array operation\n */\nexport interface InsertOperation extends OperationDescription {\n\ttype: ArrayIteratorOperationTypes.INSERT;\n\tremoveInsertOperation?: arrayInsertList;\n\toperation?: arrayInsertList;\n}\n\n/**\n * Description of a remove array operation\n */\nexport interface RemoveOperation extends OperationDescription {\n\ttype: ArrayIteratorOperationTypes.REMOVE;\n\tremoveInsertOperation?: arrayRemoveList;\n\toperation?: arrayRemoveList;\n}\n\n/**\n * Description of a modify array operation\n */\nexport interface ModifyOperation extends OperationDescription {\n\ttype: ArrayIteratorOperationTypes.MODIFY;\n\tremoveInsertOperation?: arrayModifyList;\n\toperation: arrayModifyList;\n}\n\n/**\n * Description of a modify array operation\n */\nexport interface NOPOperation\n\textends Omit<OperationDescription, \"removeInsertOperation\" | \"operation\"> {\n\ttype: ArrayIteratorOperationTypes.NOP;\n\toperation?: [];\n}\n\nexport type NoneNOPOperation = RemoveOperation | InsertOperation | ModifyOperation;\nexport type GenericOperation = NoneNOPOperation | NOPOperation;\n\n/**\n * Iterator class which iterates over an array ChangeSet. It will successively return the operations ordered by their\n * position within the array. Additionally, it will keep track of the modifications to the array indices caused\n * by the previous operations.\n *\n */\nexport class ArrayChangeSetIterator {\n\tstatic types = ArrayIteratorOperationTypes; // @TODO Not sure if this is still required if we export it separately.\n\n\tprivate readonly _changeSet: SerializedChangeSet;\n\tprivate _copiedModifies: string | any[];\n\tprivate readonly _currentIndices: { insert: number; remove: number; modify: number };\n\tprivate _currentOffset: number;\n\tprivate _lastOperationIndex: number;\n\tprivate _lastOperationOffset: number;\n\n\tprivate _atEnd: boolean;\n\tprivate _op: GenericOperation;\n\n\tpublic get opDescription(): GenericOperation {\n\t\treturn this._op;\n\t}\n\n\tpublic get currentOffset(): number {\n\t\treturn this._currentOffset;\n\t}\n\n\tpublic get lastOperationIndex(): number {\n\t\treturn this._lastOperationIndex;\n\t}\n\n\tpublic get lastOperationOffset(): number {\n\t\treturn this._lastOperationOffset;\n\t}\n\n\t/**\n\t * @param in_changeSet - The ChangeSet to iterate over (this has to be an array ChangeSet\n\t */\n\tconstructor(in_changeSet: SerializedChangeSet) {\n\t\tthis._changeSet = in_changeSet;\n\t\t// if we need to chop overlapping modifies internally, so we have to copy them\n\t\t// we do this lazy and only if really needed\n\t\tthis._copiedModifies = in_changeSet.modify;\n\t\tthis._currentIndices = {\n\t\t\tinsert: 0,\n\t\t\tremove: 0,\n\t\t\tmodify: 0,\n\t\t};\n\n\t\tthis._currentOffset = 0;\n\t\tthis._lastOperationIndex = -1;\n\t\tthis._lastOperationOffset = 0;\n\t\tthis._atEnd = false;\n\n\t\tthis._op = {\n\t\t\ttype: ArrayIteratorOperationTypes.NOP,\n\t\t\toffset: 0,\n\t\t\toperation: undefined,\n\t\t};\n\n\t\t// go to the first element\n\t\tthis.next();\n\t}\n\n\t/**\n\t * Returns the next operation in the ChangeSet\n\t * @returns true, if there are operations left\n\t */\n\tnext(): boolean {\n\t\t// Find the smallest index in the operations lists\n\t\tlet currentIndex = Infinity;\n\t\tlet type: ArrayIteratorOperationTypes;\n\t\t(this._op as any).removeInsertOperation = undefined;\n\t\t// Process the current remove entry\n\t\tif (this._changeSet.remove && this._currentIndices.remove < this._changeSet.remove.length) {\n\t\t\ttype = ArrayChangeSetIterator.types.REMOVE;\n\t\t\tcurrentIndex = this._changeSet.remove[this._currentIndices.remove][0];\n\t\t\tlet currentLength = this._changeSet.remove[this._currentIndices.remove][1];\n\t\t\tif (!isNumber(currentLength)) {\n\t\t\t\tcurrentLength = currentLength.length;\n\t\t\t}\n\n\t\t\t// Check, whether this is a removeInsertOperation\n\t\t\tif (\n\t\t\t\tthis._changeSet.insert &&\n\t\t\t\tthis._currentIndices.insert < this._changeSet.insert.length &&\n\t\t\t\tthis._changeSet.insert[this._currentIndices.insert][0] <=\n\t\t\t\t\tcurrentIndex + currentLength\n\t\t\t) {\n\t\t\t\t(this._op as InsertOperation).removeInsertOperation =\n\t\t\t\t\tthis._changeSet.insert[this._currentIndices.insert];\n\t\t\t}\n\t\t}\n\n\t\t// Process the current insert entry (we prefer remove over insert, since this prevents the array from growing more\n\t\t// than necessary)\n\t\tif (\n\t\t\tthis._changeSet.insert &&\n\t\t\tthis._currentIndices.insert < this._changeSet.insert.length &&\n\t\t\tthis._changeSet.insert[this._currentIndices.insert][0] < currentIndex\n\t\t) {\n\t\t\ttype = ArrayChangeSetIterator.types.INSERT;\n\t\t\tcurrentIndex = this._changeSet.insert[this._currentIndices.insert][0];\n\t\t}\n\n\t\t// Process the current modify entry\n\t\tif (\n\t\t\tthis._copiedModifies &&\n\t\t\tthis._currentIndices.modify < this._copiedModifies.length &&\n\t\t\tthis._copiedModifies[this._currentIndices.modify][0] < currentIndex\n\t\t) {\n\t\t\ttype = ArrayChangeSetIterator.types.MODIFY;\n\t\t}\n\n\t\tif (this._lastOperationIndex !== currentIndex) {\n\t\t\tthis._currentOffset += this._lastOperationOffset;\n\t\t\tthis._lastOperationIndex = currentIndex;\n\t\t\tthis._lastOperationOffset = 0;\n\t\t}\n\n\t\t// We have found nothing, so we are at the end of the ChangeSet\n\t\tif (type === undefined) {\n\t\t\tthis._op.type = ArrayChangeSetIterator.types.NOP;\n\t\t\tthis._op.offset = this._currentOffset;\n\t\t\tthis._op.operation = undefined;\n\t\t\tthis._atEnd = true;\n\t\t\treturn false;\n\t\t}\n\n\t\t// Determine the return value and update the internal indices and offsets depending on the next operation\n\t\tswitch (type) {\n\t\t\tcase ArrayChangeSetIterator.types.INSERT:\n\t\t\t\tthis._op.type = ArrayChangeSetIterator.types.INSERT;\n\t\t\t\t// Define the return value\n\t\t\t\tthis._op.operation = this._changeSet.insert[this._currentIndices.insert];\n\t\t\t\tthis._op.offset = this._currentOffset;\n\t\t\t\t// Update the current offset. For an insert we have to increase it by the number of the inserted elements\n\t\t\t\tthis._lastOperationOffset += (this._op.operation[1] as any).length;\n\n\t\t\t\t// Shift the internal index\n\t\t\t\tthis._currentIndices.insert++;\n\t\t\t\tbreak;\n\t\t\tcase ArrayChangeSetIterator.types.REMOVE:\n\t\t\t\tthis._op.type = ArrayChangeSetIterator.types.REMOVE;\n\t\t\t\t// Define the return value\n\t\t\t\tthis._op.operation = this._changeSet.remove[this._currentIndices.remove];\n\t\t\t\tthis._op.offset = this._currentOffset;\n\t\t\t\t// Update the current offset. For a remove we have to decrement it by the number of the removed elements\n\t\t\t\tvar removedElements = isNumber(this._op.operation[1])\n\t\t\t\t\t? this._op.operation[1]\n\t\t\t\t\t: this._op.operation[1].length;\n\t\t\t\tthis._lastOperationOffset -= removedElements;\n\n\t\t\t\t// Shift the internal index\n\t\t\t\tthis._currentIndices.remove++;\n\t\t\t\tbreak;\n\t\t\tcase ArrayChangeSetIterator.types.MODIFY: {\n\t\t\t\tthis._op.type = ArrayChangeSetIterator.types.MODIFY;\n\t\t\t\tthis._op.offset = this._currentOffset;\n\t\t\t\t// check, if the modify's range overlaps with coming insert changes:\n\t\t\t\tlet nextModify = this._copiedModifies[this._currentIndices.modify];\n\t\t\t\tconst modifyEnd = nextModify[0] + nextModify[1].length;\n\t\t\t\tif (\n\t\t\t\t\tthis._changeSet.insert &&\n\t\t\t\t\tthis._currentIndices.insert < this._changeSet.insert.length &&\n\t\t\t\t\tthis._changeSet.insert[this._currentIndices.insert][0] < modifyEnd\n\t\t\t\t) {\n\t\t\t\t\t// we have an overlap and need to cut the modify\n\t\t\t\t\tconst insertPosition = this._changeSet.insert[this._currentIndices.insert][0];\n\n\t\t\t\t\t// if we haven't copied the change set's modifies yet, we need to do that now\n\t\t\t\t\tif (this._copiedModifies === this._changeSet.modify) {\n\t\t\t\t\t\tthis._copiedModifies = this._copyModifies(this._changeSet.modify);\n\t\t\t\t\t\t// now we need to update nextModify!\n\t\t\t\t\t\tnextModify = this._copiedModifies[this._currentIndices.modify];\n\t\t\t\t\t}\n\n\t\t\t\t\t// use modify only up to insert's position\n\n\t\t\t\t\t// build a partial modify and cut the remaining one:\n\t\t\t\t\tconst partialModify: arrayModifyList = [nextModify[0], undefined];\n\t\t\t\t\tif (isString(nextModify[1])) {\n\t\t\t\t\t\tpartialModify[1] = nextModify[1].substr(0, insertPosition - nextModify[0]);\n\t\t\t\t\t\tnextModify[1] = nextModify[1].substr(insertPosition - nextModify[0]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpartialModify[1] = nextModify[1].splice(0, insertPosition - nextModify[0]);\n\t\t\t\t\t}\n\n\t\t\t\t\tnextModify[0] = insertPosition;\n\n\t\t\t\t\t// use the whole modify\n\t\t\t\t\tthis._op.operation = partialModify;\n\t\t\t\t} else {\n\t\t\t\t\t// use the whole modify\n\t\t\t\t\tthis._op.operation = nextModify;\n\n\t\t\t\t\t// Shift the internal index\n\t\t\t\t\tthis._currentIndices.modify++;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`ArrayChangeSetIterator: ${MSG.UNKNOWN_OPERATION}`);\n\t\t}\n\t\tthis._atEnd = false;\n\t\treturn true;\n\t}\n\n\t/**\n\t * @returns true, if there are no more operations left\n\t */\n\tatEnd(): boolean {\n\t\treturn this._atEnd;\n\t}\n\n\tprivate _copyModifies(in_modifies: string[]) {\n\t\tif (!in_modifies || in_modifies.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst result = [];\n\t\tfor (let i = 0; i < in_modifies.length; i++) {\n\t\t\tresult.push([in_modifies[i][0], in_modifies[i][1].slice()]);\n\t\t}\n\t\treturn result;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changesetConflictTypes.js","sourceRoot":"","sources":["../../src/changeset_operations/changesetConflictTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH;;GAEG;AAEH,MAAM,CAAN,IAAY,YAqBX;AArBD,WAAY,YAAY;
|
|
1
|
+
{"version":3,"file":"changesetConflictTypes.js","sourceRoot":"","sources":["../../src/changeset_operations/changesetConflictTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH;;GAEG;AAEH,MAAM,CAAN,IAAY,YAqBX;AArBD,WAAY,YAAY;IACvB,oGAAoG;IACpG,mFAA0B,CAAA;IAC1B,6CAA6C;IAC7C,iEAAa,CAAA;IACb,wCAAwC;IACxC,6FAA2B,CAAA;IAC3B;;;;OAIG;IACH,mHAAsC,CAAA;IACtC,kEAAkE;IAClE,+FAA4B,CAAA;IAC5B,+GAA+G;IAC/G,6EAAmB,CAAA;IACnB,oDAAoD;IACpD,2EAAkB,CAAA;IAClB,+CAA+C;IAC/C,qFAAuB,CAAA;AACxB,CAAC,EArBW,YAAY,KAAZ,YAAY,QAqBvB","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n/**\n * @fileoverview Conflict types that can occur during changeset operations\n */\n\nexport enum ConflictType {\n\t/** We had two incompatible ChangeSets, they probably were with respect to different base commits */\n\tINVALID_CHANGESET_BASE = 1,\n\t/** A value was changed in both ChangeSets */\n\tCOLLIDING_SET,\n\t/** A deleted child node was modified */\n\tENTRY_MODIFIED_AFTER_REMOVE,\n\t/** A child was modified after it had been removed and added.\n\t *\n\t * The modification can no longer be applied, since the affected object has changed and thus\n\t * the ChangeSet is no longer compatible.\n\t */\n\tENTRY_MODIFICATION_AFTER_REMOVE_INSERT,\n\t/** An entry with the same key was inserted into the collection */\n\tINSERTED_ENTRY_WITH_SAME_KEY,\n\t/** A property was removed after a modify, this should mostly be safe, be we report it for completeness sake */\n\tREMOVE_AFTER_MODIFY,\n\t// Templates do not match from one commit to another\n\tMISMATCH_TEMPLATES,\n\t// Tried to insert inside a removed array range\n\tINSERT_IN_REMOVED_RANGE,\n}\n"]}
|
|
@@ -68,8 +68,9 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
68
68
|
// Get and initialize the corresponding entries in the existing collection
|
|
69
69
|
let removedEntries = in_appliedPropertyChanges.remove;
|
|
70
70
|
io_basePropertyChanges = io_basePropertyChanges || {};
|
|
71
|
-
io_basePropertyChanges.remove =
|
|
72
|
-
|
|
71
|
+
io_basePropertyChanges.remove =
|
|
72
|
+
io_basePropertyChanges.remove ||
|
|
73
|
+
(Array.isArray(in_appliedPropertyChanges.remove) ? [] : {});
|
|
73
74
|
let baseInserted = io_basePropertyChanges.insert || {};
|
|
74
75
|
let baseRemoved = io_basePropertyChanges.remove;
|
|
75
76
|
let baseModified = io_basePropertyChanges.modify;
|
|
@@ -94,7 +95,8 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
else {
|
|
97
|
-
if (baseModified &&
|
|
98
|
+
if (baseModified &&
|
|
99
|
+
baseModified[removedTypes[t]] &&
|
|
98
100
|
baseModified[removedTypes[t]][removedKeys[i]] !== undefined) {
|
|
99
101
|
delete baseModified[removedTypes[t]][removedKeys[i]];
|
|
100
102
|
// If all entries for a typeid have been removed, we can remove
|
|
@@ -110,7 +112,8 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
110
112
|
if (!baseRemoved[removedTypes[t]]) {
|
|
111
113
|
baseRemoved[removedTypes[t]] = {};
|
|
112
114
|
}
|
|
113
|
-
baseRemoved[removedTypes[t]][removedKeys[i]] =
|
|
115
|
+
baseRemoved[removedTypes[t]][removedKeys[i]] =
|
|
116
|
+
removedEntries[removedTypes[t]][removedKeys[i]];
|
|
114
117
|
}
|
|
115
118
|
}
|
|
116
119
|
}
|
|
@@ -193,11 +196,14 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
193
196
|
let baseRemoved = io_basePropertyChanges.remove;
|
|
194
197
|
// Insert the inserted entries
|
|
195
198
|
// If no typeids are included, we just use a placeholder for the iteration below
|
|
196
|
-
const insertedTypeids = isPrimitiveTypeid
|
|
199
|
+
const insertedTypeids = isPrimitiveTypeid
|
|
200
|
+
? [undefined]
|
|
201
|
+
: Object.keys(in_appliedPropertyChanges.insert);
|
|
197
202
|
for (let i = 0; i < insertedTypeids.length; i++) {
|
|
198
203
|
let typeid = insertedTypeids[i];
|
|
199
|
-
const insertedEntries = isPrimitiveTypeid
|
|
200
|
-
|
|
204
|
+
const insertedEntries = isPrimitiveTypeid
|
|
205
|
+
? in_appliedPropertyChanges.insert
|
|
206
|
+
: in_appliedPropertyChanges.insert[typeid];
|
|
201
207
|
const insertedKeys = Object.keys(insertedEntries);
|
|
202
208
|
let removalCS;
|
|
203
209
|
if (baseRemoved) {
|
|
@@ -211,7 +217,10 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
211
217
|
// TODO: We should actually compute a diff between the two and recursively convert portions to modifies
|
|
212
218
|
// Instead, right now, we only handle the case where the two keys cancel each out perfectly, i.e.,
|
|
213
219
|
// the insert is reinserting exactly what was removed.
|
|
214
|
-
if (!isPrimitiveTypeid &&
|
|
220
|
+
if (!isPrimitiveTypeid &&
|
|
221
|
+
removalCS &&
|
|
222
|
+
isObject(removalCS) &&
|
|
223
|
+
removalCS[key] !== undefined) {
|
|
215
224
|
// Split out the two parts: all the keys other than remove/insert should match exactly.
|
|
216
225
|
// The contents 'remove' and 'insert', if they exist, should also match.
|
|
217
226
|
deeplyEqualCS = !!insertedEntries[key].insert === !!removalCS[key].remove;
|
|
@@ -220,13 +229,20 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
220
229
|
deeplyEqualCS = isEqual(insertedEntries[key].insert, removalCS[key].remove);
|
|
221
230
|
}
|
|
222
231
|
// Finally, check if the data being inserted matches the data that was removed
|
|
223
|
-
const insertedEntry = isObject(insertedEntries[key])
|
|
224
|
-
|
|
232
|
+
const insertedEntry = isObject(insertedEntries[key])
|
|
233
|
+
? without(insertedEntries[key], "insert")
|
|
234
|
+
: insertedEntries[key];
|
|
235
|
+
const removedEntry = isObject(removalCS[key])
|
|
236
|
+
? without(removalCS[key], "remove")
|
|
237
|
+
: removalCS[key];
|
|
225
238
|
deeplyEqualCS = deeplyEqualCS && isEqual(insertedEntry, removedEntry);
|
|
226
239
|
}
|
|
227
|
-
if ((isPrimitiveTypeid ||
|
|
240
|
+
if ((isPrimitiveTypeid ||
|
|
241
|
+
TypeIdHelper.isPrimitiveType(typeid) ||
|
|
242
|
+
deeplyEqualCS) &&
|
|
228
243
|
removalCS &&
|
|
229
|
-
((Array.isArray(removalCS) && includes(baseRemoved, key)) ||
|
|
244
|
+
((Array.isArray(removalCS) && includes(baseRemoved, key)) ||
|
|
245
|
+
removalCS[key] !== undefined)) {
|
|
230
246
|
// A remove and insert are combined into a modify for primitive types
|
|
231
247
|
// Remove the old remove command
|
|
232
248
|
let oldValueMatches = false;
|
|
@@ -239,7 +255,8 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
239
255
|
}
|
|
240
256
|
}
|
|
241
257
|
else {
|
|
242
|
-
oldValueMatches =
|
|
258
|
+
oldValueMatches =
|
|
259
|
+
deeplyEqualCS || removalCS[key] === insertedEntries[key];
|
|
243
260
|
delete removalCS[key];
|
|
244
261
|
}
|
|
245
262
|
// Insert a modify command instead
|
|
@@ -249,7 +266,8 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
249
266
|
io_basePropertyChanges.modify[key] = insertedEntries[key];
|
|
250
267
|
}
|
|
251
268
|
else {
|
|
252
|
-
io_basePropertyChanges.modify[typeid] =
|
|
269
|
+
io_basePropertyChanges.modify[typeid] =
|
|
270
|
+
io_basePropertyChanges.modify[typeid] || {};
|
|
253
271
|
io_basePropertyChanges.modify[typeid][key] = cloneDeep(insertedEntries[key]);
|
|
254
272
|
}
|
|
255
273
|
}
|
|
@@ -257,7 +275,8 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
257
275
|
else if (isPrimitiveTypeid && baseInserted[key] === undefined) {
|
|
258
276
|
baseInserted[key] = insertedEntries[key];
|
|
259
277
|
}
|
|
260
|
-
else if (!isPrimitiveTypeid &&
|
|
278
|
+
else if (!isPrimitiveTypeid &&
|
|
279
|
+
(!baseInserted[typeid] || baseInserted[typeid][key] === undefined)) {
|
|
261
280
|
baseInserted[typeid] = baseInserted[typeid] || {};
|
|
262
281
|
baseInserted[typeid][key] = cloneDeep(insertedEntries[key]);
|
|
263
282
|
}
|
|
@@ -319,7 +338,8 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
319
338
|
if (typeid === "Int64" || typeid === "Uint64") {
|
|
320
339
|
newValue = newValue.slice();
|
|
321
340
|
}
|
|
322
|
-
if (baseInserted[typeid][key] &&
|
|
341
|
+
if (baseInserted[typeid][key] &&
|
|
342
|
+
baseInserted[typeid][key].hasOwnProperty("value")) {
|
|
323
343
|
baseInserted[typeid][key].value = newValue;
|
|
324
344
|
}
|
|
325
345
|
else {
|
|
@@ -330,7 +350,8 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
330
350
|
this.performApplyAfterOnPropertyWithTypeid(key, baseInserted[typeid], modifiedEntries[typeid], typeid, false, in_options);
|
|
331
351
|
}
|
|
332
352
|
}
|
|
333
|
-
else if (baseModified[typeid] &&
|
|
353
|
+
else if (baseModified[typeid] &&
|
|
354
|
+
baseModified[typeid][key] !== undefined) {
|
|
334
355
|
// If there was a previous modification operation, we have to merge the two
|
|
335
356
|
if (isEntryPrimitiveType && typeid !== "String") {
|
|
336
357
|
// Primitive types can simply be overwritten, however we have an exception for
|
|
@@ -397,9 +418,9 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
397
418
|
const key = keys[j];
|
|
398
419
|
// Store the type of the change
|
|
399
420
|
changesByKeys[key] = changesByKeys[key] || {};
|
|
400
|
-
changesByKeys[key][in_changePrefix] = changesByKeys[key][in_changePrefix]
|
|
401
|
-
`${changesByKeys[key][in_changePrefix]}_${in_changeIdentifier}`
|
|
402
|
-
in_changeIdentifier;
|
|
421
|
+
changesByKeys[key][in_changePrefix] = changesByKeys[key][in_changePrefix]
|
|
422
|
+
? `${changesByKeys[key][in_changePrefix]}_${in_changeIdentifier}`
|
|
423
|
+
: in_changeIdentifier;
|
|
403
424
|
// If applicable store the typeid of the change
|
|
404
425
|
if (in_typeidChange) {
|
|
405
426
|
changesByKeys[key][`${in_changePrefix}Typeid`] = in_typeidChange;
|
|
@@ -466,9 +487,9 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
466
487
|
const changedKeys = Object.keys(changesByKeys);
|
|
467
488
|
for (let i = 0; i < changedKeys.length; i++) {
|
|
468
489
|
const key = changedKeys[i];
|
|
469
|
-
const newPath = in_useSquareBracketsInPath
|
|
470
|
-
`${in_basePath}[${PathHelper.quotePathSegmentIfNeeded(key)}]`
|
|
471
|
-
joinPaths(in_basePath, PathHelper.quotePathSegmentIfNeeded(key), PROPERTY_PATH_DELIMITER);
|
|
490
|
+
const newPath = in_useSquareBracketsInPath
|
|
491
|
+
? `${in_basePath}[${PathHelper.quotePathSegmentIfNeeded(key)}]`
|
|
492
|
+
: joinPaths(in_basePath, PathHelper.quotePathSegmentIfNeeded(key), PROPERTY_PATH_DELIMITER);
|
|
472
493
|
const modification = changesByKeys[key];
|
|
473
494
|
if (modification.own && modification.other) {
|
|
474
495
|
/*
|
|
@@ -506,7 +527,8 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
506
527
|
// A key was modified after it had been removed
|
|
507
528
|
if (modification.own === "modify" && modification.other === "modify") {
|
|
508
529
|
if (isPrimitiveTypeid ||
|
|
509
|
-
(TypeIdHelper.isPrimitiveType(modification.ownTypeid) &&
|
|
530
|
+
(TypeIdHelper.isPrimitiveType(modification.ownTypeid) &&
|
|
531
|
+
modification.ownTypeid !== "String")) {
|
|
510
532
|
// We have two modification operations that affect the same entry for a base type.
|
|
511
533
|
// This is a legal operation, the second one will overwrite the first one, but we
|
|
512
534
|
// report it as a possible conflict
|
|
@@ -528,10 +550,13 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
528
550
|
ownValue = ownValue.value;
|
|
529
551
|
}
|
|
530
552
|
let rebaseValue = rebasedModify[key];
|
|
531
|
-
if (typeof rebaseValue === "object" &&
|
|
553
|
+
if (typeof rebaseValue === "object" &&
|
|
554
|
+
rebaseValue.hasOwnProperty("value")) {
|
|
532
555
|
rebaseValue = rebaseValue.value;
|
|
533
556
|
}
|
|
534
|
-
if (modification.ownTypeid === "Int64" ||
|
|
557
|
+
if (modification.ownTypeid === "Int64" ||
|
|
558
|
+
modification.ownTypeid === "Uint64" ||
|
|
559
|
+
ownValue.length === 2) {
|
|
535
560
|
// For (u)int64, values are arrays of 2 elements
|
|
536
561
|
if (ownValue[0] === rebaseValue[0] && ownValue[1] === rebaseValue[1]) {
|
|
537
562
|
delete rebasedModify[key];
|
|
@@ -548,8 +573,9 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
548
573
|
}
|
|
549
574
|
}
|
|
550
575
|
else if (modification.own === "remove" && modification.other === "modify") {
|
|
551
|
-
modifyMap = modification.otherTypeid
|
|
552
|
-
io_rebasePropertyChangeSet.modify
|
|
576
|
+
modifyMap = modification.otherTypeid
|
|
577
|
+
? io_rebasePropertyChangeSet.modify[modification.otherTypeid]
|
|
578
|
+
: io_rebasePropertyChangeSet.modify;
|
|
553
579
|
// Create the conflict information
|
|
554
580
|
let conflict = {
|
|
555
581
|
path: newPath,
|
|
@@ -560,7 +586,8 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
560
586
|
// Delete the modification from the rebased ChangeSet
|
|
561
587
|
delete modifyMap[key];
|
|
562
588
|
}
|
|
563
|
-
else if (modification.own === "remove_insert" &&
|
|
589
|
+
else if (modification.own === "remove_insert" &&
|
|
590
|
+
modification.other === "modify") {
|
|
564
591
|
// We have a conflicting change. A node was removed and inserted (replaced) in the original
|
|
565
592
|
// ChangeSet and then modified by the rebased ChangeSet. Since the base of the modification
|
|
566
593
|
// can have been changed significantly by this operation, we don't know whether we can
|
|
@@ -578,8 +605,9 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
578
605
|
else if ((modification.own === "modify" || modification.own === "remove") &&
|
|
579
606
|
(modification.other === "remove" || modification.other === "remove_insert")) {
|
|
580
607
|
if (modification.own === "modify") {
|
|
581
|
-
modifyMap = modification.ownTypeid
|
|
582
|
-
in_ownPropertyChangeSet.modify
|
|
608
|
+
modifyMap = modification.ownTypeid
|
|
609
|
+
? in_ownPropertyChangeSet.modify[modification.ownTypeid]
|
|
610
|
+
: in_ownPropertyChangeSet.modify;
|
|
583
611
|
// Create the conflict information
|
|
584
612
|
let conflict = {
|
|
585
613
|
path: newPath,
|
|
@@ -604,10 +632,10 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
604
632
|
}
|
|
605
633
|
}
|
|
606
634
|
else if (modification.own === "insert" && modification.other === "insert") {
|
|
607
|
-
if (isPrimitiveTypeid ||
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
io_rebasePropertyChangeSet.insert;
|
|
635
|
+
if (isPrimitiveTypeid || TypeIdHelper.isPrimitiveType(modification.ownTypeid)) {
|
|
636
|
+
let insertMap = modification.otherTypeid
|
|
637
|
+
? io_rebasePropertyChangeSet.insert[modification.otherTypeid]
|
|
638
|
+
: io_rebasePropertyChangeSet.insert;
|
|
611
639
|
// We have two insert operations that affect the same key for a primitive type.
|
|
612
640
|
// This is a legal operation, the second one will overwrite the first one, but we
|
|
613
641
|
// report it as a possible conflicting set
|
|
@@ -620,14 +648,16 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
620
648
|
// Convert to modify
|
|
621
649
|
let oldValue;
|
|
622
650
|
if (modification.otherTypeid) {
|
|
623
|
-
io_rebasePropertyChangeSet.modify =
|
|
651
|
+
io_rebasePropertyChangeSet.modify =
|
|
652
|
+
io_rebasePropertyChangeSet.modify || {};
|
|
624
653
|
io_rebasePropertyChangeSet.modify[modification.otherTypeid] =
|
|
625
654
|
io_rebasePropertyChangeSet.modify[modification.otherTypeid] || {};
|
|
626
655
|
modifyMap = io_rebasePropertyChangeSet.modify[modification.otherTypeid];
|
|
627
656
|
oldValue = in_ownPropertyChangeSet.insert[modification.ownTypeid][key];
|
|
628
657
|
}
|
|
629
658
|
else {
|
|
630
|
-
io_rebasePropertyChangeSet.modify =
|
|
659
|
+
io_rebasePropertyChangeSet.modify =
|
|
660
|
+
io_rebasePropertyChangeSet.modify || {};
|
|
631
661
|
modifyMap = io_rebasePropertyChangeSet.modify;
|
|
632
662
|
oldValue = in_ownPropertyChangeSet.insert[key];
|
|
633
663
|
}
|
|
@@ -637,8 +667,9 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
637
667
|
else {
|
|
638
668
|
// Here we have two insert operations for objects. Since these affect a whole sub-tree and not
|
|
639
669
|
// just a single value, we cannot easily convert it into a modify and instead report it as invalid
|
|
640
|
-
let insertMap = modification.otherTypeid
|
|
641
|
-
io_rebasePropertyChangeSet.insert
|
|
670
|
+
let insertMap = modification.otherTypeid
|
|
671
|
+
? io_rebasePropertyChangeSet.insert[modification.otherTypeid]
|
|
672
|
+
: io_rebasePropertyChangeSet.insert;
|
|
642
673
|
// Create the conflict information
|
|
643
674
|
let conflict = {
|
|
644
675
|
path: newPath,
|
|
@@ -650,9 +681,11 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
650
681
|
delete insertMap[key];
|
|
651
682
|
}
|
|
652
683
|
}
|
|
653
|
-
else if (modification.own === "remove_insert" &&
|
|
654
|
-
|
|
655
|
-
|
|
684
|
+
else if (modification.own === "remove_insert" &&
|
|
685
|
+
modification.other === "remove_insert") {
|
|
686
|
+
let insertMap = modification.otherTypeid
|
|
687
|
+
? io_rebasePropertyChangeSet.insert[modification.otherTypeid]
|
|
688
|
+
: io_rebasePropertyChangeSet.insert;
|
|
656
689
|
// Raise the duplicate inserts as a conflict
|
|
657
690
|
let conflict = {
|
|
658
691
|
path: newPath,
|
|
@@ -683,8 +716,7 @@ export var ChangeSetIndexedCollectionFunctions;
|
|
|
683
716
|
else {
|
|
684
717
|
// Remove remove operations from the ChangeSet
|
|
685
718
|
if (Array.isArray(io_rebasePropertyChangeSet[modification.other])) {
|
|
686
|
-
io_rebasePropertyChangeSet[modification.other] =
|
|
687
|
-
without(io_rebasePropertyChangeSet[modification.other], key);
|
|
719
|
+
io_rebasePropertyChangeSet[modification.other] = without(io_rebasePropertyChangeSet[modification.other], key);
|
|
688
720
|
}
|
|
689
721
|
else {
|
|
690
722
|
delete io_rebasePropertyChangeSet[modification.other][key];
|