@fluidframework/merge-tree 0.57.1 → 0.58.0-55561
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/base.d.ts +0 -1
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js.map +1 -1
- package/dist/client.d.ts +0 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +8 -29
- package/dist/client.js.map +1 -1
- package/dist/collections.d.ts +0 -3
- package/dist/collections.d.ts.map +1 -1
- package/dist/collections.js +6 -22
- package/dist/collections.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/mergeTree.d.ts +8 -26
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +16 -277
- package/dist/mergeTree.js.map +1 -1
- package/dist/ops.d.ts +0 -6
- package/dist/ops.d.ts.map +1 -1
- package/dist/ops.js +1 -8
- package/dist/ops.js.map +1 -1
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +0 -9
- package/dist/partialLengths.js.map +1 -1
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +2 -15
- package/dist/properties.js.map +1 -1
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +3 -6
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/textSegment.d.ts.map +1 -1
- package/dist/textSegment.js +0 -14
- package/dist/textSegment.js.map +1 -1
- package/lib/base.d.ts +0 -1
- package/lib/base.d.ts.map +1 -1
- package/lib/base.js.map +1 -1
- package/lib/client.d.ts +0 -2
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +5 -26
- package/lib/client.js.map +1 -1
- package/lib/collections.d.ts +0 -3
- package/lib/collections.d.ts.map +1 -1
- package/lib/collections.js +6 -22
- package/lib/collections.js.map +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/lib/mergeTree.d.ts +8 -26
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +15 -274
- package/lib/mergeTree.js.map +1 -1
- package/lib/ops.d.ts +0 -6
- package/lib/ops.d.ts.map +1 -1
- package/lib/ops.js +0 -7
- package/lib/ops.js.map +1 -1
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +0 -9
- package/lib/partialLengths.js.map +1 -1
- package/lib/properties.d.ts.map +1 -1
- package/lib/properties.js +2 -15
- package/lib/properties.js.map +1 -1
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +3 -6
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/textSegment.d.ts.map +1 -1
- package/lib/textSegment.js +1 -15
- package/lib/textSegment.js.map +1 -1
- package/package.json +10 -10
- package/src/base.ts +0 -1
- package/src/client.ts +5 -29
- package/src/collections.ts +7 -24
- package/src/index.ts +0 -1
- package/src/mergeTree.ts +31 -306
- package/src/ops.ts +0 -7
- package/src/partialLengths.ts +0 -10
- package/src/properties.ts +7 -15
- package/src/snapshotlegacy.ts +4 -6
- package/src/textSegment.ts +2 -17
- package/dist/text.d.ts +0 -8
- package/dist/text.d.ts.map +0 -1
- package/dist/text.js +0 -78
- package/dist/text.js.map +0 -1
- package/lib/text.d.ts +0 -8
- package/lib/text.d.ts.map +0 -1
- package/lib/text.js +0 -73
- package/lib/text.js.map +0 -1
- package/src/text.ts +0 -83
package/lib/textSegment.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { BaseSegment
|
|
5
|
+
import { BaseSegment } from "./mergeTree";
|
|
6
6
|
import { LocalReferenceCollection } from "./localReference";
|
|
7
7
|
// Maximum length of text segment to be considered to be merged with other segment.
|
|
8
8
|
// Maximum segment length is at least 2x of it (not taking into account initial segment creation).
|
|
@@ -109,12 +109,6 @@ export class MergeTreeTextHelper {
|
|
|
109
109
|
this.gatherText = (segment, pos, refSeq, clientId, start, end, accumText) => {
|
|
110
110
|
let _start = start;
|
|
111
111
|
if (TextSegment.is(segment)) {
|
|
112
|
-
if (MergeTree.traceGatherText) {
|
|
113
|
-
console.log(
|
|
114
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
115
|
-
`@cli ${this.mergeTree.getLongClientId(this.mergeTree.collabWindow.clientId)} ` +
|
|
116
|
-
`gather seg seq ${segment.seq} rseq ${segment.removedSeq} text ${segment.text}`);
|
|
117
|
-
}
|
|
118
112
|
let beginTags = "";
|
|
119
113
|
let endTags = "";
|
|
120
114
|
if (isTextAndMarkerAccumulator(accumText)) {
|
|
@@ -209,20 +203,12 @@ export class MergeTreeTextHelper {
|
|
|
209
203
|
tagsInProgress: [],
|
|
210
204
|
textSegment: new TextSegment(""),
|
|
211
205
|
};
|
|
212
|
-
if (MergeTree.traceGatherText) {
|
|
213
|
-
console.log(`get text on cli ${glc(this.mergeTree, this.mergeTree.collabWindow.clientId)} ` +
|
|
214
|
-
`ref cli ${glc(this.mergeTree, clientId)} refSeq ${refSeq}`);
|
|
215
|
-
}
|
|
216
206
|
this.mergeTree.mapRange({ leaf: this.gatherText }, refSeq, clientId, accum, range.start, range.end);
|
|
217
207
|
return { parallelText: accum.parallelText, parallelMarkers: accum.parallelMarkers };
|
|
218
208
|
}
|
|
219
209
|
getText(refSeq, clientId, placeholder = "", start, end) {
|
|
220
210
|
const range = this.getValidRange(start, end, refSeq, clientId);
|
|
221
211
|
const accum = { textSegment: new TextSegment(""), placeholder };
|
|
222
|
-
if (MergeTree.traceGatherText) {
|
|
223
|
-
console.log(`get text on cli ${glc(this.mergeTree, this.mergeTree.collabWindow.clientId)} ` +
|
|
224
|
-
`ref cli ${glc(this.mergeTree, clientId)} refSeq ${refSeq}`);
|
|
225
|
-
}
|
|
226
212
|
this.mergeTree.mapRange({ leaf: this.gatherText }, refSeq, clientId, accum, range.start, range.end);
|
|
227
213
|
return accum.textSegment.text;
|
|
228
214
|
}
|
package/lib/textSegment.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textSegment.js","sourceRoot":"","sources":["../src/textSegment.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\nimport { IIntegerRange } from \"./base\";\nimport { BaseSegment, glc, ISegment, Marker, MergeTree } from \"./mergeTree\";\nimport { IJSONSegment } from \"./ops\";\nimport { PropertySet } from \"./properties\";\nimport { LocalReferenceCollection } from \"./localReference\";\n\n// Maximum length of text segment to be considered to be merged with other segment.\n// Maximum segment length is at least 2x of it (not taking into account initial segment creation).\n// The bigger it is, the more expensive it is to break segment into sub-segments (on edits)\n// The smaller it is, the more segments we have in snapshots (and in memory) - it's more expensive to load snapshots.\n// Small number also makes ReplayTool produce false positives (\"same\" snapshots have slightly different binary\n// representations). More measurements needs to be done, but it's very likely the right spot is somewhere between\n// 1K-2K mark. That said, we also break segments on newline and there are very few segments that are longer than 256\n// because of it. Must be an even number\nconst TextSegmentGranularity = 256;\n\nexport interface IJSONTextSegment extends IJSONSegment {\n text: string;\n}\n\nexport class TextSegment extends BaseSegment {\n public static readonly type = \"TextSegment\";\n\n public static is(segment: ISegment): segment is TextSegment {\n return segment.type === TextSegment.type;\n }\n\n public static make(text: string, props?: PropertySet) {\n const tseg = new TextSegment(text);\n if (props) {\n tseg.addProperties(props);\n }\n return tseg;\n }\n\n public static fromJSONObject(spec: any) {\n if (typeof spec === \"string\") {\n return new TextSegment(spec);\n } else if (spec && typeof spec === \"object\" && \"text\" in spec) {\n const textSpec = spec as IJSONTextSegment;\n return TextSegment.make(textSpec.text, textSpec.props as PropertySet);\n }\n return undefined;\n }\n\n public readonly type = TextSegment.type;\n\n constructor(public text: string) {\n super();\n this.cachedLength = text.length;\n }\n\n public toJSONObject() {\n // To reduce snapshot/ops size, we serialize a TextSegment as a plain 'string' if it is\n // not annotated.\n return this.properties\n ? { text: this.text, props: this.properties }\n : this.text;\n }\n\n public clone(start = 0, end?: number) {\n const text = this.text.substring(start, end);\n const b = TextSegment.make(text, this.properties);\n this.cloneInto(b);\n return b;\n }\n\n public canAppend(segment: ISegment): boolean {\n return !this.text.endsWith(\"\\n\")\n && TextSegment.is(segment)\n && (this.cachedLength <= TextSegmentGranularity ||\n segment.cachedLength <= TextSegmentGranularity);\n }\n\n public toString() {\n return this.text;\n }\n\n public append(segment: ISegment) {\n if (TextSegment.is(segment)) {\n // Note: Must call 'appendLocalRefs' before modifying this segment's length as\n // 'this.cachedLength' is used to adjust the offsets of the local refs.\n LocalReferenceCollection.append(this, segment);\n\n this.text += segment.text;\n this.cachedLength = this.text.length;\n } else {\n throw new Error(\"can only append text segment\");\n }\n }\n\n // TODO: retain removed text for undo\n // returns true if entire string removed\n public removeRange(start: number, end: number) {\n let remnantString = \"\";\n const len = this.text.length;\n if (start > 0) {\n remnantString += this.text.substring(0, start);\n }\n if (end < len) {\n remnantString += this.text.substring(end);\n }\n this.text = remnantString;\n this.cachedLength = remnantString.length;\n return (remnantString.length === 0);\n }\n\n protected createSplitSegmentAt(pos: number) {\n if (pos > 0) {\n const remainingText = this.text.substring(pos);\n this.text = this.text.substring(0, pos);\n this.cachedLength = this.text.length;\n const leafSegment = new TextSegment(remainingText);\n return leafSegment;\n }\n }\n}\n\ninterface ITextAccumulator {\n textSegment: TextSegment;\n placeholder?: string;\n parallelArrays?: boolean;\n}\n\ninterface ITextAndMarkerAccumulator extends ITextAccumulator {\n parallelArrays: true;\n parallelText: string[];\n parallelMarkers: Marker[];\n parallelMarkerLabel: string;\n tagsInProgress: string[];\n}\n\nfunction isTextAndMarkerAccumulator(accum: ITextAccumulator): accum is ITextAndMarkerAccumulator {\n return accum.parallelArrays === true;\n}\n\ntype ITextAccumulatorType = ITextAccumulator | ITextAndMarkerAccumulator;\nexport class MergeTreeTextHelper {\n constructor(private readonly mergeTree: MergeTree) { }\n\n public getTextAndMarkers(refSeq: number, clientId: number, label: string, start?: number, end?: number) {\n const range = this.getValidRange(start, end, refSeq, clientId);\n const accum: ITextAndMarkerAccumulator = {\n parallelArrays: true,\n parallelMarkerLabel: label,\n parallelMarkers: [],\n parallelText: [],\n tagsInProgress: [],\n textSegment: new TextSegment(\"\"),\n };\n\n if (MergeTree.traceGatherText) {\n console.log(\n `get text on cli ${glc(this.mergeTree, this.mergeTree.collabWindow.clientId)} ` +\n `ref cli ${glc(this.mergeTree, clientId)} refSeq ${refSeq}`);\n }\n this.mergeTree.mapRange<ITextAndMarkerAccumulator>(\n { leaf: this.gatherText },\n refSeq,\n clientId,\n accum,\n range.start,\n range.end);\n\n return { parallelText: accum.parallelText, parallelMarkers: accum.parallelMarkers };\n }\n\n public getText(refSeq: number, clientId: number, placeholder = \"\", start?: number, end?: number) {\n const range = this.getValidRange(start, end, refSeq, clientId);\n\n const accum: ITextAccumulator = { textSegment: new TextSegment(\"\"), placeholder };\n\n if (MergeTree.traceGatherText) {\n console.log(\n `get text on cli ${glc(this.mergeTree, this.mergeTree.collabWindow.clientId)} ` +\n `ref cli ${glc(this.mergeTree, clientId)} refSeq ${refSeq}`);\n }\n this.mergeTree.mapRange<ITextAccumulator>(\n { leaf: this.gatherText },\n refSeq,\n clientId,\n accum,\n range.start,\n range.end);\n return accum.textSegment.text;\n }\n\n private getValidRange(\n start: number | undefined,\n end: number | undefined,\n refSeq: number,\n clientId: number,\n ): IIntegerRange {\n const range: IIntegerRange = {\n end: end ?? this.mergeTree.getLength(refSeq, clientId),\n start: start ?? 0,\n };\n return range;\n }\n\n private readonly gatherText = (segment: ISegment, pos: number, refSeq: number, clientId: number, start: number,\n end: number, accumText: ITextAccumulatorType) => {\n let _start = start;\n if (TextSegment.is(segment)) {\n if (MergeTree.traceGatherText) {\n console.log(\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n `@cli ${this.mergeTree.getLongClientId!(this.mergeTree.collabWindow.clientId)} ` +\n `gather seg seq ${segment.seq} rseq ${segment.removedSeq} text ${segment.text}`);\n }\n let beginTags = \"\";\n let endTags = \"\";\n if (isTextAndMarkerAccumulator(accumText)) {\n // TODO: let clients pass in function to get tag\n const tags = [] as string[];\n const initTags = [] as string[];\n\n if (segment.properties && (segment.properties[\"font-weight\"])) {\n tags.push(\"b\");\n }\n if (segment.properties && (segment.properties[\"text-decoration\"])) {\n tags.push(\"u\");\n }\n const remTags = [] as string[];\n if (tags.length > 0) {\n for (const tag of tags) {\n if (!accumText.tagsInProgress.includes(tag)) {\n beginTags += `<${tag}>`;\n initTags.push(tag);\n }\n }\n for (const accumTag of accumText.tagsInProgress) {\n if (!tags.includes(accumTag)) {\n endTags += `</${accumTag}>`;\n remTags.push(accumTag);\n }\n }\n for (const initTag of initTags.reverse()) {\n accumText.tagsInProgress.push(initTag);\n }\n } else {\n for (const accumTag of accumText.tagsInProgress) {\n endTags += `</${accumTag}>`;\n remTags.push(accumTag);\n }\n }\n for (const remTag of remTags) {\n const remdex = accumText.tagsInProgress.indexOf(remTag);\n if (remdex >= 0) {\n accumText.tagsInProgress.splice(remdex, 1);\n }\n }\n }\n accumText.textSegment.text += endTags;\n accumText.textSegment.text += beginTags;\n if ((_start <= 0) && (end >= segment.text.length)) {\n accumText.textSegment.text += segment.text;\n } else {\n if (_start < 0) {\n _start = 0;\n }\n if (end >= segment.text.length) {\n accumText.textSegment.text += segment.text.substring(_start);\n } else {\n accumText.textSegment.text += segment.text.substring(_start, end);\n }\n }\n } else {\n if (accumText.placeholder && (accumText.placeholder.length > 0)) {\n if (accumText.placeholder === \"*\") {\n const marker = segment as Marker;\n accumText.textSegment.text += `\\n${marker.toString()}`;\n } else {\n for (let i = 0; i < segment.cachedLength; i++) {\n accumText.textSegment.text += accumText.placeholder;\n }\n }\n } else if (isTextAndMarkerAccumulator(accumText)) {\n const marker = segment as Marker;\n if (marker.hasTileLabel(accumText.parallelMarkerLabel)) {\n accumText.parallelMarkers.push(marker);\n accumText.parallelText.push(accumText.textSegment.text);\n accumText.textSegment.text = \"\";\n }\n }\n }\n\n return true;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"textSegment.js","sourceRoot":"","sources":["../src/textSegment.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\nimport { IIntegerRange } from \"./base\";\nimport { BaseSegment, ISegment, Marker, MergeTree } from \"./mergeTree\";\nimport { IJSONSegment } from \"./ops\";\nimport { PropertySet } from \"./properties\";\nimport { LocalReferenceCollection } from \"./localReference\";\n\n// Maximum length of text segment to be considered to be merged with other segment.\n// Maximum segment length is at least 2x of it (not taking into account initial segment creation).\n// The bigger it is, the more expensive it is to break segment into sub-segments (on edits)\n// The smaller it is, the more segments we have in snapshots (and in memory) - it's more expensive to load snapshots.\n// Small number also makes ReplayTool produce false positives (\"same\" snapshots have slightly different binary\n// representations). More measurements needs to be done, but it's very likely the right spot is somewhere between\n// 1K-2K mark. That said, we also break segments on newline and there are very few segments that are longer than 256\n// because of it. Must be an even number\nconst TextSegmentGranularity = 256;\n\nexport interface IJSONTextSegment extends IJSONSegment {\n text: string;\n}\n\nexport class TextSegment extends BaseSegment {\n public static readonly type = \"TextSegment\";\n\n public static is(segment: ISegment): segment is TextSegment {\n return segment.type === TextSegment.type;\n }\n\n public static make(text: string, props?: PropertySet) {\n const tseg = new TextSegment(text);\n if (props) {\n tseg.addProperties(props);\n }\n return tseg;\n }\n\n public static fromJSONObject(spec: any) {\n if (typeof spec === \"string\") {\n return new TextSegment(spec);\n } else if (spec && typeof spec === \"object\" && \"text\" in spec) {\n const textSpec = spec as IJSONTextSegment;\n return TextSegment.make(textSpec.text, textSpec.props as PropertySet);\n }\n return undefined;\n }\n\n public readonly type = TextSegment.type;\n\n constructor(public text: string) {\n super();\n this.cachedLength = text.length;\n }\n\n public toJSONObject() {\n // To reduce snapshot/ops size, we serialize a TextSegment as a plain 'string' if it is\n // not annotated.\n return this.properties\n ? { text: this.text, props: this.properties }\n : this.text;\n }\n\n public clone(start = 0, end?: number) {\n const text = this.text.substring(start, end);\n const b = TextSegment.make(text, this.properties);\n this.cloneInto(b);\n return b;\n }\n\n public canAppend(segment: ISegment): boolean {\n return !this.text.endsWith(\"\\n\")\n && TextSegment.is(segment)\n && (this.cachedLength <= TextSegmentGranularity ||\n segment.cachedLength <= TextSegmentGranularity);\n }\n\n public toString() {\n return this.text;\n }\n\n public append(segment: ISegment) {\n if (TextSegment.is(segment)) {\n // Note: Must call 'appendLocalRefs' before modifying this segment's length as\n // 'this.cachedLength' is used to adjust the offsets of the local refs.\n LocalReferenceCollection.append(this, segment);\n\n this.text += segment.text;\n this.cachedLength = this.text.length;\n } else {\n throw new Error(\"can only append text segment\");\n }\n }\n\n // TODO: retain removed text for undo\n // returns true if entire string removed\n public removeRange(start: number, end: number) {\n let remnantString = \"\";\n const len = this.text.length;\n if (start > 0) {\n remnantString += this.text.substring(0, start);\n }\n if (end < len) {\n remnantString += this.text.substring(end);\n }\n this.text = remnantString;\n this.cachedLength = remnantString.length;\n return (remnantString.length === 0);\n }\n\n protected createSplitSegmentAt(pos: number) {\n if (pos > 0) {\n const remainingText = this.text.substring(pos);\n this.text = this.text.substring(0, pos);\n this.cachedLength = this.text.length;\n const leafSegment = new TextSegment(remainingText);\n return leafSegment;\n }\n }\n}\n\ninterface ITextAccumulator {\n textSegment: TextSegment;\n placeholder?: string;\n parallelArrays?: boolean;\n}\n\ninterface ITextAndMarkerAccumulator extends ITextAccumulator {\n parallelArrays: true;\n parallelText: string[];\n parallelMarkers: Marker[];\n parallelMarkerLabel: string;\n tagsInProgress: string[];\n}\n\nfunction isTextAndMarkerAccumulator(accum: ITextAccumulator): accum is ITextAndMarkerAccumulator {\n return accum.parallelArrays === true;\n}\n\ntype ITextAccumulatorType = ITextAccumulator | ITextAndMarkerAccumulator;\nexport class MergeTreeTextHelper {\n constructor(private readonly mergeTree: MergeTree) { }\n\n public getTextAndMarkers(refSeq: number, clientId: number, label: string, start?: number, end?: number) {\n const range = this.getValidRange(start, end, refSeq, clientId);\n const accum: ITextAndMarkerAccumulator = {\n parallelArrays: true,\n parallelMarkerLabel: label,\n parallelMarkers: [],\n parallelText: [],\n tagsInProgress: [],\n textSegment: new TextSegment(\"\"),\n };\n\n this.mergeTree.mapRange<ITextAndMarkerAccumulator>(\n { leaf: this.gatherText },\n refSeq,\n clientId,\n accum,\n range.start,\n range.end);\n\n return { parallelText: accum.parallelText, parallelMarkers: accum.parallelMarkers };\n }\n\n public getText(refSeq: number, clientId: number, placeholder = \"\", start?: number, end?: number) {\n const range = this.getValidRange(start, end, refSeq, clientId);\n\n const accum: ITextAccumulator = { textSegment: new TextSegment(\"\"), placeholder };\n\n this.mergeTree.mapRange<ITextAccumulator>(\n { leaf: this.gatherText },\n refSeq,\n clientId,\n accum,\n range.start,\n range.end);\n return accum.textSegment.text;\n }\n\n private getValidRange(\n start: number | undefined,\n end: number | undefined,\n refSeq: number,\n clientId: number,\n ): IIntegerRange {\n const range: IIntegerRange = {\n end: end ?? this.mergeTree.getLength(refSeq, clientId),\n start: start ?? 0,\n };\n return range;\n }\n\n private readonly gatherText = (segment: ISegment, pos: number, refSeq: number, clientId: number, start: number,\n end: number, accumText: ITextAccumulatorType) => {\n let _start = start;\n if (TextSegment.is(segment)) {\n\n let beginTags = \"\";\n let endTags = \"\";\n if (isTextAndMarkerAccumulator(accumText)) {\n // TODO: let clients pass in function to get tag\n const tags = [] as string[];\n const initTags = [] as string[];\n\n if (segment.properties && (segment.properties[\"font-weight\"])) {\n tags.push(\"b\");\n }\n if (segment.properties && (segment.properties[\"text-decoration\"])) {\n tags.push(\"u\");\n }\n const remTags = [] as string[];\n if (tags.length > 0) {\n for (const tag of tags) {\n if (!accumText.tagsInProgress.includes(tag)) {\n beginTags += `<${tag}>`;\n initTags.push(tag);\n }\n }\n for (const accumTag of accumText.tagsInProgress) {\n if (!tags.includes(accumTag)) {\n endTags += `</${accumTag}>`;\n remTags.push(accumTag);\n }\n }\n for (const initTag of initTags.reverse()) {\n accumText.tagsInProgress.push(initTag);\n }\n } else {\n for (const accumTag of accumText.tagsInProgress) {\n endTags += `</${accumTag}>`;\n remTags.push(accumTag);\n }\n }\n for (const remTag of remTags) {\n const remdex = accumText.tagsInProgress.indexOf(remTag);\n if (remdex >= 0) {\n accumText.tagsInProgress.splice(remdex, 1);\n }\n }\n }\n accumText.textSegment.text += endTags;\n accumText.textSegment.text += beginTags;\n if ((_start <= 0) && (end >= segment.text.length)) {\n accumText.textSegment.text += segment.text;\n } else {\n if (_start < 0) {\n _start = 0;\n }\n if (end >= segment.text.length) {\n accumText.textSegment.text += segment.text.substring(_start);\n } else {\n accumText.textSegment.text += segment.text.substring(_start, end);\n }\n }\n } else {\n if (accumText.placeholder && (accumText.placeholder.length > 0)) {\n if (accumText.placeholder === \"*\") {\n const marker = segment as Marker;\n accumText.textSegment.text += `\\n${marker.toString()}`;\n } else {\n for (let i = 0; i < segment.cachedLength; i++) {\n accumText.textSegment.text += accumText.placeholder;\n }\n }\n } else if (isTextAndMarkerAccumulator(accumText)) {\n const marker = segment as Marker;\n if (marker.hasTileLabel(accumText.parallelMarkerLabel)) {\n accumText.parallelMarkers.push(marker);\n accumText.parallelText.push(accumText.textSegment.text);\n accumText.textSegment.text = \"\";\n }\n }\n }\n\n return true;\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/merge-tree",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.58.0-55561",
|
|
4
4
|
"description": "Merge tree",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": "https://github.com/microsoft/FluidFramework",
|
|
@@ -56,20 +56,20 @@
|
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
58
58
|
"@fluidframework/common-utils": "^0.32.1",
|
|
59
|
-
"@fluidframework/container-definitions": "^0.46.0",
|
|
59
|
+
"@fluidframework/container-definitions": "^0.46.0-0",
|
|
60
60
|
"@fluidframework/core-interfaces": "^0.42.0",
|
|
61
|
-
"@fluidframework/datastore-definitions": "
|
|
61
|
+
"@fluidframework/datastore-definitions": "0.58.0-55561",
|
|
62
62
|
"@fluidframework/protocol-definitions": "^0.1026.0",
|
|
63
|
-
"@fluidframework/runtime-definitions": "
|
|
64
|
-
"@fluidframework/runtime-utils": "
|
|
65
|
-
"@fluidframework/shared-object-base": "
|
|
66
|
-
"@fluidframework/telemetry-utils": "
|
|
63
|
+
"@fluidframework/runtime-definitions": "0.58.0-55561",
|
|
64
|
+
"@fluidframework/runtime-utils": "0.58.0-55561",
|
|
65
|
+
"@fluidframework/shared-object-base": "0.58.0-55561",
|
|
66
|
+
"@fluidframework/telemetry-utils": "0.58.0-55561"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@fluidframework/build-common": "^0.23.0",
|
|
70
|
-
"@fluidframework/eslint-config-fluid": "^0.26.0",
|
|
71
|
-
"@fluidframework/mocha-test-setup": "
|
|
72
|
-
"@fluidframework/test-runtime-utils": "
|
|
70
|
+
"@fluidframework/eslint-config-fluid": "^0.26.0-0",
|
|
71
|
+
"@fluidframework/mocha-test-setup": "0.58.0-55561",
|
|
72
|
+
"@fluidframework/test-runtime-utils": "0.58.0-55561",
|
|
73
73
|
"@microsoft/api-extractor": "^7.16.1",
|
|
74
74
|
"@rushstack/eslint-config": "^2.5.1",
|
|
75
75
|
"@types/diff": "^3.5.1",
|
package/src/base.ts
CHANGED
|
@@ -26,7 +26,6 @@ export interface Dictionary<TKey, TData> {
|
|
|
26
26
|
put(key: TKey, data: TData, conflict?: ConflictAction<TKey, TData>): void;
|
|
27
27
|
remove(key: TKey): void;
|
|
28
28
|
map<TAccum>(action: PropertyAction<TKey, TData>, accum?: TAccum): void;
|
|
29
|
-
diag(): void;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
export interface SortedDictionary<TKey, TData> extends Dictionary<TKey, TData> {
|
package/src/client.ts
CHANGED
|
@@ -20,7 +20,6 @@ import { LocalReference } from "./localReference";
|
|
|
20
20
|
import {
|
|
21
21
|
CollaborationWindow,
|
|
22
22
|
compareStrings,
|
|
23
|
-
elapsedMicroseconds,
|
|
24
23
|
IConsensusInfo,
|
|
25
24
|
ISegment,
|
|
26
25
|
ISegmentAction,
|
|
@@ -61,9 +60,11 @@ import {
|
|
|
61
60
|
ReferencePosition,
|
|
62
61
|
} from "./index";
|
|
63
62
|
|
|
63
|
+
function elapsedMicroseconds(trace: Trace) {
|
|
64
|
+
return trace.trace().duration * 1000;
|
|
65
|
+
}
|
|
66
|
+
|
|
64
67
|
export class Client {
|
|
65
|
-
public verboseOps = false;
|
|
66
|
-
public noVerboseRemoteAnnotate = false;
|
|
67
68
|
public measureOps = false;
|
|
68
69
|
public accumTime = 0;
|
|
69
70
|
public localTime = 0;
|
|
@@ -478,13 +479,6 @@ export class Client {
|
|
|
478
479
|
this.accumWindow += (this.getCurrentSeq() - this.getCollabWindow().minSeq);
|
|
479
480
|
}
|
|
480
481
|
}
|
|
481
|
-
if (this.verboseOps && (!opArgs.sequencedMessage || !this.noVerboseRemoteAnnotate)) {
|
|
482
|
-
console.log(
|
|
483
|
-
`@cli ${this.getLongClientId(this.getCollabWindow().clientId)} ` +
|
|
484
|
-
`seq ${clientArgs.sequenceNumber} ${opArgs.op.type} local ${!opArgs.sequencedMessage} ` +
|
|
485
|
-
`start ${range.start} end ${range.end} refseq ${clientArgs.referenceSequenceNumber} ` +
|
|
486
|
-
`cli ${clientArgs.clientId}`);
|
|
487
|
-
}
|
|
488
482
|
}
|
|
489
483
|
|
|
490
484
|
/**
|
|
@@ -552,7 +546,6 @@ export class Client {
|
|
|
552
546
|
}
|
|
553
547
|
}
|
|
554
548
|
|
|
555
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
556
549
|
return { start, end } as IIntegerRange;
|
|
557
550
|
}
|
|
558
551
|
|
|
@@ -587,7 +580,7 @@ export class Client {
|
|
|
587
580
|
trace = Trace.start();
|
|
588
581
|
}
|
|
589
582
|
|
|
590
|
-
this.mergeTree.ackPendingSegment(deltaOpArgs
|
|
583
|
+
this.mergeTree.ackPendingSegment(deltaOpArgs);
|
|
591
584
|
if (deltaOpArgs.op.type === MergeTreeDeltaType.ANNOTATE) {
|
|
592
585
|
if (deltaOpArgs.op.combiningOp && (deltaOpArgs.op.combiningOp.name === "consensus")) {
|
|
593
586
|
this.updateConsensusProperty(deltaOpArgs.op, deltaOpArgs.sequencedMessage!);
|
|
@@ -599,11 +592,6 @@ export class Client {
|
|
|
599
592
|
this.accumOps++;
|
|
600
593
|
this.accumWindow += (this.getCurrentSeq() - this.getCollabWindow().minSeq);
|
|
601
594
|
}
|
|
602
|
-
|
|
603
|
-
if (this.verboseOps) {
|
|
604
|
-
console.log(`@cli ${this.getLongClientId(this.getCollabWindow().clientId)} ` +
|
|
605
|
-
`ack seq # ${deltaOpArgs.sequencedMessage?.sequenceNumber}`);
|
|
606
|
-
}
|
|
607
595
|
};
|
|
608
596
|
|
|
609
597
|
if (opArgs.op.type === MergeTreeDeltaType.GROUP) {
|
|
@@ -985,12 +973,6 @@ export class Client {
|
|
|
985
973
|
}
|
|
986
974
|
|
|
987
975
|
getPropertiesAtPosition(pos: number) {
|
|
988
|
-
const segWindow = this.getCollabWindow();
|
|
989
|
-
if (this.verboseOps) {
|
|
990
|
-
// eslint-disable-next-line max-len
|
|
991
|
-
console.log(`getPropertiesAtPosition cli ${this.getLongClientId(segWindow.clientId)} ref seq ${segWindow.currentSeq}`);
|
|
992
|
-
}
|
|
993
|
-
|
|
994
976
|
let propertiesAtPosition: PropertySet | undefined;
|
|
995
977
|
const segoff = this.getContainingSegment(pos);
|
|
996
978
|
const seg = segoff.segment;
|
|
@@ -1000,12 +982,6 @@ export class Client {
|
|
|
1000
982
|
return propertiesAtPosition;
|
|
1001
983
|
}
|
|
1002
984
|
getRangeExtentsOfPosition(pos: number) {
|
|
1003
|
-
const segWindow = this.getCollabWindow();
|
|
1004
|
-
if (this.verboseOps) {
|
|
1005
|
-
// eslint-disable-next-line max-len
|
|
1006
|
-
console.log(`getRangeExtentsOfPosition cli ${this.getLongClientId(segWindow.clientId)} ref seq ${segWindow.currentSeq}`);
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
985
|
let posStart: number | undefined;
|
|
1010
986
|
let posAfterEnd: number | undefined;
|
|
1011
987
|
|
package/src/collections.ts
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/* eslint-disable @typescript-eslint/consistent-type-assertions
|
|
7
|
-
/* eslint-disable no-bitwise */
|
|
6
|
+
/* eslint-disable @typescript-eslint/consistent-type-assertions */
|
|
8
7
|
|
|
9
8
|
/* Remove once strictNullCheck is enabled */
|
|
10
9
|
|
|
@@ -61,7 +60,6 @@ export class List<T> {
|
|
|
61
60
|
public next: List<T>;
|
|
62
61
|
public prev: List<T>;
|
|
63
62
|
|
|
64
|
-
// eslint-disable-next-line @typescript-eslint/prefer-readonly
|
|
65
63
|
constructor(public isHead: boolean, private data: T | undefined) {
|
|
66
64
|
this.prev = this;
|
|
67
65
|
this.next = this;
|
|
@@ -262,7 +260,7 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
|
|
|
262
260
|
}
|
|
263
261
|
|
|
264
262
|
private isRed(node: RBNode<TKey, TData> | undefined) {
|
|
265
|
-
return !!node && (node.color
|
|
263
|
+
return !!node && (node.color === RBColor.RED);
|
|
266
264
|
}
|
|
267
265
|
|
|
268
266
|
private nodeSize(node: RBNode<TKey, TData> | undefined) {
|
|
@@ -508,14 +506,14 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
|
|
|
508
506
|
if (this.isRed(_node.left)) {
|
|
509
507
|
_node = this.rotateRight(_node);
|
|
510
508
|
}
|
|
511
|
-
if ((this.compareKeys(key, _node.key)
|
|
509
|
+
if ((this.compareKeys(key, _node.key) === 0) && (!_node.right)) {
|
|
512
510
|
return undefined;
|
|
513
511
|
}
|
|
514
512
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
515
513
|
if ((!this.isRed(_node.right)) && (!this.isRed(_node.right!.left))) {
|
|
516
514
|
_node = this.moveRedRight(_node);
|
|
517
515
|
}
|
|
518
|
-
if (this.compareKeys(key, _node.key)
|
|
516
|
+
if (this.compareKeys(key, _node.key) === 0) {
|
|
519
517
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
520
518
|
const subtreeMin = this.nodeMin(_node.right!);
|
|
521
519
|
_node.key = subtreeMin.key;
|
|
@@ -530,17 +528,6 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
|
|
|
530
528
|
}
|
|
531
529
|
return this.balance(_node);
|
|
532
530
|
}
|
|
533
|
-
private height() {
|
|
534
|
-
return this.nodeHeight(this.root);
|
|
535
|
-
}
|
|
536
|
-
private nodeHeight(node: RBNode<TKey, TData> | undefined): number {
|
|
537
|
-
if (node === undefined) {
|
|
538
|
-
return -1;
|
|
539
|
-
}
|
|
540
|
-
else {
|
|
541
|
-
return 1 + Math.max(this.nodeHeight(node.left), this.nodeHeight(node.right));
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
531
|
|
|
545
532
|
public floor(key: TKey) {
|
|
546
533
|
if (!this.isEmpty()) {
|
|
@@ -551,7 +538,7 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
|
|
|
551
538
|
private nodeFloor(node: RBNode<TKey, TData> | undefined, key: TKey): RBNode<TKey, TData> | undefined {
|
|
552
539
|
if (node) {
|
|
553
540
|
const cmp = this.compareKeys(key, node.key);
|
|
554
|
-
if (cmp
|
|
541
|
+
if (cmp === 0) {
|
|
555
542
|
return node;
|
|
556
543
|
}
|
|
557
544
|
else if (cmp < 0) {
|
|
@@ -578,7 +565,7 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
|
|
|
578
565
|
private nodeCeil(node: RBNode<TKey, TData> | undefined, key: TKey): RBNode<TKey, TData> | undefined {
|
|
579
566
|
if (node) {
|
|
580
567
|
const cmp = this.compareKeys(key, node.key);
|
|
581
|
-
if (cmp
|
|
568
|
+
if (cmp === 0) {
|
|
582
569
|
return node;
|
|
583
570
|
}
|
|
584
571
|
else if (cmp > 0) {
|
|
@@ -659,7 +646,7 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
|
|
|
659
646
|
}
|
|
660
647
|
|
|
661
648
|
private oppositeColor(c: RBColor) {
|
|
662
|
-
return (c
|
|
649
|
+
return (c === RBColor.BLACK) ? RBColor.RED : RBColor.BLACK;
|
|
663
650
|
}
|
|
664
651
|
|
|
665
652
|
private flipColors(node: RBNode<TKey, TData>) {
|
|
@@ -837,9 +824,6 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
|
|
|
837
824
|
}
|
|
838
825
|
return go;
|
|
839
826
|
}
|
|
840
|
-
public diag() {
|
|
841
|
-
console.log(`Height is ${this.height()}`);
|
|
842
|
-
}
|
|
843
827
|
}
|
|
844
828
|
|
|
845
829
|
export interface AugmentedIntervalNode {
|
|
@@ -1013,7 +997,6 @@ export class TST<T> {
|
|
|
1013
997
|
this.n++;
|
|
1014
998
|
}
|
|
1015
999
|
this.root = this.nodePut(this.root, key, val, 0);
|
|
1016
|
-
// console.log(`put ${key}`);
|
|
1017
1000
|
}
|
|
1018
1001
|
|
|
1019
1002
|
private nodePut(x: TSTNode<T> | undefined, key: string, val: T, d: number) {
|
package/src/index.ts
CHANGED