@fluidframework/sequence 2.32.0 → 2.33.0
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/CHANGELOG.md +16 -0
- package/api-report/sequence.legacy.alpha.api.md +39 -39
- package/dist/intervalCollection.d.ts +14 -9
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +137 -77
- package/dist/intervalCollection.js.map +1 -1
- package/dist/intervalCollectionMap.d.ts +5 -4
- package/dist/intervalCollectionMap.d.ts.map +1 -1
- package/dist/intervalCollectionMap.js +25 -50
- package/dist/intervalCollectionMap.js.map +1 -1
- package/dist/intervalCollectionMapInterfaces.d.ts +22 -15
- package/dist/intervalCollectionMapInterfaces.d.ts.map +1 -1
- package/dist/intervalCollectionMapInterfaces.js.map +1 -1
- package/dist/intervalIndex/intervalIndex.d.ts +1 -1
- package/dist/intervalIndex/intervalIndex.js.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/dist/intervals/sequenceInterval.d.ts +3 -3
- package/dist/intervals/sequenceInterval.d.ts.map +1 -1
- package/dist/intervals/sequenceInterval.js +10 -9
- package/dist/intervals/sequenceInterval.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/sequence.d.ts +4 -0
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +10 -0
- package/dist/sequence.js.map +1 -1
- package/dist/sharedIntervalCollection.d.ts +1 -1
- package/dist/sharedIntervalCollection.js.map +1 -1
- package/dist/sharedString.d.ts +0 -4
- package/dist/sharedString.d.ts.map +1 -1
- package/dist/sharedString.js +0 -11
- package/dist/sharedString.js.map +1 -1
- package/lib/intervalCollection.d.ts +14 -9
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +138 -78
- package/lib/intervalCollection.js.map +1 -1
- package/lib/intervalCollectionMap.d.ts +5 -4
- package/lib/intervalCollectionMap.d.ts.map +1 -1
- package/lib/intervalCollectionMap.js +26 -51
- package/lib/intervalCollectionMap.js.map +1 -1
- package/lib/intervalCollectionMapInterfaces.d.ts +22 -15
- package/lib/intervalCollectionMapInterfaces.d.ts.map +1 -1
- package/lib/intervalCollectionMapInterfaces.js.map +1 -1
- package/lib/intervalIndex/intervalIndex.d.ts +1 -1
- package/lib/intervalIndex/intervalIndex.js.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/lib/intervals/sequenceInterval.d.ts +3 -3
- package/lib/intervals/sequenceInterval.d.ts.map +1 -1
- package/lib/intervals/sequenceInterval.js +10 -9
- package/lib/intervals/sequenceInterval.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/sequence.d.ts +4 -0
- package/lib/sequence.d.ts.map +1 -1
- package/lib/sequence.js +10 -0
- package/lib/sequence.js.map +1 -1
- package/lib/sharedIntervalCollection.d.ts +1 -1
- package/lib/sharedIntervalCollection.js.map +1 -1
- package/lib/sharedString.d.ts +0 -4
- package/lib/sharedString.d.ts.map +1 -1
- package/lib/sharedString.js +0 -11
- package/lib/sharedString.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/package.json +18 -20
- package/src/intervalCollection.ts +188 -96
- package/src/intervalCollectionMap.ts +31 -60
- package/src/intervalCollectionMapInterfaces.ts +34 -29
- package/src/intervalIndex/intervalIndex.ts +1 -1
- package/src/intervalIndex/overlappingIntervalsIndex.ts +1 -1
- package/src/intervals/sequenceInterval.ts +14 -2
- package/src/packageVersion.ts +1 -1
- package/src/sequence.ts +15 -0
- package/src/sharedIntervalCollection.ts +1 -1
- package/src/sharedString.ts +0 -11
package/lib/sharedString.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedString.js","sourceRoot":"","sources":["../src/sharedString.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 {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport {\n\t// eslint-disable-next-line import/no-deprecated\n\tIMergeTreeTextHelper,\n\tIRelativePosition,\n\tISegment,\n\tISegmentAction,\n\tMarker,\n\tPropertySet,\n\tReferenceType,\n\tTextSegment,\n\trefHasTileLabel,\n} from \"@fluidframework/merge-tree/internal\";\n\n// eslint-disable-next-line import/no-deprecated\nimport { SharedSegmentSequence, type ISharedSegmentSequence } from \"./sequence.js\";\nimport { SharedStringFactory } from \"./sequenceFactory.js\";\n\n/**\n * Fluid object interface describing access methods on a SharedString\n * @legacy\n * @alpha\n */\nexport interface ISharedString extends ISharedSegmentSequence<SharedStringSegment> {\n\t/**\n\t * Inserts the text at the position.\n\t * @param pos - The position to insert the text at\n\t * @param text - The text to insert\n\t * @param props - The properties of the text\n\t */\n\tinsertText(pos: number, text: string, props?: PropertySet): void;\n\n\t/**\n\t * Inserts a marker at the position.\n\t * @param pos - The position to insert the marker at\n\t * @param refType - The reference type of the marker\n\t * @param props - The properties of the marker\n\t */\n\tinsertMarker(pos: number, refType: ReferenceType, props?: PropertySet): void;\n\n\t/**\n\t * Inserts a marker at a relative position.\n\t * @param relativePos1 - The relative position to insert the marker at\n\t * @param refType - The reference type of the marker\n\t * @param props - The properties of the marker\n\t */\n\tinsertMarkerRelative(\n\t\trelativePos1: IRelativePosition,\n\t\trefType: ReferenceType,\n\t\tprops?: PropertySet,\n\t): void;\n\n\t/**\n\t * Inserts the text at the position.\n\t * @param relativePos1 - The relative position to insert the text at\n\t * @param text - The text to insert\n\t * @param props - The properties of text\n\t */\n\tinsertTextRelative(relativePos1: IRelativePosition, text: string, props?: PropertySet): void;\n\n\t/**\n\t * Replaces a range with the provided text.\n\t * @param start - The inclusive start of the range to replace\n\t * @param end - The exclusive end of the range to replace\n\t * @param text - The text to replace the range with\n\t * @param props - Optional. The properties of the replacement text\n\t */\n\treplaceText(start: number, end: number, text: string, props?: PropertySet): void;\n\n\t/**\n\t * Removes the text in the given range.\n\t * @param start - The inclusive start of the range to remove\n\t * @param end - The exclusive end of the range to replace\n\t * @returns the message sent.\n\t */\n\tremoveText(start: number, end: number): void;\n\n\t/**\n\t * Annotates the marker with the provided properties.\n\t * @param marker - The marker to annotate\n\t * @param props - The properties to annotate the marker with\n\t */\n\tannotateMarker(marker: Marker, props: PropertySet): void;\n\n\t/**\n\t * Searches a string for the nearest marker in either direction to a given start position.\n\t * The search will include the start position, so markers at the start position are valid\n\t * results of the search.\n\t * @param startPos - Position at which to start the search\n\t * @param markerLabel - Label of the marker to search for\n\t * @param forwards - Whether the desired marker comes before (false) or after (true) `startPos`. Default true.\n\t */\n\tsearchForMarker(\n\t\tstartPos: number,\n\t\tmarkerLabel: string,\n\t\tforwards?: boolean,\n\t): Marker | undefined;\n\n\t/**\n\t * Retrieve text from the SharedString in string format.\n\t * @param start - The starting index of the text to retrieve, or 0 if omitted.\n\t * @param end - The ending index of the text to retrieve, or the end of the string if omitted\n\t * @returns The requested text content as a string.\n\t */\n\tgetText(start?: number, end?: number): string;\n\n\t/**\n\t * Adds spaces for markers and handles, so that position calculations account for them.\n\t */\n\tgetTextWithPlaceholders(start?: number, end?: number): string;\n\n\tgetTextRangeWithMarkers(start: number, end: number): string;\n\n\t/**\n\t * Looks up and returns a `Marker` using its id. Returns `undefined` if there is no marker with the provided\n\t * id in this `SharedString`.\n\t */\n\tgetMarkerFromId(id: string): ISegment | undefined;\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport type SharedStringSegment = TextSegment | Marker;\n\n/**\n * The Shared String is a specialized data structure for handling collaborative\n * text. It is based on a more general Sequence data structure but has\n * additional features that make working with text easier.\n *\n * In addition to text, a Shared String can also contain markers. Markers can be\n * used to store metadata at positions within the text, like the details of an\n * image or Fluid object that should be rendered with the text.\n * @internal\n */\nexport class SharedStringClass\n\t// eslint-disable-next-line import/no-deprecated\n\textends SharedSegmentSequence<SharedStringSegment>\n\timplements ISharedString\n{\n\tpublic get ISharedString(): ISharedString {\n\t\treturn this;\n\t}\n\n\t// eslint-disable-next-line import/no-deprecated\n\tprivate readonly mergeTreeTextHelper: IMergeTreeTextHelper;\n\n\tconstructor(\n\t\tdocument: IFluidDataStoreRuntime,\n\t\tpublic id: string,\n\t\tattributes: IChannelAttributes,\n\t) {\n\t\tsuper(document, id, attributes, SharedStringFactory.segmentFromSpec as any);\n\t\tthis.mergeTreeTextHelper = this.client.createTextHelper();\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.insertMarkerRelative}\n\t */\n\tpublic insertMarkerRelative(\n\t\trelativePos1: IRelativePosition,\n\t\trefType: ReferenceType,\n\t\tprops?: PropertySet,\n\t): void {\n\t\tconst pos = this.posFromRelativePos(relativePos1);\n\t\tthis.guardReentrancy(() =>\n\t\t\tthis.client.insertSegmentLocal(pos, Marker.make(refType, props)),\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.insertMarker}\n\t */\n\tpublic insertMarker(pos: number, refType: ReferenceType, props?: PropertySet): void {\n\t\tthis.guardReentrancy(() =>\n\t\t\tthis.client.insertSegmentLocal(pos, Marker.make(refType, props)),\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.insertTextRelative}\n\t */\n\tpublic insertTextRelative(\n\t\trelativePos1: IRelativePosition,\n\t\ttext: string,\n\t\tprops?: PropertySet,\n\t): void {\n\t\tconst pos = this.posFromRelativePos(relativePos1);\n\t\tthis.guardReentrancy(() =>\n\t\t\tthis.client.insertSegmentLocal(pos, TextSegment.make(text, props)),\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.insertText}\n\t */\n\tpublic insertText(pos: number, text: string, props?: PropertySet): void {\n\t\tthis.guardReentrancy(() =>\n\t\t\tthis.client.insertSegmentLocal(pos, TextSegment.make(text, props)),\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.replaceText}\n\t */\n\tpublic replaceText(start: number, end: number, text: string, props?: PropertySet): void {\n\t\tthis.replaceRange(start, end, TextSegment.make(text, props));\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.removeText}\n\t */\n\tpublic removeText(start: number, end: number): void {\n\t\tthis.removeRange(start, end);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.annotateMarker}\n\t */\n\tpublic annotateMarker(marker: Marker, props: PropertySet): void {\n\t\tthis.guardReentrancy(() => this.client.annotateMarker(marker, props));\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.searchForMarker}\n\t */\n\tpublic searchForMarker(\n\t\tstartPos: number,\n\t\tmarkerLabel: string,\n\t\tforwards = true,\n\t): Marker | undefined {\n\t\treturn this.client.searchForMarker(startPos, markerLabel, forwards);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.getText}\n\t */\n\tpublic getText(start?: number, end?: number) {\n\t\tconst collabWindow = this.client.getCollabWindow();\n\t\treturn this.mergeTreeTextHelper.getText(collabWindow.localPerspective, \"\", start, end);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.getTextWithPlaceholders}\n\t */\n\tpublic getTextWithPlaceholders(start?: number, end?: number) {\n\t\tconst collabWindow = this.client.getCollabWindow();\n\t\treturn this.mergeTreeTextHelper.getText(collabWindow.localPerspective, \" \", start, end);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.getTextRangeWithMarkers}\n\t */\n\tpublic getTextRangeWithMarkers(start: number, end: number) {\n\t\tconst collabWindow = this.client.getCollabWindow();\n\t\treturn this.mergeTreeTextHelper.getText(collabWindow.localPerspective, \"*\", start, end);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.getMarkerFromId}\n\t */\n\tpublic getMarkerFromId(id: string): ISegment | undefined {\n\t\treturn this.client.getMarkerFromId(id);\n\t}\n\n\t/**\n\t * Revert an op\n\t */\n\tprotected rollback(content: any, localOpMetadata: unknown): void {\n\t\tif (this.client.rollback !== undefined) {\n\t\t\tthis.client.rollback(content, localOpMetadata);\n\t\t} else {\n\t\t\tsuper.rollback(content, localOpMetadata);\n\t\t}\n\t}\n}\n\ninterface ITextAndMarkerAccumulator {\n\tparallelText: string[];\n\tparallelMarkers: Marker[];\n\tparallelMarkerLabel: string;\n\tplaceholder?: string;\n\ttagsInProgress: string[];\n\ttextSegment: TextSegment;\n}\n\n/**\n * Splits the text into regions ending with markers with the given `label`.\n * @param sharedString - String to retrieve text and markers from\n * @param label - label to split on\n * @returns Two parallel lists of text and markers, split by markers with the provided `label`.\n * For example:\n * ```typescript\n * // Say sharedstring has contents \"hello<paragraph marker 1>world<paragraph marker 2>missing\".\n * const { parallelText, parallelMarkers } = getTextAndMarkers(sharedString, \"paragraph\");\n * // parallelText === [\"hello\", \"world\"]\n * // parallelMarkers === [<paragraph marker 1 object>, <paragraph marker 2 object>]\n * // Note parallelText does not include \"missing\".\n * ```\n * @internal\n */\nexport function getTextAndMarkers(\n\tsharedString: ISharedString,\n\tlabel: string,\n\tstart?: number,\n\tend?: number,\n): {\n\tparallelText: string[];\n\tparallelMarkers: Marker[];\n} {\n\tconst accum: ITextAndMarkerAccumulator = {\n\t\tparallelMarkerLabel: label,\n\t\tparallelMarkers: [],\n\t\tparallelText: [],\n\t\ttagsInProgress: [],\n\t\ttextSegment: new TextSegment(\"\"),\n\t};\n\n\tsharedString.walkSegments(gatherTextAndMarkers, start, end, accum);\n\treturn { parallelText: accum.parallelText, parallelMarkers: accum.parallelMarkers };\n}\n\nconst gatherTextAndMarkers: ISegmentAction<ITextAndMarkerAccumulator> = (\n\tsegment: ISegment,\n\tpos: number,\n\trefSeq: number,\n\tclientId: number,\n\tstart: number,\n\tend: number,\n\taccumText: ITextAndMarkerAccumulator,\n) => {\n\tconst { placeholder, tagsInProgress, textSegment } = accumText;\n\tif (TextSegment.is(segment)) {\n\t\tlet beginTags = \"\";\n\t\tlet endTags = \"\";\n\t\t// TODO: let clients pass in function to get tag\n\t\tconst tags = [] as string[];\n\t\tconst initTags = [] as string[];\n\n\t\tif (segment.properties?.[\"font-weight\"]) {\n\t\t\ttags.push(\"b\");\n\t\t}\n\t\tif (segment.properties?.[\"text-decoration\"]) {\n\t\t\ttags.push(\"u\");\n\t\t}\n\t\tconst remTags = [] as string[];\n\t\tif (tags.length > 0) {\n\t\t\tfor (const tag of tags) {\n\t\t\t\tif (!tagsInProgress.includes(tag)) {\n\t\t\t\t\tbeginTags += `<${tag}>`;\n\t\t\t\t\tinitTags.push(tag);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const accumTag of tagsInProgress) {\n\t\t\t\tif (!tags.includes(accumTag)) {\n\t\t\t\t\tendTags += `</${accumTag}>`;\n\t\t\t\t\tremTags.push(accumTag);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const initTag of initTags.reverse()) {\n\t\t\t\ttagsInProgress.push(initTag);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const accumTag of tagsInProgress) {\n\t\t\t\tendTags += `</${accumTag}>`;\n\t\t\t\tremTags.push(accumTag);\n\t\t\t}\n\t\t}\n\t\tfor (const remTag of remTags) {\n\t\t\tconst remdex = tagsInProgress.indexOf(remTag);\n\t\t\tif (remdex >= 0) {\n\t\t\t\ttagsInProgress.splice(remdex, 1);\n\t\t\t}\n\t\t}\n\t\ttextSegment.text += endTags;\n\t\ttextSegment.text += beginTags;\n\t\tif (start <= 0 && end >= segment.text.length) {\n\t\t\ttextSegment.text += segment.text;\n\t\t} else {\n\t\t\tconst seglen = segment.text.length;\n\t\t\tconst _start = start < 0 ? 0 : start;\n\t\t\tconst _end = end >= seglen ? undefined : end;\n\t\t\ttextSegment.text += segment.text.substring(_start, _end);\n\t\t}\n\t} else {\n\t\tif (placeholder && placeholder.length > 0) {\n\t\t\tconst placeholderText =\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\t\t\tplaceholder === \"*\" ? `\\n${segment}` : placeholder.repeat(segment.cachedLength);\n\t\t\ttextSegment.text += placeholderText;\n\t\t} else {\n\t\t\tconst marker = segment as Marker;\n\t\t\tif (refHasTileLabel(marker, accumText.parallelMarkerLabel)) {\n\t\t\t\taccumText.parallelMarkers.push(marker);\n\t\t\t\taccumText.parallelText.push(textSegment.text);\n\t\t\t\ttextSegment.text = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"sharedString.js","sourceRoot":"","sources":["../src/sharedString.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 {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport {\n\t// eslint-disable-next-line import/no-deprecated\n\tIMergeTreeTextHelper,\n\tIRelativePosition,\n\tISegment,\n\tISegmentAction,\n\tMarker,\n\tPropertySet,\n\tReferenceType,\n\tTextSegment,\n\trefHasTileLabel,\n} from \"@fluidframework/merge-tree/internal\";\n\n// eslint-disable-next-line import/no-deprecated\nimport { SharedSegmentSequence, type ISharedSegmentSequence } from \"./sequence.js\";\nimport { SharedStringFactory } from \"./sequenceFactory.js\";\n\n/**\n * Fluid object interface describing access methods on a SharedString\n * @legacy\n * @alpha\n */\nexport interface ISharedString extends ISharedSegmentSequence<SharedStringSegment> {\n\t/**\n\t * Inserts the text at the position.\n\t * @param pos - The position to insert the text at\n\t * @param text - The text to insert\n\t * @param props - The properties of the text\n\t */\n\tinsertText(pos: number, text: string, props?: PropertySet): void;\n\n\t/**\n\t * Inserts a marker at the position.\n\t * @param pos - The position to insert the marker at\n\t * @param refType - The reference type of the marker\n\t * @param props - The properties of the marker\n\t */\n\tinsertMarker(pos: number, refType: ReferenceType, props?: PropertySet): void;\n\n\t/**\n\t * Inserts a marker at a relative position.\n\t * @param relativePos1 - The relative position to insert the marker at\n\t * @param refType - The reference type of the marker\n\t * @param props - The properties of the marker\n\t */\n\tinsertMarkerRelative(\n\t\trelativePos1: IRelativePosition,\n\t\trefType: ReferenceType,\n\t\tprops?: PropertySet,\n\t): void;\n\n\t/**\n\t * Inserts the text at the position.\n\t * @param relativePos1 - The relative position to insert the text at\n\t * @param text - The text to insert\n\t * @param props - The properties of text\n\t */\n\tinsertTextRelative(relativePos1: IRelativePosition, text: string, props?: PropertySet): void;\n\n\t/**\n\t * Replaces a range with the provided text.\n\t * @param start - The inclusive start of the range to replace\n\t * @param end - The exclusive end of the range to replace\n\t * @param text - The text to replace the range with\n\t * @param props - Optional. The properties of the replacement text\n\t */\n\treplaceText(start: number, end: number, text: string, props?: PropertySet): void;\n\n\t/**\n\t * Removes the text in the given range.\n\t * @param start - The inclusive start of the range to remove\n\t * @param end - The exclusive end of the range to replace\n\t * @returns the message sent.\n\t */\n\tremoveText(start: number, end: number): void;\n\n\t/**\n\t * Annotates the marker with the provided properties.\n\t * @param marker - The marker to annotate\n\t * @param props - The properties to annotate the marker with\n\t */\n\tannotateMarker(marker: Marker, props: PropertySet): void;\n\n\t/**\n\t * Searches a string for the nearest marker in either direction to a given start position.\n\t * The search will include the start position, so markers at the start position are valid\n\t * results of the search.\n\t * @param startPos - Position at which to start the search\n\t * @param markerLabel - Label of the marker to search for\n\t * @param forwards - Whether the desired marker comes before (false) or after (true) `startPos`. Default true.\n\t */\n\tsearchForMarker(\n\t\tstartPos: number,\n\t\tmarkerLabel: string,\n\t\tforwards?: boolean,\n\t): Marker | undefined;\n\n\t/**\n\t * Retrieve text from the SharedString in string format.\n\t * @param start - The starting index of the text to retrieve, or 0 if omitted.\n\t * @param end - The ending index of the text to retrieve, or the end of the string if omitted\n\t * @returns The requested text content as a string.\n\t */\n\tgetText(start?: number, end?: number): string;\n\n\t/**\n\t * Adds spaces for markers and handles, so that position calculations account for them.\n\t */\n\tgetTextWithPlaceholders(start?: number, end?: number): string;\n\n\tgetTextRangeWithMarkers(start: number, end: number): string;\n\n\t/**\n\t * Looks up and returns a `Marker` using its id. Returns `undefined` if there is no marker with the provided\n\t * id in this `SharedString`.\n\t */\n\tgetMarkerFromId(id: string): ISegment | undefined;\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport type SharedStringSegment = TextSegment | Marker;\n\n/**\n * The Shared String is a specialized data structure for handling collaborative\n * text. It is based on a more general Sequence data structure but has\n * additional features that make working with text easier.\n *\n * In addition to text, a Shared String can also contain markers. Markers can be\n * used to store metadata at positions within the text, like the details of an\n * image or Fluid object that should be rendered with the text.\n * @internal\n */\nexport class SharedStringClass\n\t// eslint-disable-next-line import/no-deprecated\n\textends SharedSegmentSequence<SharedStringSegment>\n\timplements ISharedString\n{\n\tpublic get ISharedString(): ISharedString {\n\t\treturn this;\n\t}\n\n\t// eslint-disable-next-line import/no-deprecated\n\tprivate readonly mergeTreeTextHelper: IMergeTreeTextHelper;\n\n\tconstructor(\n\t\tdocument: IFluidDataStoreRuntime,\n\t\tpublic id: string,\n\t\tattributes: IChannelAttributes,\n\t) {\n\t\tsuper(document, id, attributes, SharedStringFactory.segmentFromSpec as any);\n\t\tthis.mergeTreeTextHelper = this.client.createTextHelper();\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.insertMarkerRelative}\n\t */\n\tpublic insertMarkerRelative(\n\t\trelativePos1: IRelativePosition,\n\t\trefType: ReferenceType,\n\t\tprops?: PropertySet,\n\t): void {\n\t\tconst pos = this.posFromRelativePos(relativePos1);\n\t\tthis.guardReentrancy(() =>\n\t\t\tthis.client.insertSegmentLocal(pos, Marker.make(refType, props)),\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.insertMarker}\n\t */\n\tpublic insertMarker(pos: number, refType: ReferenceType, props?: PropertySet): void {\n\t\tthis.guardReentrancy(() =>\n\t\t\tthis.client.insertSegmentLocal(pos, Marker.make(refType, props)),\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.insertTextRelative}\n\t */\n\tpublic insertTextRelative(\n\t\trelativePos1: IRelativePosition,\n\t\ttext: string,\n\t\tprops?: PropertySet,\n\t): void {\n\t\tconst pos = this.posFromRelativePos(relativePos1);\n\t\tthis.guardReentrancy(() =>\n\t\t\tthis.client.insertSegmentLocal(pos, TextSegment.make(text, props)),\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.insertText}\n\t */\n\tpublic insertText(pos: number, text: string, props?: PropertySet): void {\n\t\tthis.guardReentrancy(() =>\n\t\t\tthis.client.insertSegmentLocal(pos, TextSegment.make(text, props)),\n\t\t);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.replaceText}\n\t */\n\tpublic replaceText(start: number, end: number, text: string, props?: PropertySet): void {\n\t\tthis.replaceRange(start, end, TextSegment.make(text, props));\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.removeText}\n\t */\n\tpublic removeText(start: number, end: number): void {\n\t\tthis.removeRange(start, end);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.annotateMarker}\n\t */\n\tpublic annotateMarker(marker: Marker, props: PropertySet): void {\n\t\tthis.guardReentrancy(() => this.client.annotateMarker(marker, props));\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.searchForMarker}\n\t */\n\tpublic searchForMarker(\n\t\tstartPos: number,\n\t\tmarkerLabel: string,\n\t\tforwards = true,\n\t): Marker | undefined {\n\t\treturn this.client.searchForMarker(startPos, markerLabel, forwards);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.getText}\n\t */\n\tpublic getText(start?: number, end?: number) {\n\t\tconst collabWindow = this.client.getCollabWindow();\n\t\treturn this.mergeTreeTextHelper.getText(collabWindow.localPerspective, \"\", start, end);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.getTextWithPlaceholders}\n\t */\n\tpublic getTextWithPlaceholders(start?: number, end?: number) {\n\t\tconst collabWindow = this.client.getCollabWindow();\n\t\treturn this.mergeTreeTextHelper.getText(collabWindow.localPerspective, \" \", start, end);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.getTextRangeWithMarkers}\n\t */\n\tpublic getTextRangeWithMarkers(start: number, end: number) {\n\t\tconst collabWindow = this.client.getCollabWindow();\n\t\treturn this.mergeTreeTextHelper.getText(collabWindow.localPerspective, \"*\", start, end);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedString.getMarkerFromId}\n\t */\n\tpublic getMarkerFromId(id: string): ISegment | undefined {\n\t\treturn this.client.getMarkerFromId(id);\n\t}\n}\n\ninterface ITextAndMarkerAccumulator {\n\tparallelText: string[];\n\tparallelMarkers: Marker[];\n\tparallelMarkerLabel: string;\n\tplaceholder?: string;\n\ttagsInProgress: string[];\n\ttextSegment: TextSegment;\n}\n\n/**\n * Splits the text into regions ending with markers with the given `label`.\n * @param sharedString - String to retrieve text and markers from\n * @param label - label to split on\n * @returns Two parallel lists of text and markers, split by markers with the provided `label`.\n * For example:\n * ```typescript\n * // Say sharedstring has contents \"hello<paragraph marker 1>world<paragraph marker 2>missing\".\n * const { parallelText, parallelMarkers } = getTextAndMarkers(sharedString, \"paragraph\");\n * // parallelText === [\"hello\", \"world\"]\n * // parallelMarkers === [<paragraph marker 1 object>, <paragraph marker 2 object>]\n * // Note parallelText does not include \"missing\".\n * ```\n * @internal\n */\nexport function getTextAndMarkers(\n\tsharedString: ISharedString,\n\tlabel: string,\n\tstart?: number,\n\tend?: number,\n): {\n\tparallelText: string[];\n\tparallelMarkers: Marker[];\n} {\n\tconst accum: ITextAndMarkerAccumulator = {\n\t\tparallelMarkerLabel: label,\n\t\tparallelMarkers: [],\n\t\tparallelText: [],\n\t\ttagsInProgress: [],\n\t\ttextSegment: new TextSegment(\"\"),\n\t};\n\n\tsharedString.walkSegments(gatherTextAndMarkers, start, end, accum);\n\treturn { parallelText: accum.parallelText, parallelMarkers: accum.parallelMarkers };\n}\n\nconst gatherTextAndMarkers: ISegmentAction<ITextAndMarkerAccumulator> = (\n\tsegment: ISegment,\n\tpos: number,\n\trefSeq: number,\n\tclientId: number,\n\tstart: number,\n\tend: number,\n\taccumText: ITextAndMarkerAccumulator,\n) => {\n\tconst { placeholder, tagsInProgress, textSegment } = accumText;\n\tif (TextSegment.is(segment)) {\n\t\tlet beginTags = \"\";\n\t\tlet endTags = \"\";\n\t\t// TODO: let clients pass in function to get tag\n\t\tconst tags = [] as string[];\n\t\tconst initTags = [] as string[];\n\n\t\tif (segment.properties?.[\"font-weight\"]) {\n\t\t\ttags.push(\"b\");\n\t\t}\n\t\tif (segment.properties?.[\"text-decoration\"]) {\n\t\t\ttags.push(\"u\");\n\t\t}\n\t\tconst remTags = [] as string[];\n\t\tif (tags.length > 0) {\n\t\t\tfor (const tag of tags) {\n\t\t\t\tif (!tagsInProgress.includes(tag)) {\n\t\t\t\t\tbeginTags += `<${tag}>`;\n\t\t\t\t\tinitTags.push(tag);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const accumTag of tagsInProgress) {\n\t\t\t\tif (!tags.includes(accumTag)) {\n\t\t\t\t\tendTags += `</${accumTag}>`;\n\t\t\t\t\tremTags.push(accumTag);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const initTag of initTags.reverse()) {\n\t\t\t\ttagsInProgress.push(initTag);\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const accumTag of tagsInProgress) {\n\t\t\t\tendTags += `</${accumTag}>`;\n\t\t\t\tremTags.push(accumTag);\n\t\t\t}\n\t\t}\n\t\tfor (const remTag of remTags) {\n\t\t\tconst remdex = tagsInProgress.indexOf(remTag);\n\t\t\tif (remdex >= 0) {\n\t\t\t\ttagsInProgress.splice(remdex, 1);\n\t\t\t}\n\t\t}\n\t\ttextSegment.text += endTags;\n\t\ttextSegment.text += beginTags;\n\t\tif (start <= 0 && end >= segment.text.length) {\n\t\t\ttextSegment.text += segment.text;\n\t\t} else {\n\t\t\tconst seglen = segment.text.length;\n\t\t\tconst _start = start < 0 ? 0 : start;\n\t\t\tconst _end = end >= seglen ? undefined : end;\n\t\t\ttextSegment.text += segment.text.substring(_start, _end);\n\t\t}\n\t} else {\n\t\tif (placeholder && placeholder.length > 0) {\n\t\t\tconst placeholderText =\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\t\t\tplaceholder === \"*\" ? `\\n${segment}` : placeholder.repeat(segment.cachedLength);\n\t\t\ttextSegment.text += placeholderText;\n\t\t} else {\n\t\t\tconst marker = segment as Marker;\n\t\t\tif (refHasTileLabel(marker, accumText.parallelMarkerLabel)) {\n\t\t\t\taccumText.parallelMarkers.push(marker);\n\t\t\t\taccumText.parallelText.push(textSegment.text);\n\t\t\t\ttextSegment.text = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true;\n};\n"]}
|
package/lib/tsdoc-metadata.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/sequence",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.33.0",
|
|
4
4
|
"description": "Distributed sequence",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -91,34 +91,34 @@
|
|
|
91
91
|
"temp-directory": "nyc/.nyc_output"
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {
|
|
94
|
-
"@fluid-internal/client-utils": "~2.
|
|
95
|
-
"@fluidframework/core-interfaces": "~2.
|
|
96
|
-
"@fluidframework/core-utils": "~2.
|
|
97
|
-
"@fluidframework/datastore-definitions": "~2.
|
|
98
|
-
"@fluidframework/driver-definitions": "~2.
|
|
99
|
-
"@fluidframework/merge-tree": "~2.
|
|
100
|
-
"@fluidframework/runtime-definitions": "~2.
|
|
101
|
-
"@fluidframework/runtime-utils": "~2.
|
|
102
|
-
"@fluidframework/shared-object-base": "~2.
|
|
103
|
-
"@fluidframework/telemetry-utils": "~2.
|
|
94
|
+
"@fluid-internal/client-utils": "~2.33.0",
|
|
95
|
+
"@fluidframework/core-interfaces": "~2.33.0",
|
|
96
|
+
"@fluidframework/core-utils": "~2.33.0",
|
|
97
|
+
"@fluidframework/datastore-definitions": "~2.33.0",
|
|
98
|
+
"@fluidframework/driver-definitions": "~2.33.0",
|
|
99
|
+
"@fluidframework/merge-tree": "~2.33.0",
|
|
100
|
+
"@fluidframework/runtime-definitions": "~2.33.0",
|
|
101
|
+
"@fluidframework/runtime-utils": "~2.33.0",
|
|
102
|
+
"@fluidframework/shared-object-base": "~2.33.0",
|
|
103
|
+
"@fluidframework/telemetry-utils": "~2.33.0",
|
|
104
104
|
"double-ended-queue": "^2.1.0-0",
|
|
105
105
|
"uuid": "^9.0.0"
|
|
106
106
|
},
|
|
107
107
|
"devDependencies": {
|
|
108
108
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
109
109
|
"@biomejs/biome": "~1.9.3",
|
|
110
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
111
|
-
"@fluid-private/stochastic-test-utils": "~2.
|
|
112
|
-
"@fluid-private/test-dds-utils": "~2.
|
|
110
|
+
"@fluid-internal/mocha-test-setup": "~2.33.0",
|
|
111
|
+
"@fluid-private/stochastic-test-utils": "~2.33.0",
|
|
112
|
+
"@fluid-private/test-dds-utils": "~2.33.0",
|
|
113
113
|
"@fluid-tools/benchmark": "^0.50.0",
|
|
114
114
|
"@fluid-tools/build-cli": "^0.55.0",
|
|
115
115
|
"@fluidframework/build-common": "^2.0.3",
|
|
116
116
|
"@fluidframework/build-tools": "^0.55.0",
|
|
117
|
-
"@fluidframework/container-definitions": "~2.
|
|
117
|
+
"@fluidframework/container-definitions": "~2.33.0",
|
|
118
118
|
"@fluidframework/eslint-config-fluid": "^5.7.3",
|
|
119
|
-
"@fluidframework/sequence-previous": "npm:@fluidframework/sequence@2.
|
|
120
|
-
"@fluidframework/test-runtime-utils": "~2.
|
|
121
|
-
"@microsoft/api-extractor": "7.
|
|
119
|
+
"@fluidframework/sequence-previous": "npm:@fluidframework/sequence@2.32.0",
|
|
120
|
+
"@fluidframework/test-runtime-utils": "~2.33.0",
|
|
121
|
+
"@microsoft/api-extractor": "7.52.5",
|
|
122
122
|
"@types/diff": "^3.5.1",
|
|
123
123
|
"@types/double-ended-queue": "^2.1.0",
|
|
124
124
|
"@types/mocha": "^10.0.10",
|
|
@@ -132,9 +132,7 @@
|
|
|
132
132
|
"eslint": "~8.55.0",
|
|
133
133
|
"mocha": "^10.8.2",
|
|
134
134
|
"mocha-multi-reporters": "^1.5.1",
|
|
135
|
-
"moment": "^2.21.0",
|
|
136
135
|
"random-js": "^2.1.0",
|
|
137
|
-
"replace-in-file": "^6.3.5",
|
|
138
136
|
"rimraf": "^4.4.0",
|
|
139
137
|
"typescript": "~5.4.5"
|
|
140
138
|
},
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
9
9
|
import { IEvent } from "@fluidframework/core-interfaces";
|
|
10
|
-
import { assert } from "@fluidframework/core-utils/internal";
|
|
10
|
+
import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
|
|
11
11
|
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
12
12
|
import {
|
|
13
13
|
Client,
|
|
@@ -30,7 +30,6 @@ import { LoggingError, UsageError } from "@fluidframework/telemetry-utils/intern
|
|
|
30
30
|
import { v4 as uuid } from "uuid";
|
|
31
31
|
|
|
32
32
|
import {
|
|
33
|
-
IIntervalCollectionOperation,
|
|
34
33
|
IMapMessageLocalMetadata,
|
|
35
34
|
SequenceOptions,
|
|
36
35
|
type IIntervalCollectionTypeOperationValue,
|
|
@@ -49,7 +48,6 @@ import {
|
|
|
49
48
|
import {
|
|
50
49
|
CompressedSerializedInterval,
|
|
51
50
|
ISerializedInterval,
|
|
52
|
-
IntervalDeltaOpType,
|
|
53
51
|
IntervalStickiness,
|
|
54
52
|
IntervalType,
|
|
55
53
|
SequenceInterval,
|
|
@@ -217,6 +215,7 @@ export class LocalIntervalCollection {
|
|
|
217
215
|
end: SequencePlace,
|
|
218
216
|
props?: PropertySet,
|
|
219
217
|
op?: ISequencedDocumentMessage,
|
|
218
|
+
rollback?: boolean,
|
|
220
219
|
) {
|
|
221
220
|
// This check is intended to prevent scenarios where a random interval is created and then
|
|
222
221
|
// inserted into a collection. The aim is to ensure that the collection is created first
|
|
@@ -240,6 +239,7 @@ export class LocalIntervalCollection {
|
|
|
240
239
|
undefined,
|
|
241
240
|
this.options.mergeTreeReferencesCanSlideToEndpoint,
|
|
242
241
|
props,
|
|
242
|
+
rollback,
|
|
243
243
|
);
|
|
244
244
|
|
|
245
245
|
this.add(interval);
|
|
@@ -352,55 +352,6 @@ export class LocalIntervalCollection {
|
|
|
352
352
|
}
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
-
const rebase: IIntervalCollectionOperation["rebase"] = (collection, op, localOpMetadata) => {
|
|
356
|
-
const { localSeq } = localOpMetadata;
|
|
357
|
-
const rebasedValue = collection.rebaseLocalInterval(op.opName, op.value, localSeq);
|
|
358
|
-
if (rebasedValue === undefined) {
|
|
359
|
-
return undefined;
|
|
360
|
-
}
|
|
361
|
-
const rebasedOp = { ...op, value: rebasedValue };
|
|
362
|
-
return { rebasedOp, rebasedLocalOpMetadata: localOpMetadata };
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
export const opsMap: Record<IntervalDeltaOpType, IIntervalCollectionOperation> = {
|
|
366
|
-
[IntervalDeltaOpType.ADD]: {
|
|
367
|
-
process: (collection, params, local, op, localOpMetadata) => {
|
|
368
|
-
// if params is undefined, the interval was deleted during
|
|
369
|
-
// rebasing
|
|
370
|
-
if (!params) {
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
assert(op !== undefined, 0x3fb /* op should exist here */);
|
|
374
|
-
collection.ackAdd(params, local, op, localOpMetadata);
|
|
375
|
-
},
|
|
376
|
-
rebase,
|
|
377
|
-
},
|
|
378
|
-
|
|
379
|
-
[IntervalDeltaOpType.DELETE]: {
|
|
380
|
-
process: (collection, params, local, op) => {
|
|
381
|
-
assert(op !== undefined, 0x3fc /* op should exist here */);
|
|
382
|
-
collection.ackDelete(params, local, op);
|
|
383
|
-
},
|
|
384
|
-
rebase: (collection, op, localOpMetadata) => {
|
|
385
|
-
// Deletion of intervals is based on id, so requires no rebasing.
|
|
386
|
-
return { rebasedOp: op, rebasedLocalOpMetadata: localOpMetadata };
|
|
387
|
-
},
|
|
388
|
-
},
|
|
389
|
-
|
|
390
|
-
[IntervalDeltaOpType.CHANGE]: {
|
|
391
|
-
process: (collection, params, local, op, localOpMetadata) => {
|
|
392
|
-
// if params is undefined, the interval was deleted during
|
|
393
|
-
// rebasing
|
|
394
|
-
if (!params) {
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
assert(op !== undefined, 0x3fd /* op should exist here */);
|
|
398
|
-
collection.ackChange(params, local, op, localOpMetadata);
|
|
399
|
-
},
|
|
400
|
-
rebase,
|
|
401
|
-
},
|
|
402
|
-
};
|
|
403
|
-
|
|
404
355
|
/**
|
|
405
356
|
* @legacy
|
|
406
357
|
* @alpha
|
|
@@ -442,7 +393,7 @@ class IntervalCollectionIterator implements Iterator<SequenceIntervalClass> {
|
|
|
442
393
|
* Change events emitted by `IntervalCollection`s
|
|
443
394
|
* @legacy
|
|
444
395
|
* @alpha
|
|
445
|
-
* @
|
|
396
|
+
* @deprecated The generic version of this interface is no longer used and will be removed. Use {@link ISequenceIntervalCollectionEvents} instead.
|
|
446
397
|
*/
|
|
447
398
|
export interface IIntervalCollectionEvent<TInterval extends ISerializableInterval>
|
|
448
399
|
extends IEvent {
|
|
@@ -1126,6 +1077,132 @@ export class IntervalCollection
|
|
|
1126
1077
|
return true;
|
|
1127
1078
|
}
|
|
1128
1079
|
|
|
1080
|
+
public rollback(
|
|
1081
|
+
op: IIntervalCollectionTypeOperationValue,
|
|
1082
|
+
localOpMetadata: IMapMessageLocalMetadata,
|
|
1083
|
+
) {
|
|
1084
|
+
const { opName, value } = op;
|
|
1085
|
+
const { id, properties } = getSerializedProperties(value);
|
|
1086
|
+
const { localSeq, previous } = localOpMetadata;
|
|
1087
|
+
switch (opName) {
|
|
1088
|
+
case "add": {
|
|
1089
|
+
const interval = this.getIntervalById(id);
|
|
1090
|
+
if (interval) {
|
|
1091
|
+
this.deleteExistingInterval({ interval, local: true, rollback: true });
|
|
1092
|
+
}
|
|
1093
|
+
break;
|
|
1094
|
+
}
|
|
1095
|
+
case "change": {
|
|
1096
|
+
assert(previous !== undefined, 0xb7c /* must have previous for change */);
|
|
1097
|
+
|
|
1098
|
+
const endpointsChanged = value.start !== undefined && value.end !== undefined;
|
|
1099
|
+
const start = endpointsChanged
|
|
1100
|
+
? toOptionalSequencePlace(previous.start, previous.startSide)
|
|
1101
|
+
: undefined;
|
|
1102
|
+
const end = endpointsChanged
|
|
1103
|
+
? toOptionalSequencePlace(previous.end, previous.endSide)
|
|
1104
|
+
: undefined;
|
|
1105
|
+
this.change(id, {
|
|
1106
|
+
start,
|
|
1107
|
+
end,
|
|
1108
|
+
props: Object.keys(properties).length > 0 ? properties : undefined,
|
|
1109
|
+
rollback: true,
|
|
1110
|
+
});
|
|
1111
|
+
this.localSeqToSerializedInterval.delete(localSeq);
|
|
1112
|
+
if (endpointsChanged) {
|
|
1113
|
+
this.removePendingChange(value);
|
|
1114
|
+
}
|
|
1115
|
+
break;
|
|
1116
|
+
}
|
|
1117
|
+
case "delete": {
|
|
1118
|
+
assert(previous !== undefined, 0xb7d /* must have previous for delete */);
|
|
1119
|
+
this.add({
|
|
1120
|
+
id,
|
|
1121
|
+
start: toSequencePlace(previous.start, previous.startSide),
|
|
1122
|
+
end: toSequencePlace(previous.end, previous.endSide),
|
|
1123
|
+
props: Object.keys(properties).length > 0 ? properties : undefined,
|
|
1124
|
+
rollback: true,
|
|
1125
|
+
});
|
|
1126
|
+
break;
|
|
1127
|
+
}
|
|
1128
|
+
default:
|
|
1129
|
+
unreachableCase(opName);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
public process(
|
|
1134
|
+
op: IIntervalCollectionTypeOperationValue,
|
|
1135
|
+
local: boolean,
|
|
1136
|
+
message: ISequencedDocumentMessage,
|
|
1137
|
+
localOpMetadata: IMapMessageLocalMetadata,
|
|
1138
|
+
) {
|
|
1139
|
+
const { opName, value } = op;
|
|
1140
|
+
switch (opName) {
|
|
1141
|
+
case "add": {
|
|
1142
|
+
this.ackAdd(value, local, message, localOpMetadata);
|
|
1143
|
+
break;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
case "delete": {
|
|
1147
|
+
this.ackDelete(value, local, message);
|
|
1148
|
+
break;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
case "change": {
|
|
1152
|
+
this.ackChange(value, local, message, localOpMetadata);
|
|
1153
|
+
break;
|
|
1154
|
+
}
|
|
1155
|
+
default:
|
|
1156
|
+
unreachableCase(opName);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
public resubmitMessage(
|
|
1161
|
+
op: IIntervalCollectionTypeOperationValue,
|
|
1162
|
+
localOpMetadata: IMapMessageLocalMetadata,
|
|
1163
|
+
): void {
|
|
1164
|
+
const { opName, value } = op;
|
|
1165
|
+
const { localSeq } = localOpMetadata;
|
|
1166
|
+
const rebasedValue =
|
|
1167
|
+
opName === "delete" ? value : this.rebaseLocalInterval(opName, value, localSeq);
|
|
1168
|
+
if (rebasedValue === undefined) {
|
|
1169
|
+
return undefined;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
this.submitDelta({ opName, value: rebasedValue as any }, localOpMetadata);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
public applyStashedOp(op: IIntervalCollectionTypeOperationValue): void {
|
|
1176
|
+
const { opName, value } = op;
|
|
1177
|
+
const { id, properties } = getSerializedProperties(value);
|
|
1178
|
+
switch (opName) {
|
|
1179
|
+
case "add": {
|
|
1180
|
+
this.add({
|
|
1181
|
+
id,
|
|
1182
|
+
// Todo: we should improve typing so we know add ops always have start and end
|
|
1183
|
+
start: toSequencePlace(value.start, value.startSide),
|
|
1184
|
+
end: toSequencePlace(value.end, value.endSide),
|
|
1185
|
+
props: properties,
|
|
1186
|
+
});
|
|
1187
|
+
break;
|
|
1188
|
+
}
|
|
1189
|
+
case "change": {
|
|
1190
|
+
this.change(id, {
|
|
1191
|
+
start: toOptionalSequencePlace(value.start, value.startSide),
|
|
1192
|
+
end: toOptionalSequencePlace(value.end, value.endSide),
|
|
1193
|
+
props: properties,
|
|
1194
|
+
});
|
|
1195
|
+
break;
|
|
1196
|
+
}
|
|
1197
|
+
case "delete": {
|
|
1198
|
+
this.removeIntervalById(id);
|
|
1199
|
+
break;
|
|
1200
|
+
}
|
|
1201
|
+
default:
|
|
1202
|
+
throw new Error("unknown ops should not be stashed");
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1129
1206
|
private rebasePositionWithSegmentSlide(
|
|
1130
1207
|
pos: number | "start" | "end",
|
|
1131
1208
|
seqNumberFrom: number,
|
|
@@ -1317,11 +1394,13 @@ export class IntervalCollection
|
|
|
1317
1394
|
start,
|
|
1318
1395
|
end,
|
|
1319
1396
|
props,
|
|
1397
|
+
rollback,
|
|
1320
1398
|
}: {
|
|
1321
1399
|
id?: string;
|
|
1322
1400
|
start: SequencePlace;
|
|
1323
1401
|
end: SequencePlace;
|
|
1324
1402
|
props?: PropertySet;
|
|
1403
|
+
rollback?: boolean;
|
|
1325
1404
|
}): SequenceIntervalClass {
|
|
1326
1405
|
if (!this.localCollection) {
|
|
1327
1406
|
throw new LoggingError("attach must be called prior to adding intervals");
|
|
@@ -1344,6 +1423,8 @@ export class IntervalCollection
|
|
|
1344
1423
|
toSequencePlace(startPos, startSide),
|
|
1345
1424
|
toSequencePlace(endPos, endSide),
|
|
1346
1425
|
props,
|
|
1426
|
+
undefined,
|
|
1427
|
+
rollback,
|
|
1347
1428
|
);
|
|
1348
1429
|
|
|
1349
1430
|
if (interval) {
|
|
@@ -1353,19 +1434,19 @@ export class IntervalCollection
|
|
|
1353
1434
|
}
|
|
1354
1435
|
const serializedInterval: ISerializedInterval = interval.serialize();
|
|
1355
1436
|
const localSeq = this.getNextLocalSeq();
|
|
1356
|
-
if (this.isCollaborating) {
|
|
1437
|
+
if (this.isCollaborating && rollback !== true) {
|
|
1357
1438
|
this.localSeqToSerializedInterval.set(localSeq, serializedInterval);
|
|
1358
|
-
}
|
|
1359
1439
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1440
|
+
this.submitDelta(
|
|
1441
|
+
{
|
|
1442
|
+
opName: "add",
|
|
1443
|
+
value: serializedInterval,
|
|
1444
|
+
},
|
|
1445
|
+
{
|
|
1446
|
+
localSeq,
|
|
1447
|
+
},
|
|
1448
|
+
);
|
|
1449
|
+
}
|
|
1369
1450
|
}
|
|
1370
1451
|
|
|
1371
1452
|
this.emit("addInterval", interval, true, undefined);
|
|
@@ -1373,11 +1454,17 @@ export class IntervalCollection
|
|
|
1373
1454
|
return interval;
|
|
1374
1455
|
}
|
|
1375
1456
|
|
|
1376
|
-
private deleteExistingInterval(
|
|
1377
|
-
interval
|
|
1378
|
-
local
|
|
1379
|
-
op
|
|
1380
|
-
|
|
1457
|
+
private deleteExistingInterval({
|
|
1458
|
+
interval,
|
|
1459
|
+
local,
|
|
1460
|
+
op,
|
|
1461
|
+
rollback,
|
|
1462
|
+
}: {
|
|
1463
|
+
interval: SequenceIntervalClass;
|
|
1464
|
+
local: boolean;
|
|
1465
|
+
op?: ISequencedDocumentMessage;
|
|
1466
|
+
rollback?: boolean;
|
|
1467
|
+
}) {
|
|
1381
1468
|
if (!this.localCollection) {
|
|
1382
1469
|
throw new LoggingError("Attach must be called before accessing intervals");
|
|
1383
1470
|
}
|
|
@@ -1386,7 +1473,7 @@ export class IntervalCollection
|
|
|
1386
1473
|
|
|
1387
1474
|
if (interval) {
|
|
1388
1475
|
// Local ops get submitted to the server. Remote ops have the deserializer run.
|
|
1389
|
-
if (local) {
|
|
1476
|
+
if (local && rollback !== true) {
|
|
1390
1477
|
this.submitDelta(
|
|
1391
1478
|
{
|
|
1392
1479
|
opName: "delete",
|
|
@@ -1394,6 +1481,7 @@ export class IntervalCollection
|
|
|
1394
1481
|
},
|
|
1395
1482
|
{
|
|
1396
1483
|
localSeq: this.getNextLocalSeq(),
|
|
1484
|
+
previous: interval.serialize(),
|
|
1397
1485
|
},
|
|
1398
1486
|
);
|
|
1399
1487
|
} else {
|
|
@@ -1415,7 +1503,7 @@ export class IntervalCollection
|
|
|
1415
1503
|
}
|
|
1416
1504
|
const interval = this.localCollection.idIntervalIndex.getIntervalById(id);
|
|
1417
1505
|
if (interval) {
|
|
1418
|
-
this.deleteExistingInterval(interval, true
|
|
1506
|
+
this.deleteExistingInterval({ interval, local: true });
|
|
1419
1507
|
}
|
|
1420
1508
|
return interval;
|
|
1421
1509
|
}
|
|
@@ -1424,7 +1512,12 @@ export class IntervalCollection
|
|
|
1424
1512
|
*/
|
|
1425
1513
|
public change(
|
|
1426
1514
|
id: string,
|
|
1427
|
-
{
|
|
1515
|
+
{
|
|
1516
|
+
start,
|
|
1517
|
+
end,
|
|
1518
|
+
props,
|
|
1519
|
+
rollback,
|
|
1520
|
+
}: { start?: SequencePlace; end?: SequencePlace; props?: PropertySet; rollback?: boolean },
|
|
1428
1521
|
): SequenceIntervalClass | undefined {
|
|
1429
1522
|
if (!this.localCollection) {
|
|
1430
1523
|
throw new LoggingError("Attach must be called before accessing intervals");
|
|
@@ -1455,7 +1548,7 @@ export class IntervalCollection
|
|
|
1455
1548
|
let deltaProps: PropertySet | undefined;
|
|
1456
1549
|
let newInterval: SequenceIntervalClass | undefined;
|
|
1457
1550
|
if (props !== undefined) {
|
|
1458
|
-
deltaProps = interval.changeProperties(props);
|
|
1551
|
+
deltaProps = interval.changeProperties(props, undefined, rollback);
|
|
1459
1552
|
}
|
|
1460
1553
|
const changeEndpoints = start !== undefined && end !== undefined;
|
|
1461
1554
|
if (changeEndpoints) {
|
|
@@ -1465,28 +1558,28 @@ export class IntervalCollection
|
|
|
1465
1558
|
setSlideOnRemove(newInterval.end);
|
|
1466
1559
|
}
|
|
1467
1560
|
}
|
|
1468
|
-
// Emit a property bag containing the ID and the other (if any) properties changed
|
|
1469
|
-
const serializedInterval: SerializedIntervalDelta = (
|
|
1470
|
-
newInterval ?? interval
|
|
1471
|
-
).serializeDelta({
|
|
1472
|
-
props,
|
|
1473
|
-
includeEndpoints: changeEndpoints,
|
|
1474
|
-
});
|
|
1475
1561
|
|
|
1476
|
-
|
|
1477
|
-
|
|
1562
|
+
if (this.isCollaborating && rollback !== true) {
|
|
1563
|
+
// Emit a property bag containing the ID and the other (if any) properties changed
|
|
1564
|
+
const serializedInterval: SerializedIntervalDelta = (
|
|
1565
|
+
newInterval ?? interval
|
|
1566
|
+
).serializeDelta({ props, includeEndpoints: changeEndpoints });
|
|
1567
|
+
const localSeq = this.getNextLocalSeq();
|
|
1568
|
+
|
|
1478
1569
|
this.localSeqToSerializedInterval.set(localSeq, serializedInterval);
|
|
1479
|
-
|
|
1570
|
+
this.addPendingChange(id, serializedInterval);
|
|
1480
1571
|
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1572
|
+
this.submitDelta(
|
|
1573
|
+
{
|
|
1574
|
+
opName: "change",
|
|
1575
|
+
value: serializedInterval,
|
|
1576
|
+
},
|
|
1577
|
+
{
|
|
1578
|
+
localSeq,
|
|
1579
|
+
previous: interval.serialize(),
|
|
1580
|
+
},
|
|
1581
|
+
);
|
|
1582
|
+
}
|
|
1490
1583
|
if (deltaProps !== undefined) {
|
|
1491
1584
|
this.emit("propertyChanged", interval, deltaProps, true, undefined);
|
|
1492
1585
|
this.emit(
|
|
@@ -1499,7 +1592,6 @@ export class IntervalCollection
|
|
|
1499
1592
|
);
|
|
1500
1593
|
}
|
|
1501
1594
|
if (newInterval) {
|
|
1502
|
-
this.addPendingChange(id, serializedInterval);
|
|
1503
1595
|
this.emitChange(newInterval, interval, true, false);
|
|
1504
1596
|
this.client?.removeLocalReferencePosition(interval.start);
|
|
1505
1597
|
this.client?.removeLocalReferencePosition(interval.end);
|
|
@@ -1581,7 +1673,7 @@ export class IntervalCollection
|
|
|
1581
1673
|
}
|
|
1582
1674
|
|
|
1583
1675
|
public ackChange(
|
|
1584
|
-
serializedInterval:
|
|
1676
|
+
serializedInterval: SerializedIntervalDelta,
|
|
1585
1677
|
local: boolean,
|
|
1586
1678
|
op: ISequencedDocumentMessage,
|
|
1587
1679
|
localOpMetadata: IMapMessageLocalMetadata | undefined,
|
|
@@ -1915,7 +2007,7 @@ export class IntervalCollection
|
|
|
1915
2007
|
}
|
|
1916
2008
|
|
|
1917
2009
|
public ackDelete(
|
|
1918
|
-
serializedInterval:
|
|
2010
|
+
serializedInterval: SerializedIntervalDelta,
|
|
1919
2011
|
local: boolean,
|
|
1920
2012
|
op: ISequencedDocumentMessage,
|
|
1921
2013
|
): void {
|
|
@@ -1933,7 +2025,7 @@ export class IntervalCollection
|
|
|
1933
2025
|
const { id } = getSerializedProperties(serializedInterval);
|
|
1934
2026
|
const interval = this.localCollection.idIntervalIndex.getIntervalById(id);
|
|
1935
2027
|
if (interval) {
|
|
1936
|
-
this.deleteExistingInterval(interval, local, op);
|
|
2028
|
+
this.deleteExistingInterval({ interval, local, op });
|
|
1937
2029
|
}
|
|
1938
2030
|
}
|
|
1939
2031
|
|